@amxts/core 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.
Files changed (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/README.ru.md +162 -0
  4. package/amxmodx/base/include/amxconst.inc +594 -0
  5. package/amxmodx/base/include/amxmisc.inc +902 -0
  6. package/amxmodx/base/include/amxmodx.inc +3447 -0
  7. package/amxmodx/base/include/amxmodx_version.inc +20 -0
  8. package/amxmodx/base/include/cellarray.inc +525 -0
  9. package/amxmodx/base/include/cellstack.inc +166 -0
  10. package/amxmodx/base/include/celltrie.inc +412 -0
  11. package/amxmodx/base/include/core.inc +202 -0
  12. package/amxmodx/base/include/csstats.inc +298 -0
  13. package/amxmodx/base/include/csstats_const.inc +29 -0
  14. package/amxmodx/base/include/cstrike.inc +1287 -0
  15. package/amxmodx/base/include/cstrike_const.inc +521 -0
  16. package/amxmodx/base/include/csx.inc +259 -0
  17. package/amxmodx/base/include/cvars.inc +547 -0
  18. package/amxmodx/base/include/datapack.inc +161 -0
  19. package/amxmodx/base/include/dbi.inc +154 -0
  20. package/amxmodx/base/include/dodconst.inc +152 -0
  21. package/amxmodx/base/include/dodfun.inc +152 -0
  22. package/amxmodx/base/include/dodstats.inc +69 -0
  23. package/amxmodx/base/include/dodx.inc +161 -0
  24. package/amxmodx/base/include/engine.inc +1343 -0
  25. package/amxmodx/base/include/engine_const.inc +310 -0
  26. package/amxmodx/base/include/engine_stocks.inc +248 -0
  27. package/amxmodx/base/include/esf.inc +70 -0
  28. package/amxmodx/base/include/esf_const.inc +74 -0
  29. package/amxmodx/base/include/fakemeta.inc +1127 -0
  30. package/amxmodx/base/include/fakemeta_const.inc +793 -0
  31. package/amxmodx/base/include/fakemeta_stocks.inc +395 -0
  32. package/amxmodx/base/include/fakemeta_util.inc +882 -0
  33. package/amxmodx/base/include/file.inc +666 -0
  34. package/amxmodx/base/include/float.inc +422 -0
  35. package/amxmodx/base/include/fun.inc +333 -0
  36. package/amxmodx/base/include/gameconfig.inc +93 -0
  37. package/amxmodx/base/include/geoip.inc +264 -0
  38. package/amxmodx/base/include/ham_const.inc +4352 -0
  39. package/amxmodx/base/include/hamsandwich.inc +439 -0
  40. package/amxmodx/base/include/hlsdk_const.inc +808 -0
  41. package/amxmodx/base/include/json.inc +777 -0
  42. package/amxmodx/base/include/lang.inc +119 -0
  43. package/amxmodx/base/include/message_const.inc +1130 -0
  44. package/amxmodx/base/include/message_stocks.inc +161 -0
  45. package/amxmodx/base/include/messages.inc +604 -0
  46. package/amxmodx/base/include/newmenus.inc +387 -0
  47. package/amxmodx/base/include/ns.inc +754 -0
  48. package/amxmodx/base/include/ns_const.inc +196 -0
  49. package/amxmodx/base/include/nvault.inc +154 -0
  50. package/amxmodx/base/include/regex.inc +348 -0
  51. package/amxmodx/base/include/sockets.inc +183 -0
  52. package/amxmodx/base/include/sorting.inc +107 -0
  53. package/amxmodx/base/include/sqlx.inc +582 -0
  54. package/amxmodx/base/include/string.inc +786 -0
  55. package/amxmodx/base/include/string_const.inc +156 -0
  56. package/amxmodx/base/include/string_stocks.inc +325 -0
  57. package/amxmodx/base/include/textparse_ini.inc +214 -0
  58. package/amxmodx/base/include/textparse_smc.inc +261 -0
  59. package/amxmodx/base/include/tfcconst.inc +84 -0
  60. package/amxmodx/base/include/tfcstats.inc +62 -0
  61. package/amxmodx/base/include/tfcx.inc +148 -0
  62. package/amxmodx/base/include/time.inc +118 -0
  63. package/amxmodx/base/include/tsconst.inc +154 -0
  64. package/amxmodx/base/include/tsfun.inc +198 -0
  65. package/amxmodx/base/include/tsstats.inc +65 -0
  66. package/amxmodx/base/include/tsx.inc +88 -0
  67. package/amxmodx/base/include/vault.inc +60 -0
  68. package/amxmodx/base/include/vector.inc +131 -0
  69. package/amxmodx/base/include/xs.inc +1570 -0
  70. package/as/amxts.d.ts +153 -0
  71. package/as/constants.ts +4730 -0
  72. package/as/effects.ts +1449 -0
  73. package/as/entities.ts +5482 -0
  74. package/as/events.ts +3054 -0
  75. package/as/facade.ts +4639 -0
  76. package/as/flags.ts +299 -0
  77. package/as/fs.ts +287 -0
  78. package/as/hooks.ts +18536 -0
  79. package/as/kit.ts +25 -0
  80. package/as/lib/check.ts +86 -0
  81. package/as/modules/http.ts +184 -0
  82. package/as/natives.ts +11845 -0
  83. package/as/os.ts +30 -0
  84. package/as/promise.ts +1392 -0
  85. package/as/promise.types.d.ts +82 -0
  86. package/as/remote.ts +288 -0
  87. package/as/tsconfig.json +22 -0
  88. package/as/vector.ts +65 -0
  89. package/bin/amxts.mjs +10 -0
  90. package/includes/menu_core.inc +355 -0
  91. package/includes/order.txt +54 -0
  92. package/includes/sources.json +27 -0
  93. package/includes/universal_config.inc +355 -0
  94. package/lint/oxlint-plugin.mjs +77 -0
  95. package/node_modules/assemblyscript/LICENSE +201 -0
  96. package/node_modules/assemblyscript/NOTICE +93 -0
  97. package/node_modules/assemblyscript/package.json +63 -0
  98. package/node_modules/assemblyscript/std/README.md +6 -0
  99. package/node_modules/assemblyscript/std/assembly/array.ts +526 -0
  100. package/node_modules/assemblyscript/std/assembly/arraybuffer.ts +77 -0
  101. package/node_modules/assemblyscript/std/assembly/atomics.ts +127 -0
  102. package/node_modules/assemblyscript/std/assembly/bindings/asyncify.ts +16 -0
  103. package/node_modules/assemblyscript/std/assembly/bindings/dom.ts +291 -0
  104. package/node_modules/assemblyscript/std/assembly/bindings/node.ts +6 -0
  105. package/node_modules/assemblyscript/std/assembly/builtins.ts +2631 -0
  106. package/node_modules/assemblyscript/std/assembly/compat.ts +2 -0
  107. package/node_modules/assemblyscript/std/assembly/console.ts +42 -0
  108. package/node_modules/assemblyscript/std/assembly/crypto.ts +9 -0
  109. package/node_modules/assemblyscript/std/assembly/dataview.ts +181 -0
  110. package/node_modules/assemblyscript/std/assembly/date.ts +373 -0
  111. package/node_modules/assemblyscript/std/assembly/diagnostics.ts +11 -0
  112. package/node_modules/assemblyscript/std/assembly/error.ts +44 -0
  113. package/node_modules/assemblyscript/std/assembly/function.ts +38 -0
  114. package/node_modules/assemblyscript/std/assembly/index.d.ts +2822 -0
  115. package/node_modules/assemblyscript/std/assembly/iterator.ts +35 -0
  116. package/node_modules/assemblyscript/std/assembly/map.ts +260 -0
  117. package/node_modules/assemblyscript/std/assembly/math.ts +3289 -0
  118. package/node_modules/assemblyscript/std/assembly/memory.ts +123 -0
  119. package/node_modules/assemblyscript/std/assembly/number.ts +388 -0
  120. package/node_modules/assemblyscript/std/assembly/object.ts +36 -0
  121. package/node_modules/assemblyscript/std/assembly/performance.ts +9 -0
  122. package/node_modules/assemblyscript/std/assembly/polyfills.ts +27 -0
  123. package/node_modules/assemblyscript/std/assembly/process.ts +50 -0
  124. package/node_modules/assemblyscript/std/assembly/reference.ts +48 -0
  125. package/node_modules/assemblyscript/std/assembly/regexp.ts +12 -0
  126. package/node_modules/assemblyscript/std/assembly/rt/README.md +83 -0
  127. package/node_modules/assemblyscript/std/assembly/rt/common.ts +81 -0
  128. package/node_modules/assemblyscript/std/assembly/rt/index-incremental.ts +2 -0
  129. package/node_modules/assemblyscript/std/assembly/rt/index-minimal.ts +2 -0
  130. package/node_modules/assemblyscript/std/assembly/rt/index-stub.ts +1 -0
  131. package/node_modules/assemblyscript/std/assembly/rt/index.d.ts +37 -0
  132. package/node_modules/assemblyscript/std/assembly/rt/itcms.ts +419 -0
  133. package/node_modules/assemblyscript/std/assembly/rt/rtrace.ts +15 -0
  134. package/node_modules/assemblyscript/std/assembly/rt/stub.ts +133 -0
  135. package/node_modules/assemblyscript/std/assembly/rt/tcms.ts +254 -0
  136. package/node_modules/assemblyscript/std/assembly/rt/tlsf.ts +592 -0
  137. package/node_modules/assemblyscript/std/assembly/rt.ts +87 -0
  138. package/node_modules/assemblyscript/std/assembly/set.ts +220 -0
  139. package/node_modules/assemblyscript/std/assembly/shared/feature.ts +65 -0
  140. package/node_modules/assemblyscript/std/assembly/shared/runtime.ts +11 -0
  141. package/node_modules/assemblyscript/std/assembly/shared/target.ts +11 -0
  142. package/node_modules/assemblyscript/std/assembly/shared/tsconfig.json +11 -0
  143. package/node_modules/assemblyscript/std/assembly/shared/typeinfo.ts +72 -0
  144. package/node_modules/assemblyscript/std/assembly/staticarray.ts +401 -0
  145. package/node_modules/assemblyscript/std/assembly/string.ts +847 -0
  146. package/node_modules/assemblyscript/std/assembly/symbol.ts +114 -0
  147. package/node_modules/assemblyscript/std/assembly/table.ts +16 -0
  148. package/node_modules/assemblyscript/std/assembly/tsconfig.json +6 -0
  149. package/node_modules/assemblyscript/std/assembly/typedarray.ts +1945 -0
  150. package/node_modules/assemblyscript/std/assembly/uri.ts +17 -0
  151. package/node_modules/assemblyscript/std/assembly/util/bytes.ts +107 -0
  152. package/node_modules/assemblyscript/std/assembly/util/casemap.ts +497 -0
  153. package/node_modules/assemblyscript/std/assembly/util/error.ts +54 -0
  154. package/node_modules/assemblyscript/std/assembly/util/hash.ts +117 -0
  155. package/node_modules/assemblyscript/std/assembly/util/math.ts +1922 -0
  156. package/node_modules/assemblyscript/std/assembly/util/memory.ts +290 -0
  157. package/node_modules/assemblyscript/std/assembly/util/number.ts +873 -0
  158. package/node_modules/assemblyscript/std/assembly/util/sort.ts +313 -0
  159. package/node_modules/assemblyscript/std/assembly/util/string.ts +1202 -0
  160. package/node_modules/assemblyscript/std/assembly/util/uri.ts +275 -0
  161. package/node_modules/assemblyscript/std/assembly/vector.ts +4 -0
  162. package/node_modules/assemblyscript/std/assembly.json +16 -0
  163. package/node_modules/assemblyscript/std/portable/index.d.ts +462 -0
  164. package/node_modules/assemblyscript/std/portable/index.js +416 -0
  165. package/node_modules/assemblyscript/std/portable.json +11 -0
  166. package/node_modules/assemblyscript/std/types/assembly/index.d.ts +1 -0
  167. package/node_modules/assemblyscript/std/types/assembly/package.json +3 -0
  168. package/node_modules/assemblyscript/std/types/portable/index.d.ts +1 -0
  169. package/node_modules/assemblyscript/std/types/portable/package.json +3 -0
  170. package/node_modules/assemblyscript/tsconfig-base.json +13 -0
  171. package/package.json +112 -0
  172. package/runtime/deps/assemblyscript/LICENSE +201 -0
  173. package/runtime/deps/assemblyscript/NOTICE +93 -0
  174. package/runtime/deps/assemblyscript/bin/asc.js +35 -0
  175. package/runtime/deps/assemblyscript/dist/asc.js +25035 -0
  176. package/runtime/deps/assemblyscript/dist/assemblyscript.js +337 -0
  177. package/runtime/deps/assemblyscript/node_modules/binaryen/LICENSE +201 -0
  178. package/runtime/deps/assemblyscript/node_modules/binaryen/index.js +28905 -0
  179. package/runtime/deps/assemblyscript/node_modules/binaryen/package.json +50 -0
  180. package/runtime/deps/assemblyscript/node_modules/long/LICENSE +202 -0
  181. package/runtime/deps/assemblyscript/node_modules/long/index.js +1581 -0
  182. package/runtime/deps/assemblyscript/node_modules/long/package.json +58 -0
  183. package/runtime/deps/assemblyscript/package.json +114 -0
  184. package/runtime/host/amxts.inc +85 -0
  185. package/runtime/licenses/AMXX-LICENSE.txt +34 -0
  186. package/runtime/licenses/AssemblyScript-LICENSE +201 -0
  187. package/runtime/licenses/AssemblyScript-NOTICE +93 -0
  188. package/runtime/licenses/Binaryen-LICENSE +201 -0
  189. package/runtime/licenses/Bun-LICENSE.md +84 -0
  190. package/runtime/licenses/GPL-3.0.txt +674 -0
  191. package/runtime/licenses/LLVM-LICENSE.TXT +279 -0
  192. package/runtime/licenses/README.md +25 -0
  193. package/runtime/licenses/WAMR-LICENSE +219 -0
  194. package/runtime/natives.txt +1095 -0
  195. package/runtime/patches/README.md +59 -0
  196. package/runtime/patches/assemblyscript-0.28.20-amxts.patch +14174 -0
  197. package/runtime/patches/wamr-2.4.5-amxts.patch +364 -0
  198. package/scripts/apply-docs.ts +508 -0
  199. package/scripts/asc.ts +27 -0
  200. package/scripts/auto-imports.ts +258 -0
  201. package/scripts/build-wasm.ts +595 -0
  202. package/scripts/check.ts +93 -0
  203. package/scripts/compile-cache.ts +179 -0
  204. package/scripts/compile.ts +401 -0
  205. package/scripts/docker-server.ts +73 -0
  206. package/scripts/docs/as/amxts.ts +210 -0
  207. package/scripts/docs/as/effects.ts +1684 -0
  208. package/scripts/docs/as/facade.ts +3302 -0
  209. package/scripts/docs/as/fs.ts +173 -0
  210. package/scripts/docs/as/lib/check.ts +68 -0
  211. package/scripts/docs/as/modules/http.ts +66 -0
  212. package/scripts/docs/as/os.ts +16 -0
  213. package/scripts/docs/as/promise.ts +132 -0
  214. package/scripts/docs/as/promise.types.ts +63 -0
  215. package/scripts/docs/as/vector.ts +48 -0
  216. package/scripts/docs/entities.ts +2338 -0
  217. package/scripts/docs/events.ts +245 -0
  218. package/scripts/docs/game.ts +497 -0
  219. package/scripts/docs/messages.ts +148 -0
  220. package/scripts/file-contents.ts +74 -0
  221. package/scripts/includes.ts +134 -0
  222. package/scripts/player-fields.ts +866 -0
  223. package/scripts/plugin-cache.ts +92 -0
  224. package/scripts/plugin-natives.ts +1157 -0
  225. package/scripts/prebuilt.ts +268 -0
  226. package/scripts/prepare.ts +134 -0
  227. package/scripts/project.ts +973 -0
  228. package/scripts/run.ts +28 -0
  229. package/scripts/shared-modules.ts +906 -0
  230. package/scripts/system.ts +33 -0
  231. package/scripts/tracked-fs.ts +115 -0
  232. package/scripts/typed-configs.ts +788 -0
  233. package/scripts/ui.ts +77 -0
  234. package/src/cli-api.mjs +175 -0
  235. package/src/parser/include-parser.ts +506 -0
  236. package/src/system.mjs +155 -0
  237. package/src/testing/compile-cache.ts +31 -0
  238. package/src/testing/compile.ts +222 -0
  239. package/src/testing/coroutines.ts +191 -0
  240. package/src/testing/index.ts +39 -0
  241. package/src/testing/kits.ts +55 -0
  242. package/src/testing/memory.ts +125 -0
  243. package/src/testing/natives.ts +925 -0
  244. package/src/testing/server.ts +1874 -0
  245. package/src/testing/setup.ts +63 -0
  246. package/src/testing/tables.ts +139 -0
  247. package/src/types.ts +51 -0
package/as/promise.ts ADDED
@@ -0,0 +1,1392 @@
1
+ // Promise, async/await and AbortSignal: the hood under them.
2
+ //
3
+ // The compiler reads the classes through `@global`, so `Promise`,
4
+ // `AbortController`, `AbortSignal` and `Event` are the globals they are in
5
+ // JavaScript; the facade imports the file for it, and nothing else needs to.
6
+ // The editor reads them through as/promise.types.d.ts, which makes what this
7
+ // file exports global - an `async function` is typed with this very Promise.
8
+ //
9
+ // How an async function runs (the compiler half is Compiler.compileAsyncPrologue
10
+ // in runtime/deps/assemblyscript/src/compiler.ts, the host half is the
11
+ // coroutine code in runtime/src/module.cpp):
12
+ //
13
+ // - A call to it makes its Promise and asks the host (co_spawn) to call it
14
+ // again through the table: that second call is the body, a coroutine of its
15
+ // own. The body runs at once, up to its first `await`.
16
+ // - `await p` (__await) parks the coroutine: the host unwinds it with
17
+ // Asyncify back to co_spawn, keeps its shadow stack here (__co_park), and
18
+ // the caller goes on with a pending Promise - a call without `await` does
19
+ // not wait, as in JavaScript.
20
+ // - When p settles, its reactions become jobs (microtasks). The host runs
21
+ // them (__co_next) once the plugin has nothing of its own on the stack, and
22
+ // a coroutine waiting on p is rewound from there.
23
+ //
24
+ // A rejection - or a `throw` in an async function, which the compiler makes
25
+ // one (__co_throw) - travels to whoever awaits it. Inside a `try` the await
26
+ // gives the reason to its `catch` (the compiler's exceptions, see
27
+ // std/assembly/error.ts); outside every one the awaiting coroutine gives up
28
+ // with the same reason. It ends in a `catch`, `.catch` or as one "Unhandled
29
+ // promise rejection" line. A coroutine counts its own `try` blocks
30
+ // (__tryDepth): the count is kept across an await and put back around a
31
+ // spawn and a resume.
32
+
33
+ // ---------------------------------------------------------------- host
34
+
35
+ // @ts-ignore: decorator
36
+ @external("env", "co_entered") declare function __co_host_entered(): i32;
37
+ // @ts-ignore: decorator
38
+ @external("env", "co_spawn") declare function __co_host_spawn(fn: i32, args: usize, cells: i32, id: i32, buffer: usize): i32;
39
+ // @ts-ignore: decorator
40
+ @external("env", "co_suspend") declare function __co_host_suspend(drop: i32): void;
41
+ // @ts-ignore: decorator
42
+ @external("env", "co_wake") declare function __co_host_wake(): void;
43
+ // @ts-ignore: decorator
44
+ @external("env", "co_id") declare function __co_host_id(): i32;
45
+ // @ts-ignore: decorator
46
+ @external("env", "task") declare function __co_host_task(secondsBits: i32, fn: i32, id: i32, repeat: i32): i32;
47
+ // @ts-ignore: decorator
48
+ @external("env", "stop_task") declare function __co_host_stop_task(id: i32): i32;
49
+ // @ts-ignore: decorator
50
+ @external("env", "on") declare function __co_host_on(event: string, fn: i32, shape: i32): void;
51
+
52
+ // What co_spawn and a resume end with. Must match CO_* in runtime/src/module.cpp.
53
+ const __CO_FINISHED: i32 = 0;
54
+ const __CO_PARKED: i32 = 1;
55
+ const __CO_TRAPPED: i32 = 2;
56
+ const __CO_DROPPED: i32 = 3;
57
+
58
+ /**
59
+ * Bytes Asyncify may use to keep one parked coroutine: the locals of the
60
+ * async function and of __await. A deep async function needs a few hundred;
61
+ * running out is reported by the host rather than trapping silently.
62
+ */
63
+ const __CO_BUFFER: i32 = 4096;
64
+
65
+ // ---------------------------------------------------------------- jobs
66
+
67
+ /** A microtask: a reaction to a settled promise, or a coroutine to resume. */
68
+ class __Job {
69
+ /** The coroutine to resume, when this is one; the host resumes it. */
70
+ coroutine: i32 = 0;
71
+ /** Which wait of that coroutine this resumes - a stale one is skipped. */
72
+ wait: i32 = 0;
73
+
74
+ run(): void {}
75
+ }
76
+
77
+ // @ts-ignore: decorator
78
+ @lazy const __jobs: (__Job | null)[] = [];
79
+ // @ts-ignore: decorator
80
+ @lazy let __jobHead: i32 = 0;
81
+ // @ts-ignore: decorator
82
+ @lazy let __woken = false;
83
+ // @ts-ignore: decorator
84
+ @lazy const __unhandled: PromiseBase[] = [];
85
+
86
+ function __co_queue(job: __Job): void {
87
+ __jobs.push(job);
88
+ __co_wake_up();
89
+ }
90
+
91
+ /** Tells the host there is work for when the plugin's stack is empty. */
92
+ function __co_wake_up(): void {
93
+ if (__woken) return;
94
+ __woken = true;
95
+ __co_host_wake();
96
+ }
97
+
98
+ // ---------------------------------------------------------------- promises
99
+
100
+ const __PENDING: i32 = 0;
101
+ const __FULFILLED: i32 = 1;
102
+ const __REJECTED: i32 = 2;
103
+
104
+ // Its state, and its value as raw storage - a reference, or the bits of a
105
+ // number - so the host and the compiler can settle one without knowing T.
106
+ /** The base of every Promise, whatever its value's type; a plugin uses Promise<T>. */
107
+ // @ts-ignore: decorator
108
+ @global export class PromiseBase {
109
+ /** @hidden */ __state: i32 = 0;
110
+ /** @hidden settled with a value, not with nothing - an async listener's answer. */
111
+ __hasValue: bool = false;
112
+ /** @hidden */ __ref: Object | null = null;
113
+ /** @hidden */ __bits: u64 = 0;
114
+ /** @hidden */ __reason: Error | null = null;
115
+ /** @hidden something reacts to a rejection: then, catch, await. */
116
+ __handled: bool = false;
117
+ /** @hidden */ __reactions: __Job[] | null = null;
118
+
119
+ /** @hidden Settles with a reference - like the promise it is given, as in JavaScript, when it is one. */
120
+ __resolveRef(ref: Object | null): void {
121
+ if (ref instanceof PromiseBase) {
122
+ (ref as PromiseBase).__react(new __AdoptJob(ref as PromiseBase, this));
123
+ return;
124
+ }
125
+ this.__fulfillRaw(ref, 0, true);
126
+ }
127
+
128
+ /** @hidden */
129
+ __fulfillRaw(ref: Object | null, bits: u64, hasValue: bool): void {
130
+ if (this.__state != __PENDING) return;
131
+ this.__state = __FULFILLED;
132
+ this.__ref = ref;
133
+ this.__bits = bits;
134
+ this.__hasValue = hasValue;
135
+ this.__flush();
136
+ }
137
+
138
+ /** @hidden settled with nothing: `return;`, resolve(). */
139
+ __fulfillVoid(): void {
140
+ this.__fulfillRaw(null, 0, false);
141
+ }
142
+
143
+ /** @hidden */
144
+ __reject(reason: Error): void {
145
+ if (this.__state != __PENDING) return;
146
+ this.__state = __REJECTED;
147
+ this.__reason = reason;
148
+ // Nobody to hear it yet: reported when the jobs run out, unless a
149
+ // handler is attached before then.
150
+ if (!this.__handled) {
151
+ __unhandled.push(this);
152
+ __co_wake_up();
153
+ }
154
+ this.__flush();
155
+ }
156
+
157
+ /** @hidden the same state as `other`, which has settled. */
158
+ __settleLike(other: PromiseBase): void {
159
+ if (other.__state == __REJECTED) {
160
+ this.__reject(other.__reason as Error);
161
+ return;
162
+ }
163
+
164
+ // A race of an integer and a number is a number: the integer's bits,
165
+ // read as one.
166
+ const bits = this.__isFloat() && !other.__isFloat() ? reinterpret<u64>(<f64><i64>other.__bits) : other.__bits;
167
+ this.__fulfillRaw(other.__ref, bits, other.__hasValue);
168
+ }
169
+
170
+ /** @hidden whether its value is stored as a float's bits. */
171
+ __isFloat(): bool {
172
+ return false;
173
+ }
174
+
175
+ /** @hidden runs `job` once this settles - now, as a microtask, if it has. */
176
+ __react(job: __Job): void {
177
+ this.__handled = true;
178
+ if (this.__state != __PENDING) {
179
+ __co_queue(job);
180
+ return;
181
+ }
182
+ let reactions = this.__reactions;
183
+ if (!reactions) this.__reactions = reactions = [];
184
+ reactions.push(job);
185
+ }
186
+
187
+ private __flush(): void {
188
+ const reactions = this.__reactions;
189
+ if (!reactions) return;
190
+ this.__reactions = null;
191
+ for (let i = 0; i < reactions.length; i++) __co_queue(reactions[i]);
192
+ }
193
+ }
194
+
195
+ // Only the editor reads it (TypeScript asks for the global); the compiler
196
+ // awaits a Promise and nothing else.
197
+ /** Anything with a `then`: the type `await` takes in the editor. In a plugin, `await` a Promise. */
198
+ export interface PromiseLike<T> {
199
+ /** Calls `onFulfilled` with the value once there is one. */
200
+ then(onFulfilled: (value: T) => void): void;
201
+ }
202
+
203
+ /** A value that is not there yet: the result of a request, a timer, an async function. */
204
+ // @ts-ignore: decorator
205
+ @global export class Promise<T> extends PromiseBase {
206
+ /**
207
+ * Wraps a callback API: `executor` runs at once and is handed the two
208
+ * functions that settle this promise, which the callbacks it sets up may
209
+ * call later.
210
+ *
211
+ * ```ts
212
+ * const later = new Promise<string>((resolve) => {
213
+ * setTimeout(() => resolve("done"), 1000);
214
+ * });
215
+ * ```
216
+ */
217
+ constructor(executor: (resolve: (value?: T) => void, reject: (reason: Error) => void) => void) {
218
+ super();
219
+ executor(__co_resolver<T>(this), __co_rejecter(this));
220
+ }
221
+
222
+ /**
223
+ * Calls `onFulfilled` with the value once there is one; the promise it
224
+ * returns settles with what that returns. A rejection passes through to
225
+ * it untouched, or to `onRejected` when there is one.
226
+ */
227
+ then<U = void>(onFulfilled: (value: T) => U, onRejected: ((reason: Error) => U) | null = null): Promise<U> {
228
+ const next = __co_promise<U>();
229
+ this.__react(new __ThenJob<T, U>(this, next, onFulfilled, onRejected));
230
+ return next;
231
+ }
232
+
233
+ /**
234
+ * Calls `onRejected` with the reason if this is rejected. What it returns
235
+ * is the value instead: `readFile(path).catch(() => "")` - or nothing, when
236
+ * it only logs.
237
+ */
238
+ catch<R = void>(onRejected: (reason: Error) => R): Promise<T> {
239
+ const next = __co_promise<T>();
240
+ this.__react(new __CatchJob<T, R>(this, next, onRejected));
241
+ return next;
242
+ }
243
+
244
+ /** Calls `onFinally` once this settles, either way, and passes the outcome on. */
245
+ finally(onFinally: () => void): Promise<T> {
246
+ const next = __co_promise<T>();
247
+ this.__react(new __FinallyJob<T>(this, next, onFinally));
248
+ return next;
249
+ }
250
+
251
+ /** A promise already fulfilled with `value`. */
252
+ static resolve<T>(value: T): Promise<T> {
253
+ const promise = __co_promise<T>();
254
+ promise.__resolveWith(value);
255
+ return promise;
256
+ }
257
+
258
+ /** A promise already rejected with `reason`. */
259
+ static reject<T = void>(reason: Error): Promise<T> {
260
+ const promise = __co_promise<T>();
261
+ promise.__reject(reason);
262
+ return promise;
263
+ }
264
+
265
+ /** @hidden */
266
+ __isFloat(): bool {
267
+ return isFloat<T>();
268
+ }
269
+
270
+ /** @hidden the value, once fulfilled. */
271
+ __value(): T {
272
+ if (isReference<T>()) return changetype<T>(this.__ref);
273
+ else if (isFloat<T>()) return <T>reinterpret<f64>(this.__bits);
274
+ else return <T><i64>this.__bits;
275
+ }
276
+
277
+ /** @hidden */
278
+ __resolveWith(value: T): void {
279
+ if (isReference<T>()) {
280
+ this.__resolveRef(changetype<Object | null>(changetype<usize>(value)));
281
+ } else if (isFloat<T>()) {
282
+ this.__fulfillRaw(null, reinterpret<u64>(<f64>value), true);
283
+ } else {
284
+ this.__fulfillRaw(null, <u64><i64>value, true);
285
+ }
286
+ }
287
+ }
288
+
289
+ /** @hidden a pending Promise<T>, made without an executor. */
290
+ // @ts-ignore: decorator
291
+ @global export function __co_promise<T>(): Promise<T> {
292
+ // @ts-ignore: the runtime's allocator, which the editor's typings leave out
293
+ return changetype<Promise<T>>(__new(offsetof<Promise<T>>(), idof<Promise<T>>()));
294
+ }
295
+
296
+ /** @hidden fulfils `promise` from outside: what fetch and sleep settle with. */
297
+ // @ts-ignore: decorator
298
+ @global export function __co_resolve<T>(promise: Promise<T>, value: T): void {
299
+ promise.__resolveWith(value);
300
+ }
301
+
302
+ /** @hidden */
303
+ // @ts-ignore: decorator
304
+ @global export function __co_reject(promise: PromiseBase, reason: Error): void {
305
+ promise.__reject(reason);
306
+ }
307
+
308
+ class __ThenJob<T, U> extends __Job {
309
+ constructor(
310
+ public source: Promise<T>,
311
+ public target: Promise<U>,
312
+ public onFulfilled: (value: T) => U,
313
+ public onRejected: ((reason: Error) => U) | null
314
+ ) {
315
+ super();
316
+ }
317
+
318
+ run(): void {
319
+ const source = this.source;
320
+ const target = this.target;
321
+ if (source.__state == __FULFILLED) {
322
+ const fn = this.onFulfilled;
323
+ if (isVoid<U>()) {
324
+ fn(source.__value());
325
+ target.__fulfillVoid();
326
+ } else {
327
+ target.__resolveWith(fn(source.__value()));
328
+ }
329
+ return;
330
+ }
331
+ const reason = source.__reason as Error;
332
+ const fn = this.onRejected;
333
+ if (!fn) {
334
+ target.__reject(reason);
335
+ return;
336
+ }
337
+ if (isVoid<U>()) {
338
+ fn(reason);
339
+ target.__fulfillVoid();
340
+ } else {
341
+ target.__resolveWith(fn(reason));
342
+ }
343
+ }
344
+ }
345
+
346
+ class __CatchJob<T, R> extends __Job {
347
+ constructor(public source: Promise<T>, public target: Promise<T>, public onRejected: (reason: Error) => R) {
348
+ super();
349
+ }
350
+
351
+ run(): void {
352
+ const source = this.source;
353
+ if (source.__state == __FULFILLED) {
354
+ this.target.__settleLike(source);
355
+ return;
356
+ }
357
+ const fn = this.onRejected;
358
+ if (isVoid<R>()) {
359
+ fn(source.__reason as Error);
360
+ this.target.__fulfillVoid();
361
+ return;
362
+ }
363
+ // `.catch((error) => fallback)`: the handler's answer is the value, as
364
+ // in JavaScript. It used to be dropped, and an awaited
365
+ // `readFile(path).catch(() => "")` came back as an empty pointer.
366
+ this.target.__resolveWith(changetype<T>(fn(source.__reason as Error)));
367
+ }
368
+ }
369
+
370
+ class __FinallyJob<T> extends __Job {
371
+ constructor(public source: Promise<T>, public target: Promise<T>, public onFinally: () => void) {
372
+ super();
373
+ }
374
+
375
+ run(): void {
376
+ const fn = this.onFinally;
377
+ fn();
378
+ this.target.__settleLike(this.source);
379
+ }
380
+ }
381
+
382
+ class __AdoptJob extends __Job {
383
+ constructor(public source: PromiseBase, public target: PromiseBase) {
384
+ super();
385
+ }
386
+
387
+ run(): void {
388
+ this.target.__settleLike(this.source);
389
+ }
390
+ }
391
+
392
+ // Promise.all, allSettled, race and any. They are not members of Promise:
393
+ // the editor reads them from promise.types.d.ts, typed with TypeScript's
394
+ // tuples, and the compiler lowers a call to one of the functions here
395
+ // instead (Resolver.lowerPromiseCall) - a list, or a literal of one type, to
396
+ // __co_all and the rest; a literal of different types to __co_allN, whose
397
+ // value is a __TupleN.
398
+
399
+ class __AllState<T> {
400
+ results: T[];
401
+ remaining: i32;
402
+
403
+ constructor(public target: Promise<T[]>, count: i32) {
404
+ this.results = new Array<T>(count);
405
+ this.remaining = count;
406
+ }
407
+ }
408
+
409
+ class __AllJob<T> extends __Job {
410
+ constructor(public state: __AllState<T>, public source: Promise<T>, public index: i32) {
411
+ super();
412
+ }
413
+
414
+ run(): void {
415
+ const state = this.state;
416
+ const source = this.source;
417
+ if (source.__state == __REJECTED) {
418
+ state.target.__reject(source.__reason as Error);
419
+ return;
420
+ }
421
+ state.results[this.index] = source.__value();
422
+ if (--state.remaining == 0) state.target.__resolveWith(state.results);
423
+ }
424
+ }
425
+
426
+ /** @hidden Promise.all: every value, in order, once all are; rejected with the first rejection. */
427
+ // @ts-ignore: decorator
428
+ @global function __co_all<T>(values: Promise<T>[]): Promise<T[]> {
429
+ const promise = __co_promise<T[]>();
430
+ const state = new __AllState<T>(promise, values.length);
431
+ if (values.length == 0) promise.__resolveWith(state.results);
432
+ for (let i = 0; i < values.length; i++) values[i].__react(new __AllJob<T>(state, values[i], i));
433
+ return promise;
434
+ }
435
+
436
+ /** @hidden Promise.all of a list of values, not promises: settled with a copy of the list. */
437
+ // @ts-ignore: decorator
438
+ @global function __co_allValues<T>(values: T[]): Promise<T[]> {
439
+ const promise = __co_promise<T[]>();
440
+ promise.__resolveWith(values.slice());
441
+ return promise;
442
+ }
443
+
444
+ /** A promise's outcome, as Promise.allSettled gives it for each. */
445
+ // @ts-ignore: decorator
446
+ @global export class PromiseSettledResult<T> {
447
+ /** @hidden made by allSettled, field by field: the constructor never runs. */
448
+ constructor(
449
+ /** The promise's outcome, either `"fulfilled"` or `"rejected"`. */
450
+ public status: "fulfilled" | "rejected",
451
+ /** The promise's value, when fulfilled. */
452
+ public value: T,
453
+ /** The rejection's reason, when rejected. */
454
+ public reason: Error
455
+ ) {}
456
+ }
457
+
458
+ /**
459
+ * @hidden an object of class T with every field zero, its constructor not
460
+ * run: a result or a tuple whose fields are filled in one by one.
461
+ */
462
+ function __co_blank<T>(): T {
463
+ // @ts-ignore: the runtime's allocator, which the editor's typings leave out
464
+ return changetype<T>(__new(offsetof<T>(), idof<T>()));
465
+ }
466
+
467
+ class __SettleJob<T> extends __Job {
468
+ constructor(public source: Promise<T>, public target: Promise<PromiseSettledResult<T>>) {
469
+ super();
470
+ }
471
+
472
+ run(): void {
473
+ const source = this.source;
474
+ const result = __co_blank<PromiseSettledResult<T>>();
475
+ if (source.__state == __REJECTED) {
476
+ result.status = "rejected";
477
+ result.reason = source.__reason as Error;
478
+ } else {
479
+ result.status = "fulfilled";
480
+ result.value = source.__value();
481
+ }
482
+ this.target.__resolveWith(result);
483
+ }
484
+ }
485
+
486
+ /** @hidden a promise always fulfilled, with how `promise` settled. */
487
+ // @ts-ignore: decorator
488
+ @global function __co_settle<T>(promise: Promise<T>): Promise<PromiseSettledResult<T>> {
489
+ const settled = __co_promise<PromiseSettledResult<T>>();
490
+ promise.__react(new __SettleJob<T>(promise, settled));
491
+ return settled;
492
+ }
493
+
494
+ /** @hidden Promise.allSettled: how each settled, in order, once all have. */
495
+ // @ts-ignore: decorator
496
+ @global function __co_allSettled<T>(values: Promise<T>[]): Promise<PromiseSettledResult<T>[]> {
497
+ const settled: Promise<PromiseSettledResult<T>>[] = [];
498
+ for (let i = 0; i < values.length; i++) settled.push(__co_settle<T>(values[i]));
499
+ return __co_all<PromiseSettledResult<T>>(settled);
500
+ }
501
+
502
+ /**
503
+ * @hidden Promise.race: settles like the first of `values` to settle. The
504
+ * value is copied as it is stored, so T may be a base class of theirs, or
505
+ * nullable where one of them is a Promise<void>.
506
+ */
507
+ // @ts-ignore: decorator
508
+ @global function __co_race<T>(values: PromiseBase[]): Promise<T> {
509
+ const promise = __co_promise<T>();
510
+ for (let i = 0; i < values.length; i++) values[i].__react(new __AdoptJob(values[i], promise));
511
+ return promise;
512
+ }
513
+
514
+ /** @hidden Promise.race of a list. */
515
+ // @ts-ignore: decorator
516
+ @global function __co_raceList<T>(values: Promise<T>[]): Promise<T> {
517
+ return __co_race<T>(changetype<PromiseBase[]>(values));
518
+ }
519
+
520
+ /** The error Promise.any rejects with when every promise is rejected; their reasons are in `errors`. */
521
+ // @ts-ignore: decorator
522
+ @global export class AggregateError extends Error {
523
+ constructor(
524
+ /** The reason each promise was rejected, in the order the promises were given. */
525
+ public errors: Error[],
526
+ message: string = ""
527
+ ) {
528
+ super(message);
529
+ this.name = "AggregateError";
530
+ }
531
+ }
532
+
533
+ class __AnyState {
534
+ remaining: i32;
535
+ errors: Error[];
536
+
537
+ constructor(public target: PromiseBase, count: i32) {
538
+ this.remaining = count;
539
+ this.errors = new Array<Error>(count);
540
+ }
541
+ }
542
+
543
+ class __AnyJob extends __Job {
544
+ constructor(public state: __AnyState, public source: PromiseBase, public index: i32) {
545
+ super();
546
+ }
547
+
548
+ run(): void {
549
+ const state = this.state;
550
+ const source = this.source;
551
+ if (source.__state == __FULFILLED) {
552
+ state.target.__settleLike(source);
553
+ return;
554
+ }
555
+ state.errors[this.index] = source.__reason as Error;
556
+ if (--state.remaining == 0) state.target.__reject(new AggregateError(state.errors, "All promises were rejected"));
557
+ }
558
+ }
559
+
560
+ /** @hidden Promise.any: the first value; an AggregateError once every promise is rejected. */
561
+ // @ts-ignore: decorator
562
+ @global function __co_any<T>(values: PromiseBase[]): Promise<T> {
563
+ const promise = __co_promise<T>();
564
+ const state = new __AnyState(promise, values.length);
565
+ if (values.length == 0) promise.__reject(new AggregateError([], "All promises were rejected"));
566
+ for (let i = 0; i < values.length; i++) values[i].__react(new __AnyJob(state, values[i], i));
567
+ return promise;
568
+ }
569
+
570
+ /** @hidden Promise.any of a list. */
571
+ // @ts-ignore: decorator
572
+ @global function __co_anyList<T>(values: Promise<T>[]): Promise<T> {
573
+ return __co_any<T>(changetype<PromiseBase[]>(values));
574
+ }
575
+
576
+ class __TupleState {
577
+ constructor(public target: PromiseBase, public tuple: __Tuple, public remaining: i32) {}
578
+ }
579
+
580
+ class __TupleJob extends __Job {
581
+ constructor(public state: __TupleState, public source: PromiseBase, public index: i32) {
582
+ super();
583
+ }
584
+
585
+ run(): void {
586
+ const state = this.state;
587
+ const source = this.source;
588
+ if (source.__state == __REJECTED) {
589
+ state.target.__reject(source.__reason as Error);
590
+ return;
591
+ }
592
+ state.tuple.__setRaw(this.index, changetype<usize>(source.__ref), source.__bits);
593
+ if (--state.remaining == 0) state.target.__fulfillRaw(state.tuple, 0, true);
594
+ }
595
+ }
596
+
597
+ function __co_allOf(target: PromiseBase, tuple: __Tuple, sources: PromiseBase[]): void {
598
+ const state = new __TupleState(target, tuple, sources.length);
599
+ for (let i = 0; i < sources.length; i++) sources[i].__react(new __TupleJob(state, sources[i], i));
600
+ }
601
+
602
+ /** @hidden Promise.all of 2 promises of different types. */
603
+ // @ts-ignore: decorator
604
+ @global function __co_all2<A, B>(a: Promise<A>, b: Promise<B>): Promise<__Tuple2<A, B>> {
605
+ const promise = __co_promise<__Tuple2<A, B>>();
606
+ __co_allOf(promise, __co_blank<__Tuple2<A, B>>(), [a, b]);
607
+ return promise;
608
+ }
609
+
610
+ /** @hidden Promise.allSettled of 2 promises of different types. */
611
+ // @ts-ignore: decorator
612
+ @global function __co_allSettled2<A, B>(a: Promise<A>, b: Promise<B>): Promise<__Tuple2<PromiseSettledResult<A>, PromiseSettledResult<B>>> {
613
+ return __co_all2<PromiseSettledResult<A>, PromiseSettledResult<B>>(__co_settle<A>(a), __co_settle<B>(b));
614
+ }
615
+
616
+ /** @hidden Promise.all of 3 promises of different types. */
617
+ // @ts-ignore: decorator
618
+ @global function __co_all3<A, B, C>(a: Promise<A>, b: Promise<B>, c: Promise<C>): Promise<__Tuple3<A, B, C>> {
619
+ const promise = __co_promise<__Tuple3<A, B, C>>();
620
+ __co_allOf(promise, __co_blank<__Tuple3<A, B, C>>(), [a, b, c]);
621
+ return promise;
622
+ }
623
+
624
+ /** @hidden Promise.allSettled of 3 promises of different types. */
625
+ // @ts-ignore: decorator
626
+ @global function __co_allSettled3<A, B, C>(a: Promise<A>, b: Promise<B>, c: Promise<C>): Promise<__Tuple3<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>>> {
627
+ return __co_all3<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>>(__co_settle<A>(a), __co_settle<B>(b), __co_settle<C>(c));
628
+ }
629
+
630
+ /** @hidden Promise.all of 4 promises of different types. */
631
+ // @ts-ignore: decorator
632
+ @global function __co_all4<A, B, C, D>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>): Promise<__Tuple4<A, B, C, D>> {
633
+ const promise = __co_promise<__Tuple4<A, B, C, D>>();
634
+ __co_allOf(promise, __co_blank<__Tuple4<A, B, C, D>>(), [a, b, c, d]);
635
+ return promise;
636
+ }
637
+
638
+ /** @hidden Promise.allSettled of 4 promises of different types. */
639
+ // @ts-ignore: decorator
640
+ @global function __co_allSettled4<A, B, C, D>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>): Promise<__Tuple4<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>>> {
641
+ return __co_all4<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>>(__co_settle<A>(a), __co_settle<B>(b), __co_settle<C>(c), __co_settle<D>(d));
642
+ }
643
+
644
+ /** @hidden Promise.all of 5 promises of different types. */
645
+ // @ts-ignore: decorator
646
+ @global function __co_all5<A, B, C, D, E>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>): Promise<__Tuple5<A, B, C, D, E>> {
647
+ const promise = __co_promise<__Tuple5<A, B, C, D, E>>();
648
+ __co_allOf(promise, __co_blank<__Tuple5<A, B, C, D, E>>(), [a, b, c, d, e]);
649
+ return promise;
650
+ }
651
+
652
+ /** @hidden Promise.allSettled of 5 promises of different types. */
653
+ // @ts-ignore: decorator
654
+ @global function __co_allSettled5<A, B, C, D, E>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>): Promise<__Tuple5<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>>> {
655
+ return __co_all5<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>>(__co_settle<A>(a), __co_settle<B>(b), __co_settle<C>(c), __co_settle<D>(d), __co_settle<E>(e));
656
+ }
657
+
658
+ /** @hidden Promise.all of 6 promises of different types. */
659
+ // @ts-ignore: decorator
660
+ @global function __co_all6<A, B, C, D, E, F>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>, f: Promise<F>): Promise<__Tuple6<A, B, C, D, E, F>> {
661
+ const promise = __co_promise<__Tuple6<A, B, C, D, E, F>>();
662
+ __co_allOf(promise, __co_blank<__Tuple6<A, B, C, D, E, F>>(), [a, b, c, d, e, f]);
663
+ return promise;
664
+ }
665
+
666
+ /** @hidden Promise.allSettled of 6 promises of different types. */
667
+ // @ts-ignore: decorator
668
+ @global function __co_allSettled6<A, B, C, D, E, F>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>, f: Promise<F>): Promise<__Tuple6<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>, PromiseSettledResult<F>>> {
669
+ return __co_all6<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>, PromiseSettledResult<F>>(__co_settle<A>(a), __co_settle<B>(b), __co_settle<C>(c), __co_settle<D>(d), __co_settle<E>(e), __co_settle<F>(f));
670
+ }
671
+
672
+ /** @hidden Promise.all of 7 promises of different types. */
673
+ // @ts-ignore: decorator
674
+ @global function __co_all7<A, B, C, D, E, F, G>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>, f: Promise<F>, g: Promise<G>): Promise<__Tuple7<A, B, C, D, E, F, G>> {
675
+ const promise = __co_promise<__Tuple7<A, B, C, D, E, F, G>>();
676
+ __co_allOf(promise, __co_blank<__Tuple7<A, B, C, D, E, F, G>>(), [a, b, c, d, e, f, g]);
677
+ return promise;
678
+ }
679
+
680
+ /** @hidden Promise.allSettled of 7 promises of different types. */
681
+ // @ts-ignore: decorator
682
+ @global function __co_allSettled7<A, B, C, D, E, F, G>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>, f: Promise<F>, g: Promise<G>): Promise<__Tuple7<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>, PromiseSettledResult<F>, PromiseSettledResult<G>>> {
683
+ return __co_all7<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>, PromiseSettledResult<F>, PromiseSettledResult<G>>(__co_settle<A>(a), __co_settle<B>(b), __co_settle<C>(c), __co_settle<D>(d), __co_settle<E>(e), __co_settle<F>(f), __co_settle<G>(g));
684
+ }
685
+
686
+ /** @hidden Promise.all of 8 promises of different types. */
687
+ // @ts-ignore: decorator
688
+ @global function __co_all8<A, B, C, D, E, F, G, H>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>, f: Promise<F>, g: Promise<G>, h: Promise<H>): Promise<__Tuple8<A, B, C, D, E, F, G, H>> {
689
+ const promise = __co_promise<__Tuple8<A, B, C, D, E, F, G, H>>();
690
+ __co_allOf(promise, __co_blank<__Tuple8<A, B, C, D, E, F, G, H>>(), [a, b, c, d, e, f, g, h]);
691
+ return promise;
692
+ }
693
+
694
+ /** @hidden Promise.allSettled of 8 promises of different types. */
695
+ // @ts-ignore: decorator
696
+ @global function __co_allSettled8<A, B, C, D, E, F, G, H>(a: Promise<A>, b: Promise<B>, c: Promise<C>, d: Promise<D>, e: Promise<E>, f: Promise<F>, g: Promise<G>, h: Promise<H>): Promise<__Tuple8<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>, PromiseSettledResult<F>, PromiseSettledResult<G>, PromiseSettledResult<H>>> {
697
+ return __co_all8<PromiseSettledResult<A>, PromiseSettledResult<B>, PromiseSettledResult<C>, PromiseSettledResult<D>, PromiseSettledResult<E>, PromiseSettledResult<F>, PromiseSettledResult<G>, PromiseSettledResult<H>>(__co_settle<A>(a), __co_settle<B>(b), __co_settle<C>(c), __co_settle<D>(d), __co_settle<E>(e), __co_settle<F>(f), __co_settle<G>(g), __co_settle<H>(h));
698
+ }
699
+
700
+ // ---------------------------------------------------------------- resolve and reject
701
+
702
+ // The functions `new Promise(executor)` hands out. Each is a copy of one of
703
+ // these with the promise in its `_env`, which the compiler puts in __env - the
704
+ // global of its library that closures read theirs from - on every indirect
705
+ // call (Compiler.makeCallIndirect).
706
+
707
+ function __co_envPromise(): PromiseBase {
708
+ // @ts-ignore: the compiler library's, unknown to the editor
709
+ return changetype<PromiseBase>(__env);
710
+ }
711
+
712
+ function __co_resolveI32(value: i32 = 0): void {
713
+ __co_envPromise().__fulfillRaw(null, <u64><i64>value, true);
714
+ }
715
+
716
+ function __co_resolveRef(value: usize = 0): void {
717
+ __co_envPromise().__resolveRef(changetype<Object | null>(value));
718
+ }
719
+
720
+ function __co_resolveI64(value: i64 = 0): void {
721
+ __co_envPromise().__fulfillRaw(null, <u64>value, true);
722
+ }
723
+
724
+ function __co_resolveF32(value: f32 = 0): void {
725
+ __co_envPromise().__fulfillRaw(null, reinterpret<u64>(<f64>value), true);
726
+ }
727
+
728
+ function __co_resolveF64(value: f64 = 0): void {
729
+ __co_envPromise().__fulfillRaw(null, reinterpret<u64>(value), true);
730
+ }
731
+
732
+ function __co_rejectBound(reason: Error): void {
733
+ __co_envPromise().__reject(reason);
734
+ }
735
+
736
+ /**
737
+ * @hidden A function object like `fn`, with `env` in its `_env`; the
738
+ * collector follows `_env`. The function reads it back from __env.
739
+ */
740
+ // @ts-ignore: decorator
741
+ @global export function __co_bindEnv(fn: usize, env: Object): usize {
742
+ // The copy is of the original's own class - its header's rtId, 8 bytes
743
+ // before it - since a Function class nothing else instantiates is not in
744
+ // the runtime's type table, and the collector stops at an unknown id.
745
+ // @ts-ignore: the runtime's allocator, which the editor's typings leave out
746
+ const copy: usize = __new(offsetof<(value?: i32) => void>(), load<u32>(fn - 8));
747
+ store<u32>(copy, load<u32>(fn));
748
+ store<usize>(copy, changetype<usize>(env), sizeof<u32>());
749
+ // @ts-ignore: the collector's write barrier, likewise
750
+ __link(copy, changetype<usize>(env), false);
751
+ return copy;
752
+ }
753
+
754
+ function __co_resolver<T>(promise: Promise<T>): (value?: T) => void {
755
+ let fn: usize;
756
+ if (isReference<T>()) fn = changetype<usize>(__co_resolveRef);
757
+ else if (isFloat<T>() && sizeof<T>() == 8) fn = changetype<usize>(__co_resolveF64);
758
+ else if (isFloat<T>()) fn = changetype<usize>(__co_resolveF32);
759
+ else if (sizeof<T>() == 8) fn = changetype<usize>(__co_resolveI64);
760
+ else fn = changetype<usize>(__co_resolveI32);
761
+ return changetype<(value?: T) => void>(__co_bindEnv(fn, promise));
762
+ }
763
+
764
+ function __co_rejecter(promise: PromiseBase): (reason: Error) => void {
765
+ return changetype<(reason: Error) => void>(__co_bindEnv(changetype<usize>(__co_rejectBound), promise));
766
+ }
767
+
768
+ // ---------------------------------------------------------------- coroutines
769
+
770
+ class __Coroutine {
771
+ /** Managed arguments of the call, which only its locals hold otherwise. */
772
+ roots: Object[] = [];
773
+ /** Its shadow stack while parked, where the collector sees it. */
774
+ stack: StaticArray<Object | null> | null = null;
775
+ /** Asyncify's buffer: where the host unwinds its locals to. */
776
+ buffer: usize = 0;
777
+ /** The player whose handler started it: its awaits end when they leave. */
778
+ player: i32 = 0;
779
+ /** The abort signal it runs under, once asked for. */
780
+ signal: AbortSignal | null = null;
781
+ /** Parked, waiting for a job to resume it. */
782
+ parked: bool = false;
783
+ /** Counts its waits, so a resume meant for an earlier one is dropped. */
784
+ wait: i32 = 0;
785
+ /** Why it is to give up at the next resume: its signal aborted. */
786
+ abortReason: Error | null = null;
787
+ watch: __CoroutineAbort | null = null;
788
+ watched: AbortSignal | null = null;
789
+
790
+ constructor(public id: i32, public promise: PromiseBase) {}
791
+ }
792
+
793
+ // @ts-ignore: decorator
794
+ @lazy const __coroutines = new Map<i32, __Coroutine>();
795
+ // @ts-ignore: decorator
796
+ @lazy const __running: __Coroutine[] = [];
797
+ // @ts-ignore: decorator
798
+ @lazy let __nextCoroutine: i32 = 1;
799
+ // @ts-ignore: decorator
800
+ @lazy const __spawnArgs = new StaticArray<u32>(64);
801
+ // @ts-ignore: decorator
802
+ @lazy const __keep: Object[] = [];
803
+
804
+ /**
805
+ * @hidden The player whose command or event is being handled, set by the
806
+ * facade around the handler: a coroutine started there runs under that
807
+ * player's signal.
808
+ */
809
+ // @ts-ignore: decorator
810
+ @global let __co_ambient_player: i32 = 0;
811
+
812
+ function __co_current(): __Coroutine {
813
+ if (__running.length == 0) {
814
+ console.error("await outside an async function");
815
+ unreachable();
816
+ }
817
+ return __running[__running.length - 1];
818
+ }
819
+
820
+ /** @hidden whether the host is calling an async function as its coroutine right now. */
821
+ // @ts-ignore: decorator
822
+ @global function __co_entered(): bool {
823
+ return __co_host_entered() != 0;
824
+ }
825
+
826
+ /** @hidden where an async function writes its arguments for the host. */
827
+ // @ts-ignore: decorator
828
+ @global function __co_args(): usize {
829
+ return changetype<usize>(__spawnArgs);
830
+ }
831
+
832
+ /** @hidden a managed argument, held while the call lasts. */
833
+ // @ts-ignore: decorator
834
+ @global function __co_keep(value: usize): void {
835
+ if (value != 0) __keep.push(changetype<Object>(value));
836
+ }
837
+
838
+ /** @hidden runs an async function's body as a coroutine - see the top of this file. */
839
+ // @ts-ignore: decorator
840
+ @global function __co_spawn(fn: i32, cells: i32, promise: PromiseBase): void {
841
+ const co = new __Coroutine(__nextCoroutine++, promise);
842
+ for (let i = 0; i < __keep.length; i++) co.roots.push(__keep[i]);
843
+ __keep.length = 0;
844
+
845
+ // A player's command or event runs it under that player's signal; started
846
+ // from another coroutine otherwise, it runs under the same one.
847
+ if (__co_ambient_player > 0) {
848
+ co.player = __co_ambient_player;
849
+ } else if (__running.length > 0) {
850
+ const parent = __running[__running.length - 1];
851
+ co.player = parent.player;
852
+ co.signal = parent.signal;
853
+ }
854
+
855
+ const buffer = heap.alloc(<usize>__CO_BUFFER);
856
+ store<usize>(buffer, buffer + 2 * sizeof<usize>());
857
+ store<usize>(buffer + sizeof<usize>(), buffer + <usize>__CO_BUFFER);
858
+ co.buffer = buffer;
859
+ __coroutines.set(co.id, co);
860
+
861
+ __running.push(co);
862
+ const depth = __tryDepth;
863
+ __tryDepth = 0;
864
+ const outcome = __co_host_spawn(fn, changetype<usize>(__spawnArgs), cells, co.id, buffer);
865
+ __tryDepth = depth;
866
+ __running.pop();
867
+ __co_after(co, outcome);
868
+ }
869
+
870
+ /** What a call into a coroutine came back with. */
871
+ function __co_after(co: __Coroutine, outcome: i32): void {
872
+ if (outcome == __CO_PARKED) return;
873
+ if (outcome == __CO_TRAPPED) {
874
+ // The host has said why, with the plugin's name. Whoever awaits it
875
+ // hears it as a rejection, which is not reported a second time.
876
+ co.promise.__reject(__co_abortError("the async function crashed"));
877
+ }
878
+ __co_finish(co);
879
+ }
880
+
881
+ function __co_finish(co: __Coroutine): void {
882
+ if (!__coroutines.has(co.id)) return;
883
+ __coroutines.delete(co.id);
884
+ __co_unwatch(co);
885
+ co.roots.length = 0;
886
+ co.stack = null;
887
+ if (co.buffer != 0) heap.free(co.buffer);
888
+ co.buffer = 0;
889
+ }
890
+
891
+ function __co_settled(co: __Coroutine): usize {
892
+ __co_finish(co);
893
+ return changetype<usize>(co.promise);
894
+ }
895
+
896
+ /** @hidden `return;` in an async function. */
897
+ // @ts-ignore: decorator
898
+ @global function __co_return_void(): usize {
899
+ const co = __co_current();
900
+ co.promise.__fulfillVoid();
901
+ return __co_settled(co);
902
+ }
903
+
904
+ /** @hidden `return value` in an async function, by how the value is carried. */
905
+ // @ts-ignore: decorator
906
+ @global function __co_return_i32(value: i32): usize {
907
+ const co = __co_current();
908
+ co.promise.__fulfillRaw(null, <u64><i64>value, true);
909
+ return __co_settled(co);
910
+ }
911
+
912
+ // @ts-ignore: decorator
913
+ @global function __co_return_i64(value: i64): usize {
914
+ const co = __co_current();
915
+ co.promise.__fulfillRaw(null, <u64>value, true);
916
+ return __co_settled(co);
917
+ }
918
+
919
+ // @ts-ignore: decorator
920
+ @global function __co_return_f64(value: f64): usize {
921
+ const co = __co_current();
922
+ co.promise.__fulfillRaw(null, reinterpret<u64>(value), true);
923
+ return __co_settled(co);
924
+ }
925
+
926
+ // @ts-ignore: decorator
927
+ @global function __co_return_ref(value: usize): usize {
928
+ const co = __co_current();
929
+ co.promise.__resolveRef(changetype<Object | null>(value));
930
+ return __co_settled(co);
931
+ }
932
+
933
+ /** @hidden `throw error` in an async function: its Promise rejects with the error. */
934
+ // @ts-ignore: decorator
935
+ @global function __co_throw(reason: Error): usize {
936
+ const co = __co_current();
937
+ co.promise.__reject(reason);
938
+ return __co_settled(co);
939
+ }
940
+
941
+ /** @hidden an error that unwound out of an async function: its Promise rejects with it. */
942
+ // @ts-ignore: decorator
943
+ @global function __co_throwPending(): usize {
944
+ return __co_throw(__catch());
945
+ }
946
+
947
+ class __ResumeJob extends __Job {
948
+ constructor(id: i32, wait: i32) {
949
+ super();
950
+ this.coroutine = id;
951
+ this.wait = wait;
952
+ }
953
+ }
954
+
955
+ /** @hidden `await promise`: parks the coroutine until it settles, then gives back its value. */
956
+ // @ts-ignore: decorator
957
+ @global function __await<T>(promise: Promise<T>): T {
958
+ __co_wait(promise);
959
+ return promise.__value();
960
+ }
961
+
962
+ function __co_wait(promise: PromiseBase): void {
963
+ const co = __co_current();
964
+ const wait = ++co.wait;
965
+
966
+ // As in JavaScript, even a settled promise is awaited: the rest of the
967
+ // function runs as a job, after what is already queued.
968
+ promise.__react(new __ResumeJob(co.id, wait));
969
+
970
+ const signal = __co_signal(co);
971
+ if (signal) {
972
+ if (signal.aborted) {
973
+ co.abortReason = signal.reason;
974
+ } else {
975
+ const watch = new __CoroutineAbort(co.id);
976
+ co.watch = watch;
977
+ co.watched = signal;
978
+ signal.__watch(watch);
979
+ }
980
+ }
981
+
982
+ co.parked = true;
983
+ const depth = __tryDepth;
984
+ __co_host_suspend(0);
985
+
986
+ // Resumed. The signal it runs under aborted - its player left: it ends
987
+ // here, quietly. The promise was rejected: a `try` around the await takes
988
+ // the reason to its catch.
989
+ __tryDepth = depth;
990
+ __co_unwatch(co);
991
+ const aborted = co.abortReason;
992
+ if (aborted) __co_giveUp(co, aborted);
993
+ if (promise.__state != __REJECTED) return;
994
+ const reason = promise.__reason as Error;
995
+ if (depth == 0) __co_giveUp(co, reason);
996
+ __thrown = reason;
997
+ }
998
+
999
+ /** The awaited promise was rejected, or the signal aborted: the coroutine rejects with it and ends here. */
1000
+ function __co_giveUp(co: __Coroutine, reason: Error): void {
1001
+ co.promise.__reject(reason);
1002
+ __co_host_suspend(1);
1003
+ unreachable();
1004
+ }
1005
+
1006
+ function __co_unwatch(co: __Coroutine): void {
1007
+ const watch = co.watch;
1008
+ const signal = co.watched;
1009
+ co.watch = null;
1010
+ co.watched = null;
1011
+ if (watch && signal) signal.__unwatch(watch);
1012
+ }
1013
+
1014
+ /** The signal a coroutine runs under: its player's, while that player is on the server. */
1015
+ function __co_signal(co: __Coroutine): AbortSignal | null {
1016
+ let signal = co.signal;
1017
+ if (!signal && co.player > 0) co.signal = signal = __co_player_signal(co.player);
1018
+ return signal;
1019
+ }
1020
+
1021
+ /** @hidden the signal the running coroutine is under, for fetch and sleep. */
1022
+ // @ts-ignore: decorator
1023
+ @global function __co_context(): AbortSignal | null {
1024
+ if (__running.length == 0) return null;
1025
+ return __co_signal(__running[__running.length - 1]);
1026
+ }
1027
+
1028
+ /** @hidden the next job to run, run here, or the coroutine the host is to resume; 0 when none are left. */
1029
+ // @ts-ignore: decorator
1030
+ @global function __co_next_job(): i32 {
1031
+ while (__jobHead < __jobs.length) {
1032
+ const job = __jobs[__jobHead] as __Job;
1033
+ __jobs[__jobHead] = null;
1034
+ __jobHead++;
1035
+
1036
+ const id = job.coroutine;
1037
+ if (id == 0) {
1038
+ job.run();
1039
+ continue;
1040
+ }
1041
+ if (!__coroutines.has(id)) continue;
1042
+ const co = __coroutines.get(id);
1043
+ if (!co.parked || co.wait != job.wait) continue;
1044
+ co.parked = false;
1045
+ __running.push(co);
1046
+ return id;
1047
+ }
1048
+ __jobs.length = 0;
1049
+ __jobHead = 0;
1050
+ __woken = false;
1051
+ __co_reportUnhandled();
1052
+ return 0;
1053
+ }
1054
+
1055
+ /** @hidden a resume has come back from the host. */
1056
+ // @ts-ignore: decorator
1057
+ @global function __co_resumed(outcome: i32): void {
1058
+ __tryDepth = 0;
1059
+ const co = __running.pop();
1060
+ __co_after(co, outcome);
1061
+ }
1062
+
1063
+ function __co_reportUnhandled(): void {
1064
+ for (let i = 0; i < __unhandled.length; i++) {
1065
+ const promise = __unhandled[i];
1066
+ if (promise.__handled) continue;
1067
+ const reason = promise.__reason as Error;
1068
+ // An abort is expected - a player left, a request was cancelled.
1069
+ if (reason.name == "AbortError" || reason.name == "TimeoutError") continue;
1070
+ console.error(`Unhandled promise rejection: ${reason.message}`);
1071
+ }
1072
+ __unhandled.length = 0;
1073
+ }
1074
+
1075
+ // The shadow stack of a parked coroutine. AssemblyScript keeps the managed
1076
+ // locals of every frame in linear memory below __stack_pointer, where the
1077
+ // collector scans them; a parked coroutine's frames would be overwritten by
1078
+ // whatever runs next, so they are copied here, into memory the collector
1079
+ // traces, and copied back to the same addresses when it resumes.
1080
+
1081
+ /** @hidden */
1082
+ // @ts-ignore: decorator
1083
+ @global function __co_sp(): usize {
1084
+ return __stack_pointer;
1085
+ }
1086
+
1087
+ /** @hidden */
1088
+ // @ts-ignore: decorator
1089
+ @global function __co_set_sp(sp: usize): void {
1090
+ __stack_pointer = sp;
1091
+ }
1092
+
1093
+ /** @hidden */
1094
+ // @ts-ignore: decorator
1095
+ @global function __co_park(id: i32, lo: usize, hi: usize): void {
1096
+ if (!__coroutines.has(id)) return;
1097
+ const saved = new StaticArray<Object | null>(<i32>((hi - lo) / sizeof<usize>()));
1098
+ memory.copy(changetype<usize>(saved), lo, hi - lo);
1099
+ __coroutines.get(id).stack = saved;
1100
+ }
1101
+
1102
+ /** @hidden bytes of shadow stack a parked coroutine holds. */
1103
+ // @ts-ignore: decorator
1104
+ @global function __co_parked(id: i32): usize {
1105
+ if (!__coroutines.has(id)) return 0;
1106
+ const saved = __coroutines.get(id).stack;
1107
+ return saved ? <usize>saved.length * sizeof<usize>() : 0;
1108
+ }
1109
+
1110
+ /** @hidden */
1111
+ // @ts-ignore: decorator
1112
+ @global function __co_unpark(id: i32, lo: usize): void {
1113
+ if (!__coroutines.has(id)) return;
1114
+ const co = __coroutines.get(id);
1115
+ const saved = co.stack;
1116
+ if (!saved) return;
1117
+ memory.copy(lo, changetype<usize>(saved), <usize>saved.length * sizeof<usize>());
1118
+ co.stack = null;
1119
+ }
1120
+
1121
+ // ---------------------------------------------------------------- abort
1122
+
1123
+ /** The event an abort listener gets. */
1124
+ // @ts-ignore: decorator
1125
+ @global export class Event {
1126
+ constructor(
1127
+ /** The event's type; the only one here is `"abort"`. */
1128
+ public type: string
1129
+ ) {}
1130
+ }
1131
+
1132
+ /** @hidden something the hood does when a signal aborts. */
1133
+ // @ts-ignore: decorator
1134
+ @global export class __AbortWatch {
1135
+ run(reason: Error): void {}
1136
+ }
1137
+
1138
+ /** A signal to give something up: a request, a timer, everything a player started. */
1139
+ // @ts-ignore: decorator
1140
+ @global export class AbortSignal {
1141
+ private __aborted: bool = false;
1142
+ private __reason: Error | null = null;
1143
+ private __listeners: ((event: Event) => void)[] = [];
1144
+ private __watches: __AbortWatch[] = [];
1145
+
1146
+ /** `true` once the signal has aborted. */
1147
+ get aborted(): bool {
1148
+ return this.__aborted;
1149
+ }
1150
+
1151
+ /** The abort's reason: an Error named `"AbortError"` unless `abort()` was given one. */
1152
+ get reason(): Error | null {
1153
+ return this.__reason;
1154
+ }
1155
+
1156
+ /** Calls `listener` when the signal aborts. */
1157
+ addEventListener(type: "abort", listener: (event: Event) => void): void {
1158
+ this.__listeners.push(listener);
1159
+ }
1160
+
1161
+ /** Takes back a `listener` given to `addEventListener`: it is not called any more. */
1162
+ removeEventListener(type: "abort", listener: (event: Event) => void): void {
1163
+ const at = this.__listeners.indexOf(listener);
1164
+ if (at >= 0) this.__listeners.splice(at, 1);
1165
+ }
1166
+
1167
+ /** A signal that aborts by itself after `ms`, with an Error named `"TimeoutError"`. */
1168
+ static timeout(ms: number): AbortSignal {
1169
+ const signal = new AbortSignal();
1170
+ const id = __co_host_id();
1171
+ __timeouts.set(id, signal);
1172
+ __co_host_task(reinterpret<i32>(<f32>(ms / 1000.0)), __co_timeoutFired.index, id, 0);
1173
+ return signal;
1174
+ }
1175
+
1176
+ /** A signal that has aborted already. */
1177
+ static abort(reason: Error | null = null): AbortSignal {
1178
+ const signal = new AbortSignal();
1179
+ signal.__abort(reason ? reason : __co_abortError("This operation was aborted"));
1180
+ return signal;
1181
+ }
1182
+
1183
+ /** A signal that aborts when any of `signals` does. */
1184
+ static any(signals: AbortSignal[]): AbortSignal {
1185
+ const signal = new AbortSignal();
1186
+ for (let i = 0; i < signals.length; i++) {
1187
+ const one = signals[i];
1188
+ if (one.aborted) {
1189
+ signal.__abort(one.reason as Error);
1190
+ break;
1191
+ }
1192
+ one.__watch(new __AnyAbort(signal));
1193
+ }
1194
+ return signal;
1195
+ }
1196
+
1197
+ /** @hidden */
1198
+ __abort(reason: Error): void {
1199
+ if (this.__aborted) return;
1200
+ this.__aborted = true;
1201
+ this.__reason = reason;
1202
+ const watches = this.__watches;
1203
+ this.__watches = [];
1204
+ for (let i = 0; i < watches.length; i++) watches[i].run(reason);
1205
+ const listeners = this.__listeners.slice(0);
1206
+ const event = new Event("abort");
1207
+ for (let i = 0; i < listeners.length; i++) listeners[i](event);
1208
+ }
1209
+
1210
+ /** @hidden */
1211
+ __watch(watch: __AbortWatch): void {
1212
+ this.__watches.push(watch);
1213
+ }
1214
+
1215
+ /** @hidden */
1216
+ __unwatch(watch: __AbortWatch): void {
1217
+ const at = this.__watches.indexOf(watch);
1218
+ if (at >= 0) this.__watches.splice(at, 1);
1219
+ }
1220
+ }
1221
+
1222
+ /** A controller that aborts its `signal` on demand: `controller.abort()`. */
1223
+ // @ts-ignore: decorator
1224
+ @global export class AbortController {
1225
+ /** The controller's signal: hand it to fetch, sleep or anything else that takes one. */
1226
+ readonly signal: AbortSignal = new AbortSignal();
1227
+
1228
+ /** Aborts the signal, with `reason` or an Error named `"AbortError"`. */
1229
+ abort(reason: Error | null = null): void {
1230
+ this.signal.__abort(reason ? reason : __co_abortError("This operation was aborted"));
1231
+ }
1232
+ }
1233
+
1234
+ /** @hidden an Error named as an abort: expected, never reported as unhandled. */
1235
+ // @ts-ignore: decorator
1236
+ @global function __co_abortError(message: string): Error {
1237
+ const error = new Error(message);
1238
+ error.name = "AbortError";
1239
+ return error;
1240
+ }
1241
+
1242
+ class __AnyAbort extends __AbortWatch {
1243
+ constructor(public signal: AbortSignal) {
1244
+ super();
1245
+ }
1246
+
1247
+ run(reason: Error): void {
1248
+ this.signal.__abort(reason);
1249
+ }
1250
+ }
1251
+
1252
+ class __CoroutineAbort extends __AbortWatch {
1253
+ constructor(public id: i32) {
1254
+ super();
1255
+ }
1256
+
1257
+ run(reason: Error): void {
1258
+ if (!__coroutines.has(this.id)) return;
1259
+ const co = __coroutines.get(this.id);
1260
+ if (!co.parked) return;
1261
+ co.abortReason = reason;
1262
+ __co_queue(new __ResumeJob(co.id, co.wait));
1263
+ }
1264
+ }
1265
+
1266
+ // @ts-ignore: decorator
1267
+ @lazy const __timeouts = new Map<i32, AbortSignal>();
1268
+
1269
+ function __co_timeoutFired(id: i32): void {
1270
+ if (!__timeouts.has(id)) return;
1271
+ const signal = __timeouts.get(id);
1272
+ __timeouts.delete(id);
1273
+ const error = new Error("The operation was aborted due to timeout");
1274
+ error.name = "TimeoutError";
1275
+ signal.__abort(error);
1276
+ }
1277
+
1278
+ /**
1279
+ * @hidden watches up to two signals for an operation - the one it was given
1280
+ * and the one its coroutine runs under - and lets go of both when it ends.
1281
+ */
1282
+ // @ts-ignore: decorator
1283
+ @global export class __AbortGuard {
1284
+ private signals: AbortSignal[] = [];
1285
+
1286
+ constructor(public watch: __AbortWatch, given: AbortSignal | null) {
1287
+ this.add(given);
1288
+ const context = __co_context();
1289
+ if (context != given) this.add(context);
1290
+ }
1291
+
1292
+ private add(signal: AbortSignal | null): void {
1293
+ if (!signal) return;
1294
+ this.signals.push(signal);
1295
+ signal.__watch(this.watch);
1296
+ }
1297
+
1298
+ /** The reason if a signal has aborted already. */
1299
+ get aborted(): Error | null {
1300
+ for (let i = 0; i < this.signals.length; i++) {
1301
+ if (this.signals[i].aborted) return this.signals[i].reason;
1302
+ }
1303
+ return null;
1304
+ }
1305
+
1306
+ release(): void {
1307
+ for (let i = 0; i < this.signals.length; i++) this.signals[i].__unwatch(this.watch);
1308
+ this.signals.length = 0;
1309
+ }
1310
+ }
1311
+
1312
+ // ---------------------------------------------------------------- sleep
1313
+
1314
+ class __Sleep extends __AbortWatch {
1315
+ guard: __AbortGuard | null = null;
1316
+
1317
+ constructor(public promise: Promise<void>, public id: i32) {
1318
+ super();
1319
+ }
1320
+
1321
+ run(reason: Error): void {
1322
+ if (!__sleeps.has(this.id)) return;
1323
+ __sleeps.delete(this.id);
1324
+ __co_host_stop_task(this.id);
1325
+ (this.guard as __AbortGuard).release();
1326
+ this.promise.__reject(reason);
1327
+ }
1328
+ }
1329
+
1330
+ // @ts-ignore: decorator
1331
+ @lazy const __sleeps = new Map<i32, __Sleep>();
1332
+
1333
+ /** @hidden the facade's sleep(): fulfilled after `ms`, rejected if a signal aborts first. */
1334
+ // @ts-ignore: decorator
1335
+ @global export function __co_sleep(ms: f64, signal: AbortSignal | null): Promise<void> {
1336
+ const promise = __co_promise<void>();
1337
+ const id = __co_host_id();
1338
+ const sleep = new __Sleep(promise, id);
1339
+ const guard = new __AbortGuard(sleep, signal);
1340
+ sleep.guard = guard;
1341
+
1342
+ const already = guard.aborted;
1343
+ if (already) {
1344
+ guard.release();
1345
+ promise.__reject(already);
1346
+ return promise;
1347
+ }
1348
+
1349
+ __sleeps.set(id, sleep);
1350
+ __co_host_task(reinterpret<i32>(<f32>(ms / 1000.0)), __co_sleepFired.index, id, 0);
1351
+ return promise;
1352
+ }
1353
+
1354
+ function __co_sleepFired(id: i32): void {
1355
+ if (!__sleeps.has(id)) return;
1356
+ const sleep = __sleeps.get(id);
1357
+ __sleeps.delete(id);
1358
+ (sleep.guard as __AbortGuard).release();
1359
+ sleep.promise.__fulfillVoid();
1360
+ }
1361
+
1362
+ // ---------------------------------------------------------------- players
1363
+
1364
+ // One controller per player slot, made when first asked for and aborted when
1365
+ // the player leaves; the next player in the slot gets a fresh one.
1366
+ // @ts-ignore: decorator
1367
+ @lazy const __playerControllers: (AbortController | null)[] = [];
1368
+ // @ts-ignore: decorator
1369
+ @lazy let __playersWatched = false;
1370
+
1371
+ /** @hidden player.signal. */
1372
+ // @ts-ignore: decorator
1373
+ @global export function __co_player_signal(id: i32): AbortSignal {
1374
+ if (!__playersWatched) {
1375
+ __playersWatched = true;
1376
+ // The stock forward, through the host like every event: shape 1 is
1377
+ // the wide handler, (id, drop, message, unused).
1378
+ __co_host_on("client_disconnected", __co_playerLeft.index, 1);
1379
+ }
1380
+ while (__playerControllers.length <= id) __playerControllers.push(null);
1381
+ let controller = __playerControllers[id];
1382
+ if (!controller) __playerControllers[id] = controller = new AbortController();
1383
+ return controller.signal;
1384
+ }
1385
+
1386
+ function __co_playerLeft(id: i32, drop: i32, message: i32, unused: i32): void {
1387
+ if (id < 0 || id >= __playerControllers.length) return;
1388
+ const controller = __playerControllers[id];
1389
+ if (!controller) return;
1390
+ __playerControllers[id] = null;
1391
+ controller.signal.__abort(__co_abortError("The player left"));
1392
+ }