wasmkeep 0.2.0__py3-none-any.whl
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.
- wasmkeep/__init__.py +496 -0
- wasmkeep/__main__.py +98 -0
- wasmkeep/_call.py +33 -0
- wasmkeep/kv.py +277 -0
- wasmkeep/queue.py +214 -0
- wasmkeep/wire.py +559 -0
- wasmkeep/wit/actor.wit +273 -0
- wasmkeep/wit/deps/cli.wit +233 -0
- wasmkeep/wit/deps/clocks.wit +162 -0
- wasmkeep/wit/deps/filesystem.wit +589 -0
- wasmkeep/wit/deps/http.wit +733 -0
- wasmkeep/wit/deps/io.wit +299 -0
- wasmkeep/wit/deps/random.wit +92 -0
- wasmkeep/wit/deps/sockets.wit +949 -0
- wasmkeep/workflow.py +110 -0
- wasmkeep-0.2.0.dist-info/METADATA +254 -0
- wasmkeep-0.2.0.dist-info/RECORD +20 -0
- wasmkeep-0.2.0.dist-info/WHEEL +4 -0
- wasmkeep-0.2.0.dist-info/licenses/LICENSE +202 -0
- wasmkeep-0.2.0.dist-info/licenses/NOTICE +14 -0
wasmkeep/wit/actor.wit
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/// The `wasmkeep:actor` package: everything an actor can call on the host, and
|
|
2
|
+
/// everything the host calls on an actor.
|
|
3
|
+
///
|
|
4
|
+
/// An actor is addressed as `tenant/class/name`. One component implements one
|
|
5
|
+
/// class; each distinct name is an independent instance with its own SQLite
|
|
6
|
+
/// database. The host delivers events (requests, alarms) to an instance one at
|
|
7
|
+
/// a time, in arrival order: an actor never runs concurrently with itself.
|
|
8
|
+
///
|
|
9
|
+
/// Versioning: 0.x minor versions may break guests; every change comes with a
|
|
10
|
+
/// migration note (docs/adr). See docs/adr/0002-wasmkeep-actor-wit-v0.1.md and
|
|
11
|
+
/// docs/adr/0003-websockets-wit-v0.2.md.
|
|
12
|
+
package wasmkeep:actor@0.2.0;
|
|
13
|
+
|
|
14
|
+
/// Types shared by several interfaces.
|
|
15
|
+
interface types {
|
|
16
|
+
/// A SQL value, mapping one to one onto SQLite's storage classes.
|
|
17
|
+
variant value {
|
|
18
|
+
null,
|
|
19
|
+
integer(s64),
|
|
20
|
+
real(f64),
|
|
21
|
+
text(string),
|
|
22
|
+
blob(list<u8>),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// The result set of a query: column names, then one list of values per
|
|
26
|
+
/// row, in column order.
|
|
27
|
+
record rows {
|
|
28
|
+
columns: list<string>,
|
|
29
|
+
values: list<list<value>>,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Why a statement failed.
|
|
33
|
+
enum sql-error-kind {
|
|
34
|
+
/// The SQL did not parse, or referred to a missing table or column.
|
|
35
|
+
syntax,
|
|
36
|
+
/// A constraint failed (UNIQUE, NOT NULL, CHECK, FOREIGN KEY).
|
|
37
|
+
constraint,
|
|
38
|
+
/// Parameter count or types do not match the statement.
|
|
39
|
+
bind,
|
|
40
|
+
/// The text held more than one statement; send one at a time.
|
|
41
|
+
multiple-statements,
|
|
42
|
+
/// The database reached its size cap (default 1 GB); reads still work.
|
|
43
|
+
quota-exceeded,
|
|
44
|
+
/// The statement tried something actors may not do (ATTACH, a
|
|
45
|
+
/// PRAGMA outside the allowed set, loading extensions).
|
|
46
|
+
not-allowed,
|
|
47
|
+
/// The host failed (disk, I/O). The event should fail.
|
|
48
|
+
internal,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
record sql-error {
|
|
52
|
+
kind: sql-error-kind,
|
|
53
|
+
/// Human-readable detail, usually SQLite's own message.
|
|
54
|
+
message: string,
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/// The actor's own SQLite database. Nothing else can read or write it.
|
|
59
|
+
///
|
|
60
|
+
/// Each call runs one statement. Outside an explicit transaction every
|
|
61
|
+
/// statement commits on its own. `BEGIN` ... `COMMIT` across several calls
|
|
62
|
+
/// within one event is allowed; a transaction still open when the event ends
|
|
63
|
+
/// (or traps) is rolled back. A statement that fails in a way that rolls the
|
|
64
|
+
/// open transaction back (it ran past its deadline or the event's SQL CPU
|
|
65
|
+
/// budget, say) ends that transaction: nothing of it is kept, and every
|
|
66
|
+
/// later storage statement of the event is refused with `not-allowed`
|
|
67
|
+
/// (but a `ROLLBACK`, which is what already happened, succeeds).
|
|
68
|
+
interface storage {
|
|
69
|
+
use types.{value, rows, sql-error};
|
|
70
|
+
|
|
71
|
+
/// Runs a statement that returns no rows; returns the number of rows
|
|
72
|
+
/// changed. Returns once the write is committed to the local database.
|
|
73
|
+
exec: func(sql: string, params: list<value>) -> result<u64, sql-error>;
|
|
74
|
+
|
|
75
|
+
/// Like `exec`, but returns only once the write is durable: replicated to
|
|
76
|
+
/// the bucket when the node has one, fsynced locally when it does not.
|
|
77
|
+
/// Inside a transaction it takes only `COMMIT` (or `END`), and makes the
|
|
78
|
+
/// whole transaction durable; any other statement there is refused with
|
|
79
|
+
/// `not-allowed` before it runs. Outside one it does not take a
|
|
80
|
+
/// statement that opens or controls a transaction (`BEGIN`, `SAVEPOINT`):
|
|
81
|
+
/// run those with `exec`.
|
|
82
|
+
exec-durable: func(sql: string, params: list<value>) -> result<u64, sql-error>;
|
|
83
|
+
|
|
84
|
+
/// Runs a statement and returns its rows.
|
|
85
|
+
query: func(sql: string, params: list<value>) -> result<rows, sql-error>;
|
|
86
|
+
|
|
87
|
+
/// Deletes this actor: its database is removed once the current event
|
|
88
|
+
/// ends, and its pending alarm is cleared. The next event to this address
|
|
89
|
+
/// starts a fresh actor.
|
|
90
|
+
delete-self: func();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// One pending alarm per actor. Alarms survive restarts and fire at least
|
|
94
|
+
/// once: an `on-alarm` that fails or traps is retried, so handlers must be
|
|
95
|
+
/// idempotent.
|
|
96
|
+
interface alarms {
|
|
97
|
+
/// Schedules `on-alarm` at `at` (milliseconds since the Unix epoch),
|
|
98
|
+
/// replacing any pending alarm. A time in the past fires as soon as
|
|
99
|
+
/// possible.
|
|
100
|
+
set-alarm: func(at: u64);
|
|
101
|
+
|
|
102
|
+
/// The pending alarm time, if any.
|
|
103
|
+
get-alarm: func() -> option<u64>;
|
|
104
|
+
|
|
105
|
+
/// Cancels the pending alarm, if any.
|
|
106
|
+
clear-alarm: func();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/// Calls between actors of the same tenant.
|
|
110
|
+
interface actors {
|
|
111
|
+
/// A fully buffered request, delivered to the callee's
|
|
112
|
+
/// `wasi:http/incoming-handler` like any other request.
|
|
113
|
+
record request {
|
|
114
|
+
method: string,
|
|
115
|
+
/// Path and query, starting with `/`.
|
|
116
|
+
path: string,
|
|
117
|
+
headers: list<tuple<string, string>>,
|
|
118
|
+
body: list<u8>,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
record response {
|
|
122
|
+
status: u16,
|
|
123
|
+
headers: list<tuple<string, string>>,
|
|
124
|
+
body: list<u8>,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
variant call-error {
|
|
128
|
+
/// The address is not `class/name`, or the class does not exist.
|
|
129
|
+
invalid-address(string),
|
|
130
|
+
/// The call would re-enter an actor already waiting in this call
|
|
131
|
+
/// chain (including the caller itself), which would deadlock.
|
|
132
|
+
reentrant,
|
|
133
|
+
/// The request or response exceeded the body limit (16 MB).
|
|
134
|
+
too-large,
|
|
135
|
+
/// The callee did not answer within the event's wall-clock limit.
|
|
136
|
+
timeout,
|
|
137
|
+
/// The callee trapped, or the host could not deliver the call.
|
|
138
|
+
failed(string),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// Sends `request` to the actor at `address` (`class/name`, within the
|
|
142
|
+
/// caller's tenant) and waits for its response. The caller's own event
|
|
143
|
+
/// stays in progress meanwhile: other events to the caller wait.
|
|
144
|
+
///
|
|
145
|
+
/// The callee sees `x-wasmkeep-caller: <tenant>/<class>/<name>`, the name
|
|
146
|
+
/// percent-encoded (every byte but ASCII letters, digits and `-._~`), so
|
|
147
|
+
/// `room 1` arrives as `room%201`. The host removes that header from
|
|
148
|
+
/// requests coming from outside, so the callee can trust it.
|
|
149
|
+
call: func(address: string, request: request) -> result<response, call-error>;
|
|
150
|
+
|
|
151
|
+
/// An actor's address. Within a tenant, `class/name` is what `call`
|
|
152
|
+
/// takes; the name is decoded (any text without `/` or control characters).
|
|
153
|
+
record actor-address {
|
|
154
|
+
tenant: string,
|
|
155
|
+
class: string,
|
|
156
|
+
name: string,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/// This actor's own address: an actor does not otherwise know its name
|
|
160
|
+
/// or class (requests arrive with `/actor/<class>/<name>` removed, and
|
|
161
|
+
/// alarms carry nothing). For links to itself, for telling other actors
|
|
162
|
+
/// who it is, and for anything keyed by its name.
|
|
163
|
+
self-address: func() -> actor-address;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/// WebSocket connections to this actor.
|
|
167
|
+
///
|
|
168
|
+
/// The host accepts upgrades on the actor's path and owns the sockets, so a
|
|
169
|
+
/// connection stays open while the actor hibernates; the next message wakes
|
|
170
|
+
/// it. A connection id is only valid in the actor it was opened on.
|
|
171
|
+
interface websockets {
|
|
172
|
+
/// A WebSocket message.
|
|
173
|
+
variant message {
|
|
174
|
+
text(string),
|
|
175
|
+
binary(list<u8>),
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
variant send-error {
|
|
179
|
+
/// The connection is closed, or belongs to another actor.
|
|
180
|
+
unknown-connection,
|
|
181
|
+
/// The client is not reading fast enough; the message was dropped.
|
|
182
|
+
backpressure,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/// Queues `msg` on the connection.
|
|
186
|
+
send: func(conn: u64, msg: message) -> result<_, send-error>;
|
|
187
|
+
|
|
188
|
+
/// Closes the connection with a close code (1000 = normal) and reason.
|
|
189
|
+
close: func(conn: u64, code: u16, reason: string);
|
|
190
|
+
|
|
191
|
+
/// This actor's open connections, oldest first.
|
|
192
|
+
connections: func() -> list<u64>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/// Configuration and secrets the operator gives an actor class: an API
|
|
196
|
+
/// key, a webhook URL, a feature flag. Values come, by name, last wins,
|
|
197
|
+
/// from the deployed version's plain configuration (`wasmkeep deploy
|
|
198
|
+
/// --config CLASS=FILE`), the app's secrets sealed in the bucket (`wasmkeep
|
|
199
|
+
/// secrets set`), and files on the node (`wasmkeep serve --env CLASS=FILE`),
|
|
200
|
+
/// never from the component. They are the same for every actor of the class
|
|
201
|
+
/// and read-only, and change only between events, never during one: when a
|
|
202
|
+
/// deploy or a secrets change lands (the next event runs in a new instance)
|
|
203
|
+
/// or the node restarts.
|
|
204
|
+
interface env {
|
|
205
|
+
/// The value of `name`, or none if it is not set.
|
|
206
|
+
get: func(name: string) -> option<string>;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/// WasmKeep's own part of the actor world: what the host bindings and the
|
|
210
|
+
/// guest SDK are generated from.
|
|
211
|
+
world actor-core {
|
|
212
|
+
import storage;
|
|
213
|
+
import alarms;
|
|
214
|
+
import actors;
|
|
215
|
+
import websockets;
|
|
216
|
+
import env;
|
|
217
|
+
use websockets.{message};
|
|
218
|
+
|
|
219
|
+
/// Runs before the first event an instance handles with this component
|
|
220
|
+
/// version: once for a new actor, and again after each deploy. Use it to
|
|
221
|
+
/// create or migrate tables. An error fails the event; it is retried with
|
|
222
|
+
/// the next event.
|
|
223
|
+
export on-init: func() -> result<_, string>;
|
|
224
|
+
|
|
225
|
+
/// Runs when the pending alarm is due. An error or trap schedules a retry.
|
|
226
|
+
export on-alarm: func() -> result<_, string>;
|
|
227
|
+
|
|
228
|
+
/// A client upgraded a GET to `path` (the part after the actor's name,
|
|
229
|
+
/// with its query). Return an error to refuse it: the connection is then
|
|
230
|
+
/// closed with code 1008 and the error as reason. It runs before the host
|
|
231
|
+
/// answers the upgrade (101), so the client is connected only once the
|
|
232
|
+
/// actor has accepted it. What the actor sends meanwhile waits in the
|
|
233
|
+
/// socket's queue, with its usual cap (`backpressure` past 4 MiB). A
|
|
234
|
+
/// client that leaves before the 101 (or a node relaying for it, which
|
|
235
|
+
/// gives up after 30 s) still gets this event if it was already queued,
|
|
236
|
+
/// followed by `on-websocket-close` with code 1006.
|
|
237
|
+
export on-websocket-open: func(conn: u64, path: string) -> result<_, string>;
|
|
238
|
+
|
|
239
|
+
/// A message arrived on one of this actor's connections.
|
|
240
|
+
export on-websocket-message: func(conn: u64, msg: message);
|
|
241
|
+
|
|
242
|
+
/// A connection closed (by the client, by `close`, or by the host).
|
|
243
|
+
export on-websocket-close: func(conn: u64, code: u16, reason: string);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/// The world actor components target: WasmKeep's interfaces plus the standard
|
|
247
|
+
/// `wasi:http/proxy` world, whose `incoming-handler` receives requests and
|
|
248
|
+
/// whose imports provide outbound HTTP, clocks, randomness and stdio.
|
|
249
|
+
///
|
|
250
|
+
/// This is also the capability list. Toolchains import more than they use
|
|
251
|
+
/// (ComponentizeJS and componentize-py import `wasi:filesystem`, Python also
|
|
252
|
+
/// `wasi:sockets`), so the host links those too, inert: no preopened
|
|
253
|
+
/// directories, and sockets and name lookups refused.
|
|
254
|
+
world actor {
|
|
255
|
+
include actor-core;
|
|
256
|
+
include wasi:http/proxy@0.2.12;
|
|
257
|
+
|
|
258
|
+
// Imported by the standard library of Rust (and most languages) on
|
|
259
|
+
// wasm32-wasip2. The host provides them empty: no arguments, no
|
|
260
|
+
// environment variables, no terminal. Configuration arrives through
|
|
261
|
+
// the `env` interface instead.
|
|
262
|
+
import wasi:cli/environment@0.2.12;
|
|
263
|
+
import wasi:cli/exit@0.2.12;
|
|
264
|
+
import wasi:cli/terminal-input@0.2.12;
|
|
265
|
+
import wasi:cli/terminal-output@0.2.12;
|
|
266
|
+
import wasi:cli/terminal-stdin@0.2.12;
|
|
267
|
+
import wasi:cli/terminal-stdout@0.2.12;
|
|
268
|
+
import wasi:cli/terminal-stderr@0.2.12;
|
|
269
|
+
// Seeds the standard library's hash maps (Rust's `HashMap`, used by the
|
|
270
|
+
// SDK's key-value client among others). The host provides it, as every
|
|
271
|
+
// WASI 0.2 interface it links.
|
|
272
|
+
import wasi:random/insecure-seed@0.2.12;
|
|
273
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
package wasi:cli@0.2.12;
|
|
2
|
+
|
|
3
|
+
@since(version = 0.2.0)
|
|
4
|
+
interface environment {
|
|
5
|
+
/// Get the POSIX-style environment variables.
|
|
6
|
+
///
|
|
7
|
+
/// Each environment variable is provided as a pair of string variable names
|
|
8
|
+
/// and string value.
|
|
9
|
+
///
|
|
10
|
+
/// Morally, these are a value import, but until value imports are available
|
|
11
|
+
/// in the component model, this import function should return the same
|
|
12
|
+
/// values each time it is called.
|
|
13
|
+
@since(version = 0.2.0)
|
|
14
|
+
get-environment: func() -> list<tuple<string, string>>;
|
|
15
|
+
|
|
16
|
+
/// Get the POSIX-style arguments to the program.
|
|
17
|
+
@since(version = 0.2.0)
|
|
18
|
+
get-arguments: func() -> list<string>;
|
|
19
|
+
|
|
20
|
+
/// Return a path that programs should use as their initial current working
|
|
21
|
+
/// directory, interpreting `.` as shorthand for this.
|
|
22
|
+
@since(version = 0.2.0)
|
|
23
|
+
initial-cwd: func() -> option<string>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@since(version = 0.2.0)
|
|
27
|
+
interface exit {
|
|
28
|
+
/// Exit the current instance and any linked instances.
|
|
29
|
+
@since(version = 0.2.0)
|
|
30
|
+
exit: func(status: result);
|
|
31
|
+
|
|
32
|
+
/// Exit the current instance and any linked instances, reporting the
|
|
33
|
+
/// specified status code to the host.
|
|
34
|
+
///
|
|
35
|
+
/// The meaning of the code depends on the context, with 0 usually meaning
|
|
36
|
+
/// "success", and other values indicating various types of failure.
|
|
37
|
+
///
|
|
38
|
+
/// This function does not return; the effect is analogous to a trap, but
|
|
39
|
+
/// without the connotation that something bad has happened.
|
|
40
|
+
@since(version = 0.2.12)
|
|
41
|
+
exit-with-code: func(status-code: u8);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@since(version = 0.2.0)
|
|
45
|
+
interface run {
|
|
46
|
+
/// Run the program.
|
|
47
|
+
@since(version = 0.2.0)
|
|
48
|
+
run: func() -> result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@since(version = 0.2.0)
|
|
52
|
+
interface stdin {
|
|
53
|
+
@since(version = 0.2.0)
|
|
54
|
+
use wasi:io/streams@0.2.12.{input-stream};
|
|
55
|
+
|
|
56
|
+
@since(version = 0.2.0)
|
|
57
|
+
get-stdin: func() -> input-stream;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@since(version = 0.2.0)
|
|
61
|
+
interface stdout {
|
|
62
|
+
@since(version = 0.2.0)
|
|
63
|
+
use wasi:io/streams@0.2.12.{output-stream};
|
|
64
|
+
|
|
65
|
+
@since(version = 0.2.0)
|
|
66
|
+
get-stdout: func() -> output-stream;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@since(version = 0.2.0)
|
|
70
|
+
interface stderr {
|
|
71
|
+
@since(version = 0.2.0)
|
|
72
|
+
use wasi:io/streams@0.2.12.{output-stream};
|
|
73
|
+
|
|
74
|
+
@since(version = 0.2.0)
|
|
75
|
+
get-stderr: func() -> output-stream;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// Terminal input.
|
|
79
|
+
///
|
|
80
|
+
/// In the future, this may include functions for disabling echoing,
|
|
81
|
+
/// disabling input buffering so that keyboard events are sent through
|
|
82
|
+
/// immediately, querying supported features, and so on.
|
|
83
|
+
@since(version = 0.2.0)
|
|
84
|
+
interface terminal-input {
|
|
85
|
+
/// The input side of a terminal.
|
|
86
|
+
@since(version = 0.2.0)
|
|
87
|
+
resource terminal-input;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// Terminal output.
|
|
91
|
+
///
|
|
92
|
+
/// In the future, this may include functions for querying the terminal
|
|
93
|
+
/// size, being notified of terminal size changes, querying supported
|
|
94
|
+
/// features, and so on.
|
|
95
|
+
@since(version = 0.2.0)
|
|
96
|
+
interface terminal-output {
|
|
97
|
+
/// The output side of a terminal.
|
|
98
|
+
@since(version = 0.2.0)
|
|
99
|
+
resource terminal-output;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// An interface providing an optional `terminal-input` for stdin as a
|
|
103
|
+
/// link-time authority.
|
|
104
|
+
@since(version = 0.2.0)
|
|
105
|
+
interface terminal-stdin {
|
|
106
|
+
@since(version = 0.2.0)
|
|
107
|
+
use terminal-input.{terminal-input};
|
|
108
|
+
|
|
109
|
+
/// If stdin is connected to a terminal, return a `terminal-input` handle
|
|
110
|
+
/// allowing further interaction with it.
|
|
111
|
+
@since(version = 0.2.0)
|
|
112
|
+
get-terminal-stdin: func() -> option<terminal-input>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/// An interface providing an optional `terminal-output` for stdout as a
|
|
116
|
+
/// link-time authority.
|
|
117
|
+
@since(version = 0.2.0)
|
|
118
|
+
interface terminal-stdout {
|
|
119
|
+
@since(version = 0.2.0)
|
|
120
|
+
use terminal-output.{terminal-output};
|
|
121
|
+
|
|
122
|
+
/// If stdout is connected to a terminal, return a `terminal-output` handle
|
|
123
|
+
/// allowing further interaction with it.
|
|
124
|
+
@since(version = 0.2.0)
|
|
125
|
+
get-terminal-stdout: func() -> option<terminal-output>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/// An interface providing an optional `terminal-output` for stderr as a
|
|
129
|
+
/// link-time authority.
|
|
130
|
+
@since(version = 0.2.0)
|
|
131
|
+
interface terminal-stderr {
|
|
132
|
+
@since(version = 0.2.0)
|
|
133
|
+
use terminal-output.{terminal-output};
|
|
134
|
+
|
|
135
|
+
/// If stderr is connected to a terminal, return a `terminal-output` handle
|
|
136
|
+
/// allowing further interaction with it.
|
|
137
|
+
@since(version = 0.2.0)
|
|
138
|
+
get-terminal-stderr: func() -> option<terminal-output>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@since(version = 0.2.0)
|
|
142
|
+
world imports {
|
|
143
|
+
@since(version = 0.2.0)
|
|
144
|
+
import environment;
|
|
145
|
+
@since(version = 0.2.0)
|
|
146
|
+
import exit;
|
|
147
|
+
@since(version = 0.2.0)
|
|
148
|
+
import wasi:io/error@0.2.12;
|
|
149
|
+
@since(version = 0.2.0)
|
|
150
|
+
import wasi:io/poll@0.2.12;
|
|
151
|
+
@since(version = 0.2.0)
|
|
152
|
+
import wasi:io/streams@0.2.12;
|
|
153
|
+
@since(version = 0.2.0)
|
|
154
|
+
import stdin;
|
|
155
|
+
@since(version = 0.2.0)
|
|
156
|
+
import stdout;
|
|
157
|
+
@since(version = 0.2.0)
|
|
158
|
+
import stderr;
|
|
159
|
+
@since(version = 0.2.0)
|
|
160
|
+
import terminal-input;
|
|
161
|
+
@since(version = 0.2.0)
|
|
162
|
+
import terminal-output;
|
|
163
|
+
@since(version = 0.2.0)
|
|
164
|
+
import terminal-stdin;
|
|
165
|
+
@since(version = 0.2.0)
|
|
166
|
+
import terminal-stdout;
|
|
167
|
+
@since(version = 0.2.0)
|
|
168
|
+
import terminal-stderr;
|
|
169
|
+
import wasi:clocks/monotonic-clock@0.2.12;
|
|
170
|
+
import wasi:clocks/wall-clock@0.2.12;
|
|
171
|
+
@unstable(feature = clocks-timezone)
|
|
172
|
+
import wasi:clocks/timezone@0.2.12;
|
|
173
|
+
import wasi:filesystem/types@0.2.12;
|
|
174
|
+
import wasi:filesystem/preopens@0.2.12;
|
|
175
|
+
import wasi:sockets/network@0.2.12;
|
|
176
|
+
import wasi:sockets/instance-network@0.2.12;
|
|
177
|
+
import wasi:sockets/udp@0.2.12;
|
|
178
|
+
import wasi:sockets/udp-create-socket@0.2.12;
|
|
179
|
+
import wasi:sockets/tcp@0.2.12;
|
|
180
|
+
import wasi:sockets/tcp-create-socket@0.2.12;
|
|
181
|
+
import wasi:sockets/ip-name-lookup@0.2.12;
|
|
182
|
+
import wasi:random/random@0.2.12;
|
|
183
|
+
import wasi:random/insecure@0.2.12;
|
|
184
|
+
import wasi:random/insecure-seed@0.2.12;
|
|
185
|
+
}
|
|
186
|
+
@since(version = 0.2.0)
|
|
187
|
+
world command {
|
|
188
|
+
@since(version = 0.2.0)
|
|
189
|
+
import environment;
|
|
190
|
+
@since(version = 0.2.0)
|
|
191
|
+
import exit;
|
|
192
|
+
@since(version = 0.2.0)
|
|
193
|
+
import wasi:io/error@0.2.12;
|
|
194
|
+
@since(version = 0.2.0)
|
|
195
|
+
import wasi:io/poll@0.2.12;
|
|
196
|
+
@since(version = 0.2.0)
|
|
197
|
+
import wasi:io/streams@0.2.12;
|
|
198
|
+
@since(version = 0.2.0)
|
|
199
|
+
import stdin;
|
|
200
|
+
@since(version = 0.2.0)
|
|
201
|
+
import stdout;
|
|
202
|
+
@since(version = 0.2.0)
|
|
203
|
+
import stderr;
|
|
204
|
+
@since(version = 0.2.0)
|
|
205
|
+
import terminal-input;
|
|
206
|
+
@since(version = 0.2.0)
|
|
207
|
+
import terminal-output;
|
|
208
|
+
@since(version = 0.2.0)
|
|
209
|
+
import terminal-stdin;
|
|
210
|
+
@since(version = 0.2.0)
|
|
211
|
+
import terminal-stdout;
|
|
212
|
+
@since(version = 0.2.0)
|
|
213
|
+
import terminal-stderr;
|
|
214
|
+
import wasi:clocks/monotonic-clock@0.2.12;
|
|
215
|
+
import wasi:clocks/wall-clock@0.2.12;
|
|
216
|
+
@unstable(feature = clocks-timezone)
|
|
217
|
+
import wasi:clocks/timezone@0.2.12;
|
|
218
|
+
import wasi:filesystem/types@0.2.12;
|
|
219
|
+
import wasi:filesystem/preopens@0.2.12;
|
|
220
|
+
import wasi:sockets/network@0.2.12;
|
|
221
|
+
import wasi:sockets/instance-network@0.2.12;
|
|
222
|
+
import wasi:sockets/udp@0.2.12;
|
|
223
|
+
import wasi:sockets/udp-create-socket@0.2.12;
|
|
224
|
+
import wasi:sockets/tcp@0.2.12;
|
|
225
|
+
import wasi:sockets/tcp-create-socket@0.2.12;
|
|
226
|
+
import wasi:sockets/ip-name-lookup@0.2.12;
|
|
227
|
+
import wasi:random/random@0.2.12;
|
|
228
|
+
import wasi:random/insecure@0.2.12;
|
|
229
|
+
import wasi:random/insecure-seed@0.2.12;
|
|
230
|
+
|
|
231
|
+
@since(version = 0.2.0)
|
|
232
|
+
export run;
|
|
233
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
package wasi:clocks@0.2.12;
|
|
2
|
+
|
|
3
|
+
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
|
|
4
|
+
/// time.
|
|
5
|
+
///
|
|
6
|
+
/// It is intended to be portable at least between Unix-family platforms and
|
|
7
|
+
/// Windows.
|
|
8
|
+
///
|
|
9
|
+
/// A monotonic clock is a clock which has an unspecified initial value, and
|
|
10
|
+
/// successive reads of the clock will produce non-decreasing values.
|
|
11
|
+
@since(version = 0.2.0)
|
|
12
|
+
interface monotonic-clock {
|
|
13
|
+
@since(version = 0.2.0)
|
|
14
|
+
use wasi:io/poll@0.2.12.{pollable};
|
|
15
|
+
|
|
16
|
+
/// An instant in time, in nanoseconds. An instant is relative to an
|
|
17
|
+
/// unspecified initial value, and can only be compared to instances from
|
|
18
|
+
/// the same monotonic-clock.
|
|
19
|
+
@since(version = 0.2.0)
|
|
20
|
+
type instant = u64;
|
|
21
|
+
|
|
22
|
+
/// A duration of time, in nanoseconds.
|
|
23
|
+
@since(version = 0.2.0)
|
|
24
|
+
type duration = u64;
|
|
25
|
+
|
|
26
|
+
/// Read the current value of the clock.
|
|
27
|
+
///
|
|
28
|
+
/// The clock is monotonic, therefore calling this function repeatedly will
|
|
29
|
+
/// produce a sequence of non-decreasing values.
|
|
30
|
+
///
|
|
31
|
+
/// For completeness, this function traps if it's not possible to represent
|
|
32
|
+
/// the value of the clock in an `instant`. Consequently, implementations
|
|
33
|
+
/// should ensure that the starting time is low enough to avoid the
|
|
34
|
+
/// possibility of overflow in practice.
|
|
35
|
+
@since(version = 0.2.0)
|
|
36
|
+
now: func() -> instant;
|
|
37
|
+
|
|
38
|
+
/// Query the resolution of the clock. Returns the duration of time
|
|
39
|
+
/// corresponding to a clock tick.
|
|
40
|
+
@since(version = 0.2.0)
|
|
41
|
+
resolution: func() -> duration;
|
|
42
|
+
|
|
43
|
+
/// Create a `pollable` which will resolve once the specified instant
|
|
44
|
+
/// has occurred.
|
|
45
|
+
@since(version = 0.2.0)
|
|
46
|
+
subscribe-instant: func(when: instant) -> pollable;
|
|
47
|
+
|
|
48
|
+
/// Create a `pollable` that will resolve after the specified duration has
|
|
49
|
+
/// elapsed from the time this function is invoked.
|
|
50
|
+
@since(version = 0.2.0)
|
|
51
|
+
subscribe-duration: func(when: duration) -> pollable;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// WASI Wall Clock is a clock API intended to let users query the current
|
|
55
|
+
/// time. The name "wall" makes an analogy to a "clock on the wall", which
|
|
56
|
+
/// is not necessarily monotonic as it may be reset.
|
|
57
|
+
///
|
|
58
|
+
/// It is intended to be portable at least between Unix-family platforms and
|
|
59
|
+
/// Windows.
|
|
60
|
+
///
|
|
61
|
+
/// A wall clock is a clock which measures the date and time according to
|
|
62
|
+
/// some external reference.
|
|
63
|
+
///
|
|
64
|
+
/// External references may be reset, so this clock is not necessarily
|
|
65
|
+
/// monotonic, making it unsuitable for measuring elapsed time.
|
|
66
|
+
///
|
|
67
|
+
/// It is intended for reporting the current date and time for humans.
|
|
68
|
+
@since(version = 0.2.0)
|
|
69
|
+
interface wall-clock {
|
|
70
|
+
/// A time and date in seconds plus nanoseconds.
|
|
71
|
+
@since(version = 0.2.0)
|
|
72
|
+
record datetime {
|
|
73
|
+
seconds: u64,
|
|
74
|
+
nanoseconds: u32,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/// Read the current value of the clock.
|
|
78
|
+
///
|
|
79
|
+
/// This clock is not monotonic, therefore calling this function repeatedly
|
|
80
|
+
/// will not necessarily produce a sequence of non-decreasing values.
|
|
81
|
+
///
|
|
82
|
+
/// The returned timestamps represent the number of seconds since
|
|
83
|
+
/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch],
|
|
84
|
+
/// also known as [Unix Time].
|
|
85
|
+
///
|
|
86
|
+
/// The nanoseconds field of the output is always less than 1000000000.
|
|
87
|
+
///
|
|
88
|
+
/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
|
|
89
|
+
/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
|
|
90
|
+
@since(version = 0.2.0)
|
|
91
|
+
now: func() -> datetime;
|
|
92
|
+
|
|
93
|
+
/// Query the resolution of the clock.
|
|
94
|
+
///
|
|
95
|
+
/// The nanoseconds field of the output is always less than 1000000000.
|
|
96
|
+
@since(version = 0.2.0)
|
|
97
|
+
resolution: func() -> datetime;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@unstable(feature = clocks-timezone)
|
|
101
|
+
interface timezone {
|
|
102
|
+
@unstable(feature = clocks-timezone)
|
|
103
|
+
use wall-clock.{datetime};
|
|
104
|
+
|
|
105
|
+
/// Information useful for displaying the timezone of a specific `datetime`.
|
|
106
|
+
///
|
|
107
|
+
/// This information may vary within a single `timezone` to reflect daylight
|
|
108
|
+
/// saving time adjustments.
|
|
109
|
+
@unstable(feature = clocks-timezone)
|
|
110
|
+
record timezone-display {
|
|
111
|
+
/// The number of seconds difference between UTC time and the local
|
|
112
|
+
/// time of the timezone.
|
|
113
|
+
///
|
|
114
|
+
/// The returned value will always be less than 86400 which is the
|
|
115
|
+
/// number of seconds in a day (24*60*60).
|
|
116
|
+
///
|
|
117
|
+
/// In implementations that do not expose an actual time zone, this
|
|
118
|
+
/// should return 0.
|
|
119
|
+
utc-offset: s32,
|
|
120
|
+
/// The abbreviated name of the timezone to display to a user. The name
|
|
121
|
+
/// `UTC` indicates Coordinated Universal Time. Otherwise, this should
|
|
122
|
+
/// reference local standards for the name of the time zone.
|
|
123
|
+
///
|
|
124
|
+
/// In implementations that do not expose an actual time zone, this
|
|
125
|
+
/// should be the string `UTC`.
|
|
126
|
+
///
|
|
127
|
+
/// In time zones that do not have an applicable name, a formatted
|
|
128
|
+
/// representation of the UTC offset may be returned, such as `-04:00`.
|
|
129
|
+
name: string,
|
|
130
|
+
/// Whether daylight saving time is active.
|
|
131
|
+
///
|
|
132
|
+
/// In implementations that do not expose an actual time zone, this
|
|
133
|
+
/// should return false.
|
|
134
|
+
in-daylight-saving-time: bool,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/// Return information needed to display the given `datetime`. This includes
|
|
138
|
+
/// the UTC offset, the time zone name, and a flag indicating whether
|
|
139
|
+
/// daylight saving time is active.
|
|
140
|
+
///
|
|
141
|
+
/// If the timezone cannot be determined for the given `datetime`, return a
|
|
142
|
+
/// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight
|
|
143
|
+
/// saving time.
|
|
144
|
+
@unstable(feature = clocks-timezone)
|
|
145
|
+
display: func(when: datetime) -> timezone-display;
|
|
146
|
+
|
|
147
|
+
/// The same as `display`, but only return the UTC offset.
|
|
148
|
+
@unstable(feature = clocks-timezone)
|
|
149
|
+
utc-offset: func(when: datetime) -> s32;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@since(version = 0.2.0)
|
|
153
|
+
world imports {
|
|
154
|
+
@since(version = 0.2.0)
|
|
155
|
+
import wasi:io/poll@0.2.12;
|
|
156
|
+
@since(version = 0.2.0)
|
|
157
|
+
import monotonic-clock;
|
|
158
|
+
@since(version = 0.2.0)
|
|
159
|
+
import wall-clock;
|
|
160
|
+
@unstable(feature = clocks-timezone)
|
|
161
|
+
import timezone;
|
|
162
|
+
}
|