@amxts/core 0.1.0 → 0.2.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.
Files changed (77) hide show
  1. package/README.md +21 -25
  2. package/README.ru.md +22 -24
  3. package/as/amxts.d.ts +63 -3
  4. package/as/constants.ts +684 -116
  5. package/as/entities.ts +1905 -1364
  6. package/as/events.ts +1696 -907
  7. package/as/facade.ts +1240 -220
  8. package/as/fetch.ts +1519 -0
  9. package/as/flags.ts +159 -145
  10. package/as/hlds.ts +1071 -0
  11. package/as/hooks.ts +5226 -5379
  12. package/as/kit.ts +15 -5
  13. package/as/lib/check.ts +1 -1
  14. package/as/natives.ts +2658 -2499
  15. package/as/remote.ts +39 -15
  16. package/as/tsconfig.json +7 -2
  17. package/as/vector.ts +12 -9
  18. package/includes/order.txt +22 -29
  19. package/includes/sources.json +0 -8
  20. package/node_modules/assemblyscript/std/assembly/index.d.ts +20 -11
  21. package/package.json +29 -7
  22. package/runtime/deps/assemblyscript/dist/asc.js +86 -16
  23. package/runtime/deps/assemblyscript/dist/assemblyscript.js +29 -29
  24. package/runtime/licenses/MPL-2.0.txt +373 -0
  25. package/runtime/licenses/README.md +5 -1
  26. package/runtime/licenses/curl-COPYING +22 -0
  27. package/runtime/licenses/libssh2-COPYING +43 -0
  28. package/runtime/licenses/mbedTLS-LICENSE +553 -0
  29. package/runtime/natives.txt +108 -105
  30. package/runtime/patches/assemblyscript-0.28.20-amxts.patch +752 -296
  31. package/runtime/patches/wamr-2.4.5-amxts.patch +148 -0
  32. package/scripts/apply-docs.ts +2 -2
  33. package/scripts/auto-imports.ts +2 -2
  34. package/scripts/build-identity.ts +115 -0
  35. package/scripts/build-wasm.ts +101 -50
  36. package/scripts/check.ts +17 -3
  37. package/scripts/client-messages.ts +246 -0
  38. package/scripts/compile-cache.ts +4 -2
  39. package/scripts/compile-pool.ts +128 -0
  40. package/scripts/compile-worker.ts +23 -0
  41. package/scripts/compile.ts +156 -59
  42. package/scripts/docker-server.ts +13 -3
  43. package/scripts/docs/as/amxts.ts +86 -0
  44. package/scripts/docs/as/facade.ts +688 -188
  45. package/scripts/docs/as/fetch.ts +805 -0
  46. package/scripts/docs/entities.ts +43 -144
  47. package/scripts/docs/events.ts +17 -28
  48. package/scripts/docs/game.ts +68 -22
  49. package/scripts/docs/messages.ts +330 -16
  50. package/scripts/editor-api.ts +101 -0
  51. package/scripts/hlds-events.ts +370 -0
  52. package/scripts/includes.ts +12 -10
  53. package/scripts/player-fields.ts +16 -15
  54. package/scripts/prebuilt.ts +65 -23
  55. package/scripts/prepare.ts +42 -28
  56. package/scripts/project.ts +120 -20
  57. package/scripts/reapi-events.ts +98 -0
  58. package/scripts/shared-modules.ts +85 -23
  59. package/scripts/source-map.ts +242 -0
  60. package/scripts/system.ts +1 -1
  61. package/scripts/typed-commands.ts +263 -0
  62. package/scripts/typed-configs.ts +23 -12
  63. package/scripts/ui.ts +3 -1
  64. package/scripts/upgrade-menus.ts +274 -0
  65. package/scripts/upgrade-names.ts +384 -0
  66. package/scripts/upgrade.ts +857 -0
  67. package/src/cli-api.mjs +37 -4
  68. package/src/system.mjs +74 -3
  69. package/src/testing/compile.ts +8 -5
  70. package/src/testing/index.ts +2 -1
  71. package/src/testing/natives.ts +199 -5
  72. package/src/testing/network.ts +531 -0
  73. package/src/testing/server.ts +572 -48
  74. package/src/testing/setup.ts +1 -1
  75. package/src/testing/tables.ts +25 -0
  76. package/as/modules/http.ts +0 -184
  77. package/scripts/docs/as/modules/http.ts +0 -66
package/as/remote.ts CHANGED
@@ -14,7 +14,8 @@
14
14
  // one export the module calls, __amxts_rpc. It is hood: plugins never import it.
15
15
  // __co_bindEnv, which makes a stand-in, is as/promise.ts's; __env, where the
16
16
  // stand-in finds its place, the compiler library's.
17
- import "~/promise";
17
+ import "./promise";
18
+ import { __callFrom, __pluginStopped } from "./facade";
18
19
 
19
20
  // @ts-ignore: decorator
20
21
  @external("env", "amxts_serve") declare function _serve(name: string, hash: i32): void;
@@ -29,8 +30,12 @@ import "~/promise";
29
30
  // @ts-ignore: decorator
30
31
  @external("env", "amxts_rpc_result") declare function _result(to: usize): void;
31
32
 
33
+ // What a request is: its first four bytes. KIND_GONE is RPC_GONE in
34
+ // runtime/src/module.cpp, which sends it to an owner when a plugin that called
35
+ // it stops.
32
36
  const KIND_MODULE: i32 = 0;
33
37
  const KIND_CALLBACK: i32 = 1;
38
+ const KIND_GONE: i32 = 2;
34
39
 
35
40
  /** What a call carries: its arguments, or its answer, as bytes. */
36
41
  export class Writer {
@@ -75,7 +80,7 @@ export class Writer {
75
80
  export class Reader {
76
81
  at: i32 = 0;
77
82
 
78
- /** `from`: the plugin that wrote it - where a function it carries lives. */
83
+ /** `from`: the run of the plugin that wrote it - where a function it carries lives. */
79
84
  constructor(public data: ArrayBuffer, public from: i32) {}
80
85
 
81
86
  private take(bytes: i32): usize {
@@ -117,7 +122,13 @@ export class Service {
117
122
  private id: i32 = -1;
118
123
  private failed: bool = false;
119
124
 
120
- constructor(public name: string, public hash: i32) {}
125
+ // Asked as the plugin starts, which tells the server that this plugin
126
+ // uses the module: its owner then stays while the plugin runs, and starts
127
+ // over with it. The owner may start later; a call asks again.
128
+ constructor(public name: string, public hash: i32) {
129
+ const id = _owner(name, hash);
130
+ if (id >= 0) this.id = id;
131
+ }
121
132
 
122
133
  /** A call of the module's `op`-th function (or field). */
123
134
  begin(op: i32): Writer {
@@ -132,13 +143,13 @@ export class Service {
132
143
  if (this.id < 0) {
133
144
  const id = _owner(this.name, this.hash);
134
145
  if (id < 0) return this.fail(id == -2
135
- ? `~/modules/${this.name}: ${this.name}.aot was built from another version of it - build both again`
136
- : `~/modules/${this.name}: no plugin runs it - is ${this.name}.aot in plugins.ini?`);
146
+ ? `${this.name}: ${this.name}.aot was built from another version of it - build both again`
147
+ : `${this.name}: no plugin runs it - is ${this.name}.aot in plugins.ini?`);
137
148
  this.id = id;
138
149
  }
139
150
 
140
151
  const answer = send(this.id, -1, w);
141
- if (answer == null) return this.fail(`~/modules/${this.name}: the call failed in ${this.name}`);
152
+ if (answer == null) return this.fail(`${this.name}: the call failed in ${this.name}`);
142
153
  this.failed = false;
143
154
  return answer!;
144
155
  }
@@ -150,7 +161,7 @@ export class Service {
150
161
  }
151
162
  }
152
163
 
153
- /** The answer from `service`, or from `plugin` when service is -1; null when there is none. */
164
+ /** The answer from `service`, or from the run `plugin` when service is -1; null when there is none. */
154
165
  function send(service: i32, plugin: i32, w: Writer): Reader | null {
155
166
  const length = _rpc(service, plugin, changetype<usize>(w.data), w.length);
156
167
  if (length < 4) return null;
@@ -188,12 +199,16 @@ export function sendFunction(fn: usize, sig: i32, invoke: Invoke): i32 {
188
199
  return id;
189
200
  }
190
201
 
191
- /** Where a stand-in calls: the plugin a function lives in, and its number there. */
202
+ /** Where a stand-in calls: the run of the plugin a function lives in, and its number there. */
192
203
  class Remote {
193
204
  constructor(public plugin: i32, public id: i32) {}
194
205
  }
195
206
 
196
- const standIns = new Map<string, usize>();
207
+ /**
208
+ * The stand-ins made, by "<run>:<id>". Held here: a stand-in is only ever
209
+ * reached through what it was given to. A run's go when it stops.
210
+ */
211
+ const standIns = new Map<string, Object>();
197
212
 
198
213
  /**
199
214
  * A stand-in for function `id` of the plugin that wrote `r`: a copy of
@@ -205,16 +220,21 @@ export function receiveFunction(r: Reader, stub: usize): usize {
205
220
  const id = r.i32();
206
221
  if (id == 0) return 0;
207
222
  const key = `${r.from}:${id}`;
208
- if (standIns.has(key)) return standIns.get(key);
223
+ if (standIns.has(key)) return changetype<usize>(standIns.get(key));
209
224
  // @ts-ignore: as/promise.ts's, global to the compiler and unknown to the editor
210
225
  const bound: usize = __co_bindEnv(stub, new Remote(r.from, id));
211
- standIns.set(key, bound);
212
- // Held here: the stand-in is only ever reached through what it was given to.
213
- kept.push(changetype<Object>(bound));
226
+ standIns.set(key, changetype<Object>(bound));
214
227
  return bound;
215
228
  }
216
229
 
217
- const kept: Object[] = [];
230
+ /** The run `run` stopped: its stand-ins call nothing any more, and the module drops what it gave. */
231
+ function stopped(run: i32): void {
232
+ const prefix = `${run}:`;
233
+ for (const key of standIns.keys()) {
234
+ if (key.startsWith(prefix)) standIns.delete(key);
235
+ }
236
+ __pluginStopped(run);
237
+ }
218
238
 
219
239
  /** The first thing a stub does: where it calls. Before any other call, which would change __env. */
220
240
  export function remoteTarget(): Remote {
@@ -267,7 +287,7 @@ export class Handles {
267
287
  }
268
288
  }
269
289
 
270
- /** @hidden What the module calls: a request of `length` bytes from plugin `from`. */
290
+ /** @hidden What the module calls: a request of `length` bytes from the run `from` of a plugin. */
271
291
  export function __amxts_rpc(length: i32, from: i32): void {
272
292
  const data = new ArrayBuffer(length);
273
293
  _take(changetype<usize>(data));
@@ -278,10 +298,14 @@ export function __amxts_rpc(length: i32, from: i32): void {
278
298
 
279
299
  if (kind == KIND_MODULE) {
280
300
  const dispatch = served;
301
+ const outer = __callFrom(from);
281
302
  if (dispatch != null) dispatch(id, r, w);
303
+ __callFrom(outer);
282
304
  } else if (kind == KIND_CALLBACK && id > 0 && id <= callbacks.length) {
283
305
  const callback = callbacks[id - 1];
284
306
  callback.invoke(changetype<usize>(callback.fn), callback.sig, r, w);
307
+ } else if (kind == KIND_GONE) {
308
+ stopped(from);
285
309
  }
286
310
 
287
311
  _reply(changetype<usize>(w.data), w.length);
package/as/tsconfig.json CHANGED
@@ -3,12 +3,17 @@
3
3
  "compilerOptions": {
4
4
  "target": "es2015",
5
5
  "moduleDetection": "force",
6
+ "useUnknownInCatchVariables": false,
6
7
  "module": "esnext",
7
8
  "moduleResolution": "bundler",
8
9
  "paths": {
9
- "~/*": ["./*"],
10
10
  "@amxts/core": ["./facade.ts"],
11
- "@amxts/core/*": ["./*"],
11
+ "@amxts/core/natives": ["./natives.ts"],
12
+ "@amxts/core/constants": ["./constants.ts"],
13
+ "@amxts/core/fs": ["./fs.ts"],
14
+ "@amxts/core/os": ["./os.ts"],
15
+ "@amxts/core/kit": ["./kit.ts"],
16
+ "@amxts/core/check": ["./lib/check.ts"],
12
17
  "@amxts/menu-core": ["../../amxts-modules/menu-core/src/index.ts"],
13
18
  "@amxts/config-core": ["../../amxts-modules/config-core/src/index.ts"]
14
19
  }
package/as/vector.ts CHANGED
@@ -8,24 +8,27 @@
8
8
 
9
9
  /** Three numbers, x y z, with the math a plugin needs on them. */
10
10
  export class Vector extends Array<number> {
11
+ // x, y and z read and write their element without the index's check: a
12
+ // Vector is made with room for three, which a shorter length leaves in
13
+ // place, and the check was a call - most of what reading one cost.
11
14
  constructor(x: number = 0.0, y: number = 0.0, z: number = 0.0) {
12
15
  super(3);
13
- this[0] = x;
14
- this[1] = y;
15
- this[2] = z;
16
+ unchecked(this[0] = x);
17
+ unchecked(this[1] = y);
18
+ unchecked(this[2] = z);
16
19
  }
17
20
 
18
21
  /** The x coordinate, `vector[0]`. */
19
- get x() { return this[0]; }
20
- set x(value: number) { this[0] = value; }
22
+ get x() { return unchecked(this[0]); }
23
+ set x(value: number) { unchecked(this[0] = value); }
21
24
 
22
25
  /** The y coordinate, `vector[1]`. */
23
- get y() { return this[1]; }
24
- set y(value: number) { this[1] = value; }
26
+ get y() { return unchecked(this[1]); }
27
+ set y(value: number) { unchecked(this[1] = value); }
25
28
 
26
29
  /** The z coordinate, `vector[2]`. */
27
- get z() { return this[2]; }
28
- set z(value: number) { this[2] = value; }
30
+ get z() { return unchecked(this[2]); }
31
+ set z(value: number) { unchecked(this[2] = value); }
29
32
 
30
33
  /** A new vector: this one plus `other`, number by number. */
31
34
  add(other: number[]) {
@@ -12,43 +12,36 @@ reapi
12
12
  hamsandwich
13
13
  cstrike
14
14
  engine
15
+ fakemeta
15
16
  nvault
16
- easy_http
17
+ geoip
17
18
  resemiclip
18
19
  universal_config
19
20
  menu_core
20
21
 
21
- # engine, nvault and geoip are stock AMX Mod X modules shipped with the server
22
- # (addons/amxmodx/modules/); geoip is listed in modules.ini and the other two
23
- # are auto-detected from the `#pragma reqlib` amxxpc writes into the .amxx.
24
- # easy_http and resemiclip are third-party modules, both present as DLLs and
25
- # both enabled explicitly in modules.ini.
22
+ # engine, fakemeta, nvault and geoip are stock AMX Mod X modules shipped with
23
+ # the server (addons/amxmodx/modules/); geoip is listed in modules.ini and the
24
+ # others are auto-detected from the `#pragma reqlib` amxxpc writes into the
25
+ # .amxx. The module itself calls engine's get_global_int and fakemeta's
26
+ # pev_valid and get_pdata_int to find the engine's edicts (runtime/src/fields.h).
27
+ # resemiclip is a third-party module, present as a DLL and enabled explicitly
28
+ # in modules.ini.
26
29
  #
27
30
  # universal_config and menu_core are not modules: their natives come from
28
31
  # universal_config.amxx and menu_core.amxx, which plugins.ini loads ahead of
29
32
  # amxts_host.amxx. AMX Mod X resolves plugin-registered natives after every
30
- # plugin has run plugin_natives(), so the host links against them fine - but a
31
- # server without those two plugins must put a `-` back in front of them.
33
+ # plugin has run plugin_natives(), so the host links against them fine, and a
34
+ # server without those two plugins loads it too (below).
32
35
 
33
36
  # A line starting with `-` is a deny marker: the include is still resolved and
34
- # parsed (amxxpc needs the file on disk to compile reapi.inc, which #includes
35
- # it unconditionally), but its natives are never pulled into the host's native
36
- # table. A #include costs nothing; a reference in __pull_natives() does — it
37
- # makes AMX Mod X refuse to load the plugin on a server that doesn't have the
38
- # native, taking the whole runtime down with it. None of these three are safe
39
- # to assume: vtc and rechecker are optional reapi add-ons, and reunion natives
40
- # are only registered when reapi detects Reunion at runtime, so even a server
41
- # that loads the Reunion metamod plugin cannot be assumed to expose them.
42
- # A server that wants one of these removes its `-`.
43
- # geoip is in modules.ini and its DLL is there, and it still cannot be pulled:
44
- # the module disables its own natives when it cannot find the GeoIP2 databases,
45
- # which it announces at startup and which this server does. A module being
46
- # loaded is not the same as its natives existing, and the difference is only
47
- # visible by starting the server - the host plugin refused to load with
48
- # "unknown function (name geoip_continent_name)" and took the whole runtime
49
- # with it. A server with the databases in place removes this marker.
50
- -geoip
51
-
52
- -reapi_vtc
53
- -reapi_reunion
54
- -reapi_rechecker
37
+ # parsed (amxxpc needs the file on disk to compile an include that #includes
38
+ # it), but its natives are never pulled into the host's native table. None is
39
+ # needed today.
40
+ #
41
+ # A native the server does not have does not keep the host from loading: the
42
+ # host's native filter lets it load without the native, and a call to it
43
+ # answers 0 and says so once. So the includes whose natives a server may lack
44
+ # are pulled like any other: reapi's add-ons - Reunion's natives exist only
45
+ # when reapi finds Reunion, VTC's and ReChecker's only with those plugins - and
46
+ # geoip, whose module turns its natives off when the GeoIP2 databases are not
47
+ # there. The facade asks before it calls one (has_reunion).
@@ -8,14 +8,6 @@
8
8
  "sha256": "f33a7435540bea8706db3fa948e51a85b511f5b18c383b97402a204dc5419195",
9
9
  "include": "addons/amxmodx/scripting/include/"
10
10
  },
11
- "easy_http": {
12
- "name": "AmxxEasyHttp",
13
- "version": "1.4.0",
14
- "license": "MIT",
15
- "home": "https://github.com/Next21Team/AmxxEasyHttp",
16
- "url": "https://github.com/Next21Team/AmxxEasyHttp/releases/download/1.4.0/easy_http.inc",
17
- "sha256": "5196ae17ea58eeaebd293639f96e0c8bbfe06b40e28daab2c80395538b62f1d9"
18
- },
19
11
  "resemiclip": {
20
12
  "name": "ReSemiclip AMXX",
21
13
  "version": "2.3.9-amxx",
@@ -2240,12 +2240,12 @@ declare class Date {
2240
2240
  /** Returns the UTC timestamp in milliseconds of the specified date. */
2241
2241
  static UTC(
2242
2242
  year: i32,
2243
- month: i32,
2244
- day: i32,
2245
- hour: i32,
2246
- minute: i32,
2247
- second: i32,
2248
- millisecond: i32
2243
+ month?: i32,
2244
+ day?: i32,
2245
+ hour?: i32,
2246
+ minute?: i32,
2247
+ second?: i32,
2248
+ millisecond?: i32
2249
2249
  ): f64;
2250
2250
  /** Returns the current UTC timestamp in milliseconds. */
2251
2251
  static now(): f64;
@@ -2455,6 +2455,8 @@ interface String {
2455
2455
  }
2456
2456
 
2457
2457
  declare class Map<K,V> {
2458
+ /** A Map of the `[key, value]` entries, set in their order. */
2459
+ constructor(entries?: [K, V][] | null);
2458
2460
  /** The entries, `[key, value]`, in the order the keys were added. */
2459
2461
  entries(): [K, V][];
2460
2462
  /** Calls `fn` with each value and key, in the order the keys were added. */
@@ -2472,6 +2474,8 @@ declare class Map<K,V> {
2472
2474
  }
2473
2475
 
2474
2476
  declare class Set<K> {
2477
+ /** A Set of the values, added in their order. */
2478
+ constructor(values?: K[] | null);
2475
2479
  /** Calls `fn` with each value, in the order they were added. */
2476
2480
  forEach(fn: (value: K, value2: K, set: Set<K>) => void): void;
2477
2481
  [Symbol.iterator](): IterableIterator<K>;
@@ -2678,15 +2682,15 @@ declare namespace console {
2678
2682
  /** Logs `message` to console if `assertion` is false-ish. */
2679
2683
  export function assert<T>(assertion: T, message?: string): void;
2680
2684
  /** Outputs `message` to the console. */
2681
- export function log(message?: string): void;
2685
+ export function log(message?: string | Error): void;
2682
2686
  /** Outputs `message` to the console, prefixed with "Debug:". */
2683
- export function debug(message?: string): void;
2687
+ export function debug(message?: string | Error): void;
2684
2688
  /** Outputs `message` to the console, prefixed with "Info:". */
2685
- export function info(message?: string): void;
2689
+ export function info(message?: string | Error): void;
2686
2690
  /** Outputs `message` to the console, prefixed with "Warning:". */
2687
- export function warn(message?: string): void;
2691
+ export function warn(message?: string | Error): void;
2688
2692
  /** Outputs `message` to the console, prefixed with "Error:". */
2689
- export function error(message?: string): void;
2693
+ export function error(message?: string | Error): void;
2690
2694
  /** Starts a new timer using the specified `label`. */
2691
2695
  export function time(label?: string): void;
2692
2696
  /** Logs the current value of a timer previously started with `console.time`. */
@@ -2820,3 +2824,8 @@ declare namespace JSON {
2820
2824
  /** The value as JSON text; `space` indents it - that many spaces, or the text itself. A field left undefined is left out. */
2821
2825
  function stringify(value: unknown, replacer?: null, space?: number | string): string;
2822
2826
  }
2827
+
2828
+ /** @hidden amxts: what an error's `stack` is made of - the host's frames, then their words. */
2829
+ declare abstract class ErrorStack { abstract frames(): StaticArray<u32>; abstract text(frames: StaticArray<u32>): string }
2830
+ /** @hidden amxts: the hood's ErrorStack. */
2831
+ declare let __errorStack: ErrorStack | null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@amxts/core",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "description": "Counter-Strike 1.6 plugins in TypeScript: compiled ahead of time and run inside AMX Mod X, next to Pawn plugins.",
6
6
  "author": {
7
7
  "name": "kukson777",
@@ -25,7 +25,12 @@
25
25
  ],
26
26
  "exports": {
27
27
  ".": "./as/facade.ts",
28
+ "./natives": "./as/natives.ts",
29
+ "./constants": "./as/constants.ts",
30
+ "./fs": "./as/fs.ts",
31
+ "./os": "./as/os.ts",
28
32
  "./kit": "./as/kit.ts",
33
+ "./check": "./as/lib/check.ts",
29
34
  "./test-utils": "./src/testing/index.ts",
30
35
  "./cli-api": "./src/cli-api.mjs",
31
36
  "./package.json": "./package.json",
@@ -44,13 +49,19 @@
44
49
  "scripts/apply-docs.ts",
45
50
  "scripts/asc.ts",
46
51
  "scripts/auto-imports.ts",
52
+ "scripts/build-identity.ts",
47
53
  "scripts/build-wasm.ts",
48
54
  "scripts/check.ts",
55
+ "scripts/client-messages.ts",
49
56
  "scripts/compile-cache.ts",
57
+ "scripts/compile-pool.ts",
58
+ "scripts/compile-worker.ts",
50
59
  "scripts/compile.ts",
51
60
  "scripts/docker-server.ts",
52
61
  "scripts/docs",
62
+ "scripts/editor-api.ts",
53
63
  "scripts/file-contents.ts",
64
+ "scripts/hlds-events.ts",
54
65
  "scripts/includes.ts",
55
66
  "scripts/player-fields.ts",
56
67
  "scripts/plugin-cache.ts",
@@ -58,12 +69,18 @@
58
69
  "scripts/prebuilt.ts",
59
70
  "scripts/prepare.ts",
60
71
  "scripts/project.ts",
72
+ "scripts/reapi-events.ts",
61
73
  "scripts/run.ts",
62
74
  "scripts/shared-modules.ts",
75
+ "scripts/source-map.ts",
63
76
  "scripts/system.ts",
64
77
  "scripts/tracked-fs.ts",
78
+ "scripts/typed-commands.ts",
65
79
  "scripts/typed-configs.ts",
66
80
  "scripts/ui.ts",
81
+ "scripts/upgrade.ts",
82
+ "scripts/upgrade-menus.ts",
83
+ "scripts/upgrade-names.ts",
67
84
  "includes/*.inc",
68
85
  "includes/order.txt",
69
86
  "includes/sources.json",
@@ -81,30 +98,35 @@
81
98
  "access": "public"
82
99
  },
83
100
  "dependencies": {
84
- "@amxts/cli": "^0.1.0",
101
+ "@amxts/cli": "^0.2.0",
85
102
  "bun": "^1.4.2",
86
103
  "typescript": "^5.6.0",
87
104
  "assemblyscript": "0.28.20"
88
105
  },
89
106
  "optionalDependencies": {
90
- "@amxts/wamrc-linux-x64": "^0.1.0",
91
- "@amxts/wamrc-win32-x64": "^0.1.0"
107
+ "@amxts/wamrc-linux-x64": "^0.2.1",
108
+ "@amxts/wamrc-win32-x64": "^0.2.1"
92
109
  },
93
110
  "devDependencies": {
94
- "@amxts/config-core": "^0.1.0",
95
- "@amxts/menu-core": "^0.1.0",
111
+ "@amxts/config-core": "^0.1.1",
112
+ "@amxts/menu-core": "^0.2.0",
96
113
  "@e18e/eslint-plugin": "^0.8.1",
97
114
  "@eslint-community/eslint-plugin-eslint-comments": "^4.8.1",
98
115
  "@stylistic/eslint-plugin": "^5.10.0",
99
116
  "@types/node": "^22.0.0",
117
+ "basic-ftp": "^6.2.1",
100
118
  "binaryen": "131.0.0-nightly.20260721",
119
+ "changelogen": "0.6.2",
101
120
  "eslint-plugin-antfu": "^3.2.3",
102
121
  "eslint-plugin-command": "^4.0.0",
103
122
  "eslint-plugin-n": "^18.4.0",
104
123
  "eslint-plugin-perfectionist": "^5.12.1",
105
124
  "eslint-plugin-regexp": "^3.3.1",
125
+ "ftp-srv": "^4.6.3",
106
126
  "oxfmt": "^0.70.0",
107
- "oxlint": "^1.85.0"
127
+ "oxlint": "^1.85.0",
128
+ "ssh2": "^1.17.0",
129
+ "ssh2-sftp-client": "^12.1.1"
108
130
  },
109
131
  "bundleDependencies": [
110
132
  "assemblyscript"
@@ -3726,24 +3726,33 @@ export namespace console {
3726
3726
  binding.assert(!!condition, message);
3727
3727
  }
3728
3728
 
3729
- export function log(message: string = ""): void {
3730
- binding.log(message);
3729
+ // amxts: a string, or an Error - written as its stack, as JavaScript's console does
3730
+ export function log<T = string>(message: T = changetype<T>("")): void {
3731
+ binding.log(text<T>(message));
3731
3732
  }
3732
3733
 
3733
- export function debug(message: string = ""): void {
3734
- binding.debug(message);
3734
+ export function debug<T = string>(message: T = changetype<T>("")): void {
3735
+ binding.debug(text<T>(message));
3735
3736
  }
3736
3737
 
3737
- export function info(message: string = ""): void {
3738
- binding.info(message);
3738
+ export function info<T = string>(message: T = changetype<T>("")): void {
3739
+ binding.info(text<T>(message));
3739
3740
  }
3740
3741
 
3741
- export function warn(message: string = ""): void {
3742
- binding.warn(message);
3742
+ export function warn<T = string>(message: T = changetype<T>("")): void {
3743
+ binding.warn(text<T>(message));
3743
3744
  }
3744
3745
 
3745
- export function error(message: string = ""): void {
3746
- binding.error(message);
3746
+ export function error<T = string>(message: T = changetype<T>("")): void {
3747
+ binding.error(text<T>(message));
3748
+ }
3749
+
3750
+ // @ts-ignore: decorator
3751
+ @inline function text<T>(message: T): string {
3752
+ if (isString<T>()) return changetype<string>(message);
3753
+ if (isReference<T>() && !isNullable<T>() && message instanceof Error) return changetype<Error>(message).stack;
3754
+ ERROR("console takes a string or an Error");
3755
+ return "";
3747
3756
  }
3748
3757
 
3749
3758
  export function time(label: string = "default"): void {
@@ -4438,12 +4447,24 @@ export declare function INFO(message?: string): void;
4438
4447
  `,error:`export class Error {
4439
4448
 
4440
4449
  name: string = "Error";
4441
- stack: string = ""; // TODO
4450
+
4451
+ // amxts: the calls that made it, as the host keeps them, for \`stack\`
4452
+ /** @hidden */
4453
+ __frames: StaticArray<u32> | null = __errorStack ? changetype<ErrorStack>(__errorStack).frames() : null;
4442
4454
 
4443
4455
  constructor(
4444
4456
  public message: string = ""
4445
4457
  ) {}
4446
4458
 
4459
+ /** amxts: the error and where it was made, a call a line, as JavaScript writes it. */
4460
+ get stack(): string {
4461
+ let hook = __errorStack;
4462
+ let frames = this.__frames;
4463
+ if (!hook || !frames) return this.toString();
4464
+ let calls = hook.text(frames);
4465
+ return calls.length ? this.toString() + "\\n" + calls : this.toString();
4466
+ }
4467
+
4447
4468
  toString(): string {
4448
4469
  let message = this.message;
4449
4470
  return message.length
@@ -4452,6 +4473,23 @@ export declare function INFO(message?: string): void;
4452
4473
  }
4453
4474
  }
4454
4475
 
4476
+ /**
4477
+ * @hidden amxts: what an error's \`stack\` is made of - the frames of the calls
4478
+ * that made it, then their words - which only the host the plugin runs on
4479
+ * has. The hood sets it (as/facade.ts); without it \`stack\` is the error's
4480
+ * first line alone.
4481
+ */
4482
+ export abstract class ErrorStack {
4483
+ /** The frames of the calls running now. */
4484
+ abstract frames(): StaticArray<u32>;
4485
+ /** \`frames\` as lines: " at name (file:line:column)". */
4486
+ abstract text(frames: StaticArray<u32>): string;
4487
+ }
4488
+
4489
+ /** @hidden see ErrorStack. */
4490
+ // @ts-ignore: decorator
4491
+ @lazy export let __errorStack: ErrorStack | null = null;
4492
+
4455
4493
  export class RangeError extends Error {
4456
4494
  constructor(message: string = "") {
4457
4495
  super(message);
@@ -4508,7 +4546,7 @@ export function __throw(error: Error, fileName: string, lineNumber: u32, columnN
4508
4546
  __thrown = error;
4509
4547
  return true;
4510
4548
  }
4511
- abort(error.message, fileName, lineNumber, columnNumber);
4549
+ abort(error.toString(), fileName, lineNumber, columnNumber);
4512
4550
  return false;
4513
4551
  }
4514
4552
 
@@ -4673,6 +4711,16 @@ export function __textFunction<F>(text: string): F {
4673
4711
  const fn: F = () => text;
4674
4712
  return fn;
4675
4713
  }
4714
+
4715
+ /**
4716
+ * amxts: a boolean given where \`boolean | (...) => boolean\` is declared - held
4717
+ * as the function, so a boolean becomes one that returns it
4718
+ * (Compiler.compileText).
4719
+ */
4720
+ export function __boolFunction<F>(value: bool): F {
4721
+ const fn: F = () => value;
4722
+ return fn;
4723
+ }
4676
4724
  `,iterator:`export abstract class Iterable<T> {
4677
4725
  // ?
4678
4726
  }
@@ -5315,8 +5363,14 @@ export class Map<K,V> {
5315
5363
  private entriesOffset: i32 = 0;
5316
5364
  private entriesCount: i32 = 0;
5317
5365
 
5318
- constructor() {
5319
- /* nop */
5366
+ /** amxts: \`new Map(entries)\` sets the \`[key, value]\` entries in their order, as JavaScript's Map does. */
5367
+ constructor(entries: __Tuple2<K,V>[] | null = null) {
5368
+ if (entries) {
5369
+ for (let i = 0, k = entries.length; i < k; ++i) {
5370
+ let entry = unchecked(entries[i]);
5371
+ this.set(entry._0, entry._1);
5372
+ }
5373
+ }
5320
5374
  }
5321
5375
 
5322
5376
  get size(): i32 {
@@ -7224,6 +7278,19 @@ export namespace NativeMath {
7224
7278
  }
7225
7279
 
7226
7280
  export function mod(x: f64, y: f64): f64 { // see: musl/src/math/fmod.c
7281
+ // amxts: a plugin's whole numbers are f64, and \`n % d\` of two of them
7282
+ // within i32 is i32's remainder, which takes the dividend's sign as
7283
+ // JavaScript's does; a zero keeps the dividend's sign (-4 % 2 is -0).
7284
+ // NaN, infinities, fractions, a zero divisor and larger numbers go on
7285
+ // to the general remainder below.
7286
+ if (builtin_abs<f64>(x) < 2147483648.0 && builtin_abs<f64>(y) < 2147483648.0) {
7287
+ let ix = <i32>x;
7288
+ let iy = <i32>y;
7289
+ if (<f64>ix == x && <f64>iy == y && iy != 0) {
7290
+ let r = ix % iy;
7291
+ return r ? <f64>r : builtin_copysign<f64>(0.0, x);
7292
+ }
7293
+ }
7227
7294
  if (builtin_abs<f64>(y) == 1.0) {
7228
7295
  // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))
7229
7296
  // TODO: move this rule to compiler's optimization pass.
@@ -12437,8 +12504,11 @@ export class Set<T> {
12437
12504
  private entriesOffset: i32 = 0;
12438
12505
  private entriesCount: i32 = 0;
12439
12506
 
12440
- constructor() {
12441
- /* nop */
12507
+ /** amxts: \`new Set(values)\` adds the values in their order, as JavaScript's Set does. */
12508
+ constructor(values: T[] | null = null) {
12509
+ if (values) {
12510
+ for (let i = 0, k = values.length; i < k; ++i) this.add(unchecked(values[i]));
12511
+ }
12442
12512
  }
12443
12513
 
12444
12514
  get size(): i32 {