@noita-ts/pollnet 0.2.0 → 0.3.1
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/dist/async.d.ts +62 -20
- package/dist/async.lua +123 -102
- package/dist/lualib_bundle.lua +64 -2478
- package/package.json +1 -1
package/dist/async.d.ts
CHANGED
|
@@ -1,31 +1,73 @@
|
|
|
1
|
-
import pollnet from "
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import pollnet from ".";
|
|
2
|
+
export declare namespace compat {
|
|
3
|
+
/**
|
|
4
|
+
* Run `body` inside a reactor coroutine and get its completion as a Promise.
|
|
5
|
+
* `body` may freely use socket.await() / other yield-based pollnet APIs.
|
|
6
|
+
* Errors inside body reject the promise.
|
|
7
|
+
*/
|
|
8
|
+
const asyncify: <T>(reactor: pollnet.Reactor, body: () => T) => Promise<T>;
|
|
9
|
+
/**
|
|
10
|
+
* Parks the *current coroutine* until the promise settles, then returns its
|
|
11
|
+
* value or rethrows its rejection.
|
|
12
|
+
* Only call from inside a reactor coroutine (`reactor.run(() => { .. HERE .. })`).
|
|
13
|
+
*/
|
|
14
|
+
const yieldPromise: <T>(p: Promise<T>) => T;
|
|
15
|
+
}
|
|
8
16
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
17
|
+
* Promise-friendly wrapper around a {@link pollnet.Reactor}.
|
|
18
|
+
*
|
|
19
|
+
* Lets you drive yield-based pollnet coroutines while exposing their results
|
|
20
|
+
* as Promises. Call {@link poll} regularly (e.g. once per frame) to advance
|
|
21
|
+
* all running coroutines.
|
|
12
22
|
*/
|
|
13
|
-
export declare
|
|
23
|
+
export declare class AsyncReactor {
|
|
24
|
+
private reactor;
|
|
25
|
+
constructor();
|
|
26
|
+
/**
|
|
27
|
+
* Advance every coroutine currently running on the reactor by one step.
|
|
28
|
+
* Must be called periodically for spawned work to make progress.
|
|
29
|
+
*/
|
|
30
|
+
poll(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Run `body` as a reactor coroutine and return its result as a Promise.
|
|
33
|
+
* `body` may use yield-based pollnet APIs (e.g. `socket.await()`).
|
|
34
|
+
*/
|
|
35
|
+
spawn<T>(body: () => T): Promise<T>;
|
|
36
|
+
/**
|
|
37
|
+
* Async version of `pollnet.Reactor.run_server`.
|
|
38
|
+
*
|
|
39
|
+
* Accept connections on `server_sock`, spawning a coroutine that runs
|
|
40
|
+
* `client_body` for each incoming client. `client_body` receives the client
|
|
41
|
+
* socket and its remote address, and may itself return a Promise which the
|
|
42
|
+
* coroutine parks on until it settles.
|
|
43
|
+
*/
|
|
44
|
+
runServer(server_sock: pollnet.Socket, client_body: (sock: pollnet.Socket, addr: string) => Promise<void> | void): void;
|
|
45
|
+
}
|
|
14
46
|
export declare class HttpResponse {
|
|
15
47
|
status: number;
|
|
16
48
|
headers: string;
|
|
17
49
|
body: string;
|
|
18
50
|
constructor(status: number, headers: string, body: string);
|
|
51
|
+
/**
|
|
52
|
+
* Parse the raw header block into a map.
|
|
53
|
+
* Header names seen more than once collapse into an array of their values, in
|
|
54
|
+
* order.
|
|
55
|
+
*/
|
|
19
56
|
parseHeaders(): Record<string, string | string[]>;
|
|
20
57
|
}
|
|
21
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Tiny async HTTP client built on top of an {@link AsyncReactor}.
|
|
60
|
+
* Requests run as reactor coroutines and resolve to an {@link HttpResponse}.
|
|
61
|
+
*/
|
|
62
|
+
export declare class HttpClient {
|
|
22
63
|
private reactor;
|
|
23
|
-
constructor();
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
constructor(reactor: AsyncReactor);
|
|
65
|
+
/**
|
|
66
|
+
* Perform an HTTP GET.
|
|
67
|
+
*/
|
|
68
|
+
get(url: string, headers?: Record<string, string | string[]> | string): Promise<HttpResponse>;
|
|
69
|
+
/**
|
|
70
|
+
* Perform an HTTP POST with an optional request `body`.
|
|
71
|
+
*/
|
|
72
|
+
post(url: string, headers?: Record<string, string | string[]> | string, body?: string): Promise<HttpResponse>;
|
|
31
73
|
}
|
package/dist/async.lua
CHANGED
|
@@ -2,6 +2,7 @@ local ____lualib = require("lualib_bundle")
|
|
|
2
2
|
local __TS__Promise = ____lualib.__TS__Promise
|
|
3
3
|
local __TS__New = ____lualib.__TS__New
|
|
4
4
|
local __TS__Class = ____lualib.__TS__Class
|
|
5
|
+
local __TS__InstanceOf = ____lualib.__TS__InstanceOf
|
|
5
6
|
local __TS__StringSplit = ____lualib.__TS__StringSplit
|
|
6
7
|
local __TS__ArrayIsArray = ____lualib.__TS__ArrayIsArray
|
|
7
8
|
local Error = ____lualib.Error
|
|
@@ -11,61 +12,96 @@ local SyntaxError = ____lualib.SyntaxError
|
|
|
11
12
|
local TypeError = ____lualib.TypeError
|
|
12
13
|
local URIError = ____lualib.URIError
|
|
13
14
|
local ____exports = {}
|
|
14
|
-
local
|
|
15
|
-
local pollnet =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
local _____2E = require("index")
|
|
16
|
+
local pollnet = _____2E.default
|
|
17
|
+
____exports.compat = {}
|
|
18
|
+
local compat = ____exports.compat
|
|
19
|
+
do
|
|
20
|
+
--- Run `body` inside a reactor coroutine and get its completion as a Promise.
|
|
21
|
+
-- `body` may freely use socket.await() / other yield-based pollnet APIs.
|
|
22
|
+
-- Errors inside body reject the promise.
|
|
23
|
+
compat.asyncify = function(____, reactor, body)
|
|
24
|
+
return __TS__New(
|
|
25
|
+
__TS__Promise,
|
|
26
|
+
function(____, resolve, reject)
|
|
27
|
+
reactor:run(function()
|
|
28
|
+
do
|
|
29
|
+
local function ____catch(e)
|
|
30
|
+
reject(nil, e)
|
|
31
|
+
end
|
|
32
|
+
local ____try, ____hasReturned = pcall(function()
|
|
33
|
+
resolve(
|
|
34
|
+
nil,
|
|
35
|
+
body(nil)
|
|
36
|
+
)
|
|
37
|
+
end)
|
|
38
|
+
if not ____try then
|
|
39
|
+
____catch(____hasReturned)
|
|
40
|
+
end
|
|
27
41
|
end
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
end)
|
|
43
|
+
end
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
--- Parks the *current coroutine* until the promise settles, then returns its
|
|
47
|
+
-- value or rethrows its rejection.
|
|
48
|
+
-- Only call from inside a reactor coroutine (`reactor.run(() => { .. HERE .. })`).
|
|
49
|
+
compat.yieldPromise = function(____, p)
|
|
50
|
+
local done = false
|
|
51
|
+
local ok = false
|
|
52
|
+
local result
|
|
53
|
+
p["then"](
|
|
54
|
+
p,
|
|
55
|
+
function(____, v)
|
|
56
|
+
done = true
|
|
57
|
+
ok = true
|
|
58
|
+
result = v
|
|
59
|
+
end,
|
|
60
|
+
function(____, e)
|
|
61
|
+
done = true
|
|
62
|
+
ok = false
|
|
63
|
+
result = e
|
|
64
|
+
end
|
|
65
|
+
)
|
|
66
|
+
while not done do
|
|
67
|
+
coroutine.yield()
|
|
39
68
|
end
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
--- Parks the *current coroutine* until the promise settles, then returns its
|
|
43
|
-
-- value or rethrows its rejection.
|
|
44
|
-
-- Only call from inside a reactor coroutine (`reactor.run(() => { .. HERE .. })`).
|
|
45
|
-
____exports.blockOn = function(____, p)
|
|
46
|
-
local done = false
|
|
47
|
-
local ok = false
|
|
48
|
-
local result
|
|
49
|
-
p["then"](
|
|
50
|
-
p,
|
|
51
|
-
function(____, v)
|
|
52
|
-
done = true
|
|
53
|
-
ok = true
|
|
54
|
-
result = v
|
|
55
|
-
end,
|
|
56
|
-
function(____, e)
|
|
57
|
-
done = true
|
|
58
|
-
ok = false
|
|
59
|
-
result = e
|
|
69
|
+
if not ok then
|
|
70
|
+
error(result, 0)
|
|
60
71
|
end
|
|
61
|
-
|
|
62
|
-
while not done do
|
|
63
|
-
coroutine.yield()
|
|
64
|
-
end
|
|
65
|
-
if not ok then
|
|
66
|
-
error(result, 0)
|
|
72
|
+
return result
|
|
67
73
|
end
|
|
68
|
-
|
|
74
|
+
end
|
|
75
|
+
--- Promise-friendly wrapper around a {@link pollnet.Reactor}.
|
|
76
|
+
--
|
|
77
|
+
-- Lets you drive yield-based pollnet coroutines while exposing their results
|
|
78
|
+
-- as Promises. Call {@link poll} regularly (e.g. once per frame) to advance
|
|
79
|
+
-- all running coroutines.
|
|
80
|
+
____exports.AsyncReactor = __TS__Class()
|
|
81
|
+
local AsyncReactor = ____exports.AsyncReactor
|
|
82
|
+
AsyncReactor.name = "AsyncReactor"
|
|
83
|
+
function AsyncReactor.prototype.____constructor(self)
|
|
84
|
+
self.reactor = pollnet.Reactor()
|
|
85
|
+
end
|
|
86
|
+
function AsyncReactor.prototype.poll(self)
|
|
87
|
+
return self.reactor:update()
|
|
88
|
+
end
|
|
89
|
+
function AsyncReactor.prototype.spawn(self, body)
|
|
90
|
+
return ____exports.compat:asyncify(self.reactor, body)
|
|
91
|
+
end
|
|
92
|
+
function AsyncReactor.prototype.runServer(self, server_sock, client_body)
|
|
93
|
+
server_sock:on_connection(function(client_sock, addr)
|
|
94
|
+
self.reactor:run(function()
|
|
95
|
+
local r = client_body(nil, client_sock, addr)
|
|
96
|
+
if __TS__InstanceOf(r, __TS__Promise) then
|
|
97
|
+
____exports.compat:yieldPromise(r)
|
|
98
|
+
end
|
|
99
|
+
end)
|
|
100
|
+
end)
|
|
101
|
+
self.reactor:run(function()
|
|
102
|
+
while (server_sock:await()) do
|
|
103
|
+
end
|
|
104
|
+
end)
|
|
69
105
|
end
|
|
70
106
|
____exports.HttpResponse = __TS__Class()
|
|
71
107
|
local HttpResponse = ____exports.HttpResponse
|
|
@@ -85,12 +121,12 @@ function HttpResponse.prototype.parseHeaders(self)
|
|
|
85
121
|
2
|
|
86
122
|
)
|
|
87
123
|
if not key or not value then
|
|
88
|
-
goto
|
|
124
|
+
goto __continue24
|
|
89
125
|
end
|
|
90
126
|
local prev = headers[key]
|
|
91
127
|
if not prev then
|
|
92
128
|
headers[key] = value
|
|
93
|
-
goto
|
|
129
|
+
goto __continue24
|
|
94
130
|
end
|
|
95
131
|
if __TS__ArrayIsArray(prev) then
|
|
96
132
|
prev[#prev + 1] = value
|
|
@@ -98,61 +134,46 @@ function HttpResponse.prototype.parseHeaders(self)
|
|
|
98
134
|
headers[key] = {prev, value}
|
|
99
135
|
end
|
|
100
136
|
end
|
|
101
|
-
::
|
|
137
|
+
::__continue24::
|
|
102
138
|
end
|
|
103
139
|
return headers
|
|
104
140
|
end
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return self.reactor:update()
|
|
141
|
+
--- Tiny async HTTP client built on top of an {@link AsyncReactor}.
|
|
142
|
+
-- Requests run as reactor coroutines and resolve to an {@link HttpResponse}.
|
|
143
|
+
____exports.HttpClient = __TS__Class()
|
|
144
|
+
local HttpClient = ____exports.HttpClient
|
|
145
|
+
HttpClient.name = "HttpClient"
|
|
146
|
+
function HttpClient.prototype.____constructor(self, reactor)
|
|
147
|
+
self.reactor = reactor
|
|
113
148
|
end
|
|
114
|
-
function
|
|
115
|
-
self.reactor:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
self.reactor,
|
|
124
|
-
function()
|
|
125
|
-
local socket = pollnet.http_get(url, headers, false)
|
|
126
|
-
local msgs, ____error = socket:await_n(3)
|
|
127
|
-
if not msgs then
|
|
128
|
-
error(
|
|
129
|
-
__TS__New(Error, "socket error: " .. ____error),
|
|
130
|
-
0
|
|
131
|
-
)
|
|
132
|
-
end
|
|
133
|
-
local statusStr, headersStr, respBody = unpack(msgs, 1, 3)
|
|
134
|
-
local status = tonumber({string.match("^%d+", statusStr)}) or 500
|
|
135
|
-
return __TS__New(____exports.HttpResponse, status, headersStr, respBody)
|
|
149
|
+
function HttpClient.prototype.get(self, url, headers)
|
|
150
|
+
return self.reactor:spawn(function()
|
|
151
|
+
local socket = pollnet.http_get(url, headers, false)
|
|
152
|
+
local msgs, ____error = socket:await_n(3)
|
|
153
|
+
if not msgs then
|
|
154
|
+
error(
|
|
155
|
+
__TS__New(Error, "socket error: " .. ____error),
|
|
156
|
+
0
|
|
157
|
+
)
|
|
136
158
|
end
|
|
137
|
-
|
|
159
|
+
local statusStr, headersStr, respBody = unpack(msgs, 1, 3)
|
|
160
|
+
local status = tonumber({string.match("^%d+", statusStr)}) or 500
|
|
161
|
+
return __TS__New(____exports.HttpResponse, status, headersStr, respBody)
|
|
162
|
+
end)
|
|
138
163
|
end
|
|
139
|
-
function
|
|
140
|
-
return
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
__TS__New(Error, "socket error: " .. ____error),
|
|
149
|
-
0
|
|
150
|
-
)
|
|
151
|
-
end
|
|
152
|
-
local statusStr, headersStr, respBody = unpack(msgs, 1, 3)
|
|
153
|
-
local status = tonumber({string.match("^%d+", statusStr)}) or 500
|
|
154
|
-
return __TS__New(____exports.HttpResponse, status, headersStr, respBody)
|
|
164
|
+
function HttpClient.prototype.post(self, url, headers, body)
|
|
165
|
+
return self.reactor:spawn(function()
|
|
166
|
+
local socket = pollnet.http_post(url, headers, body, false)
|
|
167
|
+
local msgs, ____error = socket:await_n(3)
|
|
168
|
+
if not msgs then
|
|
169
|
+
error(
|
|
170
|
+
__TS__New(Error, "socket error: " .. ____error),
|
|
171
|
+
0
|
|
172
|
+
)
|
|
155
173
|
end
|
|
156
|
-
|
|
174
|
+
local statusStr, headersStr, respBody = unpack(msgs, 1, 3)
|
|
175
|
+
local status = tonumber({string.match("^%d+", statusStr)}) or 500
|
|
176
|
+
return __TS__New(____exports.HttpResponse, status, headersStr, respBody)
|
|
177
|
+
end)
|
|
157
178
|
end
|
|
158
179
|
return ____exports
|