@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 CHANGED
@@ -1,31 +1,73 @@
1
- import pollnet from "./index";
2
- /**
3
- * Run `body` inside a reactor coroutine and get its completion as a Promise.
4
- * `body` may freely use socket.await() / other yield-based pollnet APIs.
5
- * Errors inside body reject the promise.
6
- */
7
- export declare const spawn: <T>(reactor: pollnet.Reactor, body: () => T) => Promise<T>;
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
- * Parks the *current coroutine* until the promise settles, then returns its
10
- * value or rethrows its rejection.
11
- * Only call from inside a reactor coroutine (`reactor.run(() => { .. HERE .. })`).
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 const blockOn: <T>(p: Promise<T>) => T;
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
- export default class AsyncReactor {
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
- update(): number;
25
- /** Runs a coroutine thread */
26
- run(thread_body: (this: pollnet.Reactor) => void): void;
27
- /** Runs a server with client handler */
28
- run_server(server_sock: pollnet.Socket, client_body: (sock: pollnet.Socket, addr: string) => void): void;
29
- http_get(url: string, headers?: Record<string, string | string[]> | string): Promise<HttpResponse>;
30
- http_post(url: string, headers?: Record<string, string | string[]> | string, body?: string): Promise<HttpResponse>;
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 ____index = require("index")
15
- local pollnet = ____index.default
16
- --- Run `body` inside a reactor coroutine and get its completion as a Promise.
17
- -- `body` may freely use socket.await() / other yield-based pollnet APIs.
18
- -- Errors inside body reject the promise.
19
- ____exports.spawn = function(____, reactor, body)
20
- return __TS__New(
21
- __TS__Promise,
22
- function(____, resolve, reject)
23
- reactor:run(function()
24
- do
25
- local function ____catch(e)
26
- reject(nil, e)
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
- local ____try, ____hasReturned = pcall(function()
29
- resolve(
30
- nil,
31
- body(nil)
32
- )
33
- end)
34
- if not ____try then
35
- ____catch(____hasReturned)
36
- end
37
- end
38
- end)
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
- end
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
- return result
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 __continue14
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 __continue14
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
- ::__continue14::
137
+ ::__continue24::
102
138
  end
103
139
  return headers
104
140
  end
105
- ____exports.default = __TS__Class()
106
- local AsyncReactor = ____exports.default
107
- AsyncReactor.name = "AsyncReactor"
108
- function AsyncReactor.prototype.____constructor(self)
109
- self.reactor = pollnet.Reactor()
110
- end
111
- function AsyncReactor.prototype.update(self)
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 AsyncReactor.prototype.run(self, thread_body)
115
- self.reactor:run(thread_body)
116
- end
117
- function AsyncReactor.prototype.run_server(self, server_sock, client_body)
118
- self.reactor:run_server(server_sock, client_body)
119
- end
120
- function AsyncReactor.prototype.http_get(self, url, headers)
121
- return ____exports.spawn(
122
- nil,
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 AsyncReactor.prototype.http_post(self, url, headers, body)
140
- return ____exports.spawn(
141
- nil,
142
- self.reactor,
143
- function()
144
- local socket = pollnet.http_post(url, headers, body, false)
145
- local msgs, ____error = socket:await_n(3)
146
- if not msgs then
147
- error(
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