@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.
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/README.ru.md +162 -0
- package/amxmodx/base/include/amxconst.inc +594 -0
- package/amxmodx/base/include/amxmisc.inc +902 -0
- package/amxmodx/base/include/amxmodx.inc +3447 -0
- package/amxmodx/base/include/amxmodx_version.inc +20 -0
- package/amxmodx/base/include/cellarray.inc +525 -0
- package/amxmodx/base/include/cellstack.inc +166 -0
- package/amxmodx/base/include/celltrie.inc +412 -0
- package/amxmodx/base/include/core.inc +202 -0
- package/amxmodx/base/include/csstats.inc +298 -0
- package/amxmodx/base/include/csstats_const.inc +29 -0
- package/amxmodx/base/include/cstrike.inc +1287 -0
- package/amxmodx/base/include/cstrike_const.inc +521 -0
- package/amxmodx/base/include/csx.inc +259 -0
- package/amxmodx/base/include/cvars.inc +547 -0
- package/amxmodx/base/include/datapack.inc +161 -0
- package/amxmodx/base/include/dbi.inc +154 -0
- package/amxmodx/base/include/dodconst.inc +152 -0
- package/amxmodx/base/include/dodfun.inc +152 -0
- package/amxmodx/base/include/dodstats.inc +69 -0
- package/amxmodx/base/include/dodx.inc +161 -0
- package/amxmodx/base/include/engine.inc +1343 -0
- package/amxmodx/base/include/engine_const.inc +310 -0
- package/amxmodx/base/include/engine_stocks.inc +248 -0
- package/amxmodx/base/include/esf.inc +70 -0
- package/amxmodx/base/include/esf_const.inc +74 -0
- package/amxmodx/base/include/fakemeta.inc +1127 -0
- package/amxmodx/base/include/fakemeta_const.inc +793 -0
- package/amxmodx/base/include/fakemeta_stocks.inc +395 -0
- package/amxmodx/base/include/fakemeta_util.inc +882 -0
- package/amxmodx/base/include/file.inc +666 -0
- package/amxmodx/base/include/float.inc +422 -0
- package/amxmodx/base/include/fun.inc +333 -0
- package/amxmodx/base/include/gameconfig.inc +93 -0
- package/amxmodx/base/include/geoip.inc +264 -0
- package/amxmodx/base/include/ham_const.inc +4352 -0
- package/amxmodx/base/include/hamsandwich.inc +439 -0
- package/amxmodx/base/include/hlsdk_const.inc +808 -0
- package/amxmodx/base/include/json.inc +777 -0
- package/amxmodx/base/include/lang.inc +119 -0
- package/amxmodx/base/include/message_const.inc +1130 -0
- package/amxmodx/base/include/message_stocks.inc +161 -0
- package/amxmodx/base/include/messages.inc +604 -0
- package/amxmodx/base/include/newmenus.inc +387 -0
- package/amxmodx/base/include/ns.inc +754 -0
- package/amxmodx/base/include/ns_const.inc +196 -0
- package/amxmodx/base/include/nvault.inc +154 -0
- package/amxmodx/base/include/regex.inc +348 -0
- package/amxmodx/base/include/sockets.inc +183 -0
- package/amxmodx/base/include/sorting.inc +107 -0
- package/amxmodx/base/include/sqlx.inc +582 -0
- package/amxmodx/base/include/string.inc +786 -0
- package/amxmodx/base/include/string_const.inc +156 -0
- package/amxmodx/base/include/string_stocks.inc +325 -0
- package/amxmodx/base/include/textparse_ini.inc +214 -0
- package/amxmodx/base/include/textparse_smc.inc +261 -0
- package/amxmodx/base/include/tfcconst.inc +84 -0
- package/amxmodx/base/include/tfcstats.inc +62 -0
- package/amxmodx/base/include/tfcx.inc +148 -0
- package/amxmodx/base/include/time.inc +118 -0
- package/amxmodx/base/include/tsconst.inc +154 -0
- package/amxmodx/base/include/tsfun.inc +198 -0
- package/amxmodx/base/include/tsstats.inc +65 -0
- package/amxmodx/base/include/tsx.inc +88 -0
- package/amxmodx/base/include/vault.inc +60 -0
- package/amxmodx/base/include/vector.inc +131 -0
- package/amxmodx/base/include/xs.inc +1570 -0
- package/as/amxts.d.ts +153 -0
- package/as/constants.ts +4730 -0
- package/as/effects.ts +1449 -0
- package/as/entities.ts +5482 -0
- package/as/events.ts +3054 -0
- package/as/facade.ts +4639 -0
- package/as/flags.ts +299 -0
- package/as/fs.ts +287 -0
- package/as/hooks.ts +18536 -0
- package/as/kit.ts +25 -0
- package/as/lib/check.ts +86 -0
- package/as/modules/http.ts +184 -0
- package/as/natives.ts +11845 -0
- package/as/os.ts +30 -0
- package/as/promise.ts +1392 -0
- package/as/promise.types.d.ts +82 -0
- package/as/remote.ts +288 -0
- package/as/tsconfig.json +22 -0
- package/as/vector.ts +65 -0
- package/bin/amxts.mjs +10 -0
- package/includes/menu_core.inc +355 -0
- package/includes/order.txt +54 -0
- package/includes/sources.json +27 -0
- package/includes/universal_config.inc +355 -0
- package/lint/oxlint-plugin.mjs +77 -0
- package/node_modules/assemblyscript/LICENSE +201 -0
- package/node_modules/assemblyscript/NOTICE +93 -0
- package/node_modules/assemblyscript/package.json +63 -0
- package/node_modules/assemblyscript/std/README.md +6 -0
- package/node_modules/assemblyscript/std/assembly/array.ts +526 -0
- package/node_modules/assemblyscript/std/assembly/arraybuffer.ts +77 -0
- package/node_modules/assemblyscript/std/assembly/atomics.ts +127 -0
- package/node_modules/assemblyscript/std/assembly/bindings/asyncify.ts +16 -0
- package/node_modules/assemblyscript/std/assembly/bindings/dom.ts +291 -0
- package/node_modules/assemblyscript/std/assembly/bindings/node.ts +6 -0
- package/node_modules/assemblyscript/std/assembly/builtins.ts +2631 -0
- package/node_modules/assemblyscript/std/assembly/compat.ts +2 -0
- package/node_modules/assemblyscript/std/assembly/console.ts +42 -0
- package/node_modules/assemblyscript/std/assembly/crypto.ts +9 -0
- package/node_modules/assemblyscript/std/assembly/dataview.ts +181 -0
- package/node_modules/assemblyscript/std/assembly/date.ts +373 -0
- package/node_modules/assemblyscript/std/assembly/diagnostics.ts +11 -0
- package/node_modules/assemblyscript/std/assembly/error.ts +44 -0
- package/node_modules/assemblyscript/std/assembly/function.ts +38 -0
- package/node_modules/assemblyscript/std/assembly/index.d.ts +2822 -0
- package/node_modules/assemblyscript/std/assembly/iterator.ts +35 -0
- package/node_modules/assemblyscript/std/assembly/map.ts +260 -0
- package/node_modules/assemblyscript/std/assembly/math.ts +3289 -0
- package/node_modules/assemblyscript/std/assembly/memory.ts +123 -0
- package/node_modules/assemblyscript/std/assembly/number.ts +388 -0
- package/node_modules/assemblyscript/std/assembly/object.ts +36 -0
- package/node_modules/assemblyscript/std/assembly/performance.ts +9 -0
- package/node_modules/assemblyscript/std/assembly/polyfills.ts +27 -0
- package/node_modules/assemblyscript/std/assembly/process.ts +50 -0
- package/node_modules/assemblyscript/std/assembly/reference.ts +48 -0
- package/node_modules/assemblyscript/std/assembly/regexp.ts +12 -0
- package/node_modules/assemblyscript/std/assembly/rt/README.md +83 -0
- package/node_modules/assemblyscript/std/assembly/rt/common.ts +81 -0
- package/node_modules/assemblyscript/std/assembly/rt/index-incremental.ts +2 -0
- package/node_modules/assemblyscript/std/assembly/rt/index-minimal.ts +2 -0
- package/node_modules/assemblyscript/std/assembly/rt/index-stub.ts +1 -0
- package/node_modules/assemblyscript/std/assembly/rt/index.d.ts +37 -0
- package/node_modules/assemblyscript/std/assembly/rt/itcms.ts +419 -0
- package/node_modules/assemblyscript/std/assembly/rt/rtrace.ts +15 -0
- package/node_modules/assemblyscript/std/assembly/rt/stub.ts +133 -0
- package/node_modules/assemblyscript/std/assembly/rt/tcms.ts +254 -0
- package/node_modules/assemblyscript/std/assembly/rt/tlsf.ts +592 -0
- package/node_modules/assemblyscript/std/assembly/rt.ts +87 -0
- package/node_modules/assemblyscript/std/assembly/set.ts +220 -0
- package/node_modules/assemblyscript/std/assembly/shared/feature.ts +65 -0
- package/node_modules/assemblyscript/std/assembly/shared/runtime.ts +11 -0
- package/node_modules/assemblyscript/std/assembly/shared/target.ts +11 -0
- package/node_modules/assemblyscript/std/assembly/shared/tsconfig.json +11 -0
- package/node_modules/assemblyscript/std/assembly/shared/typeinfo.ts +72 -0
- package/node_modules/assemblyscript/std/assembly/staticarray.ts +401 -0
- package/node_modules/assemblyscript/std/assembly/string.ts +847 -0
- package/node_modules/assemblyscript/std/assembly/symbol.ts +114 -0
- package/node_modules/assemblyscript/std/assembly/table.ts +16 -0
- package/node_modules/assemblyscript/std/assembly/tsconfig.json +6 -0
- package/node_modules/assemblyscript/std/assembly/typedarray.ts +1945 -0
- package/node_modules/assemblyscript/std/assembly/uri.ts +17 -0
- package/node_modules/assemblyscript/std/assembly/util/bytes.ts +107 -0
- package/node_modules/assemblyscript/std/assembly/util/casemap.ts +497 -0
- package/node_modules/assemblyscript/std/assembly/util/error.ts +54 -0
- package/node_modules/assemblyscript/std/assembly/util/hash.ts +117 -0
- package/node_modules/assemblyscript/std/assembly/util/math.ts +1922 -0
- package/node_modules/assemblyscript/std/assembly/util/memory.ts +290 -0
- package/node_modules/assemblyscript/std/assembly/util/number.ts +873 -0
- package/node_modules/assemblyscript/std/assembly/util/sort.ts +313 -0
- package/node_modules/assemblyscript/std/assembly/util/string.ts +1202 -0
- package/node_modules/assemblyscript/std/assembly/util/uri.ts +275 -0
- package/node_modules/assemblyscript/std/assembly/vector.ts +4 -0
- package/node_modules/assemblyscript/std/assembly.json +16 -0
- package/node_modules/assemblyscript/std/portable/index.d.ts +462 -0
- package/node_modules/assemblyscript/std/portable/index.js +416 -0
- package/node_modules/assemblyscript/std/portable.json +11 -0
- package/node_modules/assemblyscript/std/types/assembly/index.d.ts +1 -0
- package/node_modules/assemblyscript/std/types/assembly/package.json +3 -0
- package/node_modules/assemblyscript/std/types/portable/index.d.ts +1 -0
- package/node_modules/assemblyscript/std/types/portable/package.json +3 -0
- package/node_modules/assemblyscript/tsconfig-base.json +13 -0
- package/package.json +112 -0
- package/runtime/deps/assemblyscript/LICENSE +201 -0
- package/runtime/deps/assemblyscript/NOTICE +93 -0
- package/runtime/deps/assemblyscript/bin/asc.js +35 -0
- package/runtime/deps/assemblyscript/dist/asc.js +25035 -0
- package/runtime/deps/assemblyscript/dist/assemblyscript.js +337 -0
- package/runtime/deps/assemblyscript/node_modules/binaryen/LICENSE +201 -0
- package/runtime/deps/assemblyscript/node_modules/binaryen/index.js +28905 -0
- package/runtime/deps/assemblyscript/node_modules/binaryen/package.json +50 -0
- package/runtime/deps/assemblyscript/node_modules/long/LICENSE +202 -0
- package/runtime/deps/assemblyscript/node_modules/long/index.js +1581 -0
- package/runtime/deps/assemblyscript/node_modules/long/package.json +58 -0
- package/runtime/deps/assemblyscript/package.json +114 -0
- package/runtime/host/amxts.inc +85 -0
- package/runtime/licenses/AMXX-LICENSE.txt +34 -0
- package/runtime/licenses/AssemblyScript-LICENSE +201 -0
- package/runtime/licenses/AssemblyScript-NOTICE +93 -0
- package/runtime/licenses/Binaryen-LICENSE +201 -0
- package/runtime/licenses/Bun-LICENSE.md +84 -0
- package/runtime/licenses/GPL-3.0.txt +674 -0
- package/runtime/licenses/LLVM-LICENSE.TXT +279 -0
- package/runtime/licenses/README.md +25 -0
- package/runtime/licenses/WAMR-LICENSE +219 -0
- package/runtime/natives.txt +1095 -0
- package/runtime/patches/README.md +59 -0
- package/runtime/patches/assemblyscript-0.28.20-amxts.patch +14174 -0
- package/runtime/patches/wamr-2.4.5-amxts.patch +364 -0
- package/scripts/apply-docs.ts +508 -0
- package/scripts/asc.ts +27 -0
- package/scripts/auto-imports.ts +258 -0
- package/scripts/build-wasm.ts +595 -0
- package/scripts/check.ts +93 -0
- package/scripts/compile-cache.ts +179 -0
- package/scripts/compile.ts +401 -0
- package/scripts/docker-server.ts +73 -0
- package/scripts/docs/as/amxts.ts +210 -0
- package/scripts/docs/as/effects.ts +1684 -0
- package/scripts/docs/as/facade.ts +3302 -0
- package/scripts/docs/as/fs.ts +173 -0
- package/scripts/docs/as/lib/check.ts +68 -0
- package/scripts/docs/as/modules/http.ts +66 -0
- package/scripts/docs/as/os.ts +16 -0
- package/scripts/docs/as/promise.ts +132 -0
- package/scripts/docs/as/promise.types.ts +63 -0
- package/scripts/docs/as/vector.ts +48 -0
- package/scripts/docs/entities.ts +2338 -0
- package/scripts/docs/events.ts +245 -0
- package/scripts/docs/game.ts +497 -0
- package/scripts/docs/messages.ts +148 -0
- package/scripts/file-contents.ts +74 -0
- package/scripts/includes.ts +134 -0
- package/scripts/player-fields.ts +866 -0
- package/scripts/plugin-cache.ts +92 -0
- package/scripts/plugin-natives.ts +1157 -0
- package/scripts/prebuilt.ts +268 -0
- package/scripts/prepare.ts +134 -0
- package/scripts/project.ts +973 -0
- package/scripts/run.ts +28 -0
- package/scripts/shared-modules.ts +906 -0
- package/scripts/system.ts +33 -0
- package/scripts/tracked-fs.ts +115 -0
- package/scripts/typed-configs.ts +788 -0
- package/scripts/ui.ts +77 -0
- package/src/cli-api.mjs +175 -0
- package/src/parser/include-parser.ts +506 -0
- package/src/system.mjs +155 -0
- package/src/testing/compile-cache.ts +31 -0
- package/src/testing/compile.ts +222 -0
- package/src/testing/coroutines.ts +191 -0
- package/src/testing/index.ts +39 -0
- package/src/testing/kits.ts +55 -0
- package/src/testing/memory.ts +125 -0
- package/src/testing/natives.ts +925 -0
- package/src/testing/server.ts +1874 -0
- package/src/testing/setup.ts +63 -0
- package/src/testing/tables.ts +139 -0
- package/src/types.ts +51 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// Modules that come compiled: a module package from npm carries its owner
|
|
2
|
+
// plugin's .aot for each system in prebuilt/, with prebuilt/manifest.json
|
|
3
|
+
// saying what it was compiled from. A build takes it in place of compiling
|
|
4
|
+
// the module - seconds of asc and wamrc on every machine - while the project
|
|
5
|
+
// would compile the same thing; when it would not, the build says why and
|
|
6
|
+
// compiles it.
|
|
7
|
+
//
|
|
8
|
+
// bun scripts/prebuilt.ts in a project: compile every module it lists
|
|
9
|
+
// into the module's prebuilt/, for every
|
|
10
|
+
// system (scripts/publish.ts runs it on the
|
|
11
|
+
// packages it stages)
|
|
12
|
+
//
|
|
13
|
+
// What a module's .aot is made of, and so what the manifest holds:
|
|
14
|
+
//
|
|
15
|
+
// - the core: the compile's scripts, the patched AssemblyScript and its
|
|
16
|
+
// Binaryen, the API in as/, the natives table wamrc reads and the WAMR
|
|
17
|
+
// patch - which also decides whether the server's module loads the .aot.
|
|
18
|
+
// A package from the registry is its version: what npm has under a
|
|
19
|
+
// version never changes. A folder on this machine (a checkout) is its
|
|
20
|
+
// content, so the version and a hash are both kept;
|
|
21
|
+
// - every module package the compile reads - the module, and the ones it
|
|
22
|
+
// imports (menu-core reads config-core for its proxy) - the same way;
|
|
23
|
+
// - the options amxts.config.ts gives them: setup is compiled with them;
|
|
24
|
+
// - how the includes declare a forward the module raises with something
|
|
25
|
+
// other than text: a Team, a number or a Float crosses as the declaration
|
|
26
|
+
// says. The server's includes change nothing else of a module;
|
|
27
|
+
// - the project's plugins folder, which lies over the core's as/ in the
|
|
28
|
+
// tree a compile reads: a file there at a place the module reads would be
|
|
29
|
+
// compiled in its stead;
|
|
30
|
+
// - the system: one .aot each, compiled from one wasm.
|
|
31
|
+
//
|
|
32
|
+
// TypeScript is compared without its comments: `amxts prepare` writes the
|
|
33
|
+
// tooltips of the core and the modules in the project's language, which is
|
|
34
|
+
// no change to the code.
|
|
35
|
+
import type { NativesBeside, PluginNative } from './plugin-natives';
|
|
36
|
+
import type { ModulePackage, Options, Sources } from './project';
|
|
37
|
+
import type { System } from './system';
|
|
38
|
+
import { createHash } from 'node:crypto';
|
|
39
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
40
|
+
import { join, relative, resolve, sep } from 'node:path';
|
|
41
|
+
import ts from 'typescript';
|
|
42
|
+
import { compileToMachineCode, compileToWasm } from './compile';
|
|
43
|
+
import { codeFiles } from './compile-cache';
|
|
44
|
+
import { includeForward, nativesBeside } from './plugin-natives';
|
|
45
|
+
import { CORE_DIR, CORE_PLUGINS, loadProject, optionsOf, sourcesFor } from './project';
|
|
46
|
+
import { SYSTEM_NAME, SYSTEMS, wamrcPath } from './system';
|
|
47
|
+
import { c, log, since } from './ui';
|
|
48
|
+
|
|
49
|
+
/** Where a module package keeps its compiled owner: prebuilt/<system>/<name>.aot, and the manifest. */
|
|
50
|
+
export const PREBUILT_DIR = 'prebuilt';
|
|
51
|
+
const MANIFEST = 'manifest.json';
|
|
52
|
+
/** Goes up when the manifest changes shape: a build reads only its own. */
|
|
53
|
+
const FORMAT = 1;
|
|
54
|
+
const CORE_NAME = '@amxts/core';
|
|
55
|
+
|
|
56
|
+
/** A package as a prebuilt module was compiled with it. */
|
|
57
|
+
interface Built {
|
|
58
|
+
version: string;
|
|
59
|
+
/** Its content: the code files, TypeScript without comments. */
|
|
60
|
+
hash: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface PrebuiltManifest {
|
|
64
|
+
format: number;
|
|
65
|
+
module: string;
|
|
66
|
+
version: string;
|
|
67
|
+
/** The core and every module package the compile read, by name. */
|
|
68
|
+
from: Record<string, Built>;
|
|
69
|
+
/** The options each of those modules was compiled with. */
|
|
70
|
+
options: Record<string, Options>;
|
|
71
|
+
/** The forwards it raises with something other than text, as the includes declared them (null: none did). */
|
|
72
|
+
forwards: Record<string, string | null>;
|
|
73
|
+
/** The places under `~/` the compile read: a project's plugins folder must not hold them. */
|
|
74
|
+
places: string[];
|
|
75
|
+
/** Its natives, for the include a Pawn plugin compiles against. */
|
|
76
|
+
natives: PluginNative[];
|
|
77
|
+
beside: NativesBeside;
|
|
78
|
+
systems: Partial<Record<System, { file: string; size: number; sha256: string }>>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** What a build does with a module's prebuilt .aot: takes it, or compiles the module and says why. */
|
|
82
|
+
export type PrebuiltUse = { aot: Uint8Array; natives: PluginNative[]; beside: NativesBeside } | { why: string };
|
|
83
|
+
|
|
84
|
+
const posix = (path: string) => path.replace(/\\/g, '/');
|
|
85
|
+
const sha256 = (data: Uint8Array) => createHash('sha256').update(data).digest('hex');
|
|
86
|
+
|
|
87
|
+
/** Whether a package's folder is one a package manager installed, not a folder on this machine. */
|
|
88
|
+
export function fromRegistry(dir: string): boolean {
|
|
89
|
+
return realpathSync(dir).split(sep).includes('node_modules');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const printer = ts.createPrinter({ removeComments: true });
|
|
93
|
+
|
|
94
|
+
/** A file as a compile sees it: TypeScript without its comments, anything else as it is. */
|
|
95
|
+
function codeOf(file: string): string | Buffer {
|
|
96
|
+
const bytes = readFileSync(file);
|
|
97
|
+
if (!file.endsWith('.ts')) return bytes;
|
|
98
|
+
return printer.printFile(ts.createSourceFile(file, bytes.toString('utf8'), ts.ScriptTarget.Latest, false, ts.ScriptKind.TS));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** The files under `dir`, relative, but for node_modules, prebuilt/ and dot-folders. */
|
|
102
|
+
function filesIn(dir: string, at = ''): string[] {
|
|
103
|
+
return readdirSync(join(dir, at), { withFileTypes: true }).flatMap((entry) => {
|
|
104
|
+
const path = at ? `${at}/${entry.name}` : entry.name;
|
|
105
|
+
if (!entry.isDirectory()) return [path];
|
|
106
|
+
return entry.name === 'node_modules' || entry.name === PREBUILT_DIR || entry.name.startsWith('.') ? [] : filesIn(dir, path);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** One hash of `files` (relative to `base`) by their names and code, with `extra` before them. */
|
|
111
|
+
function hashFiles(base: string, files: string[], extra = ''): string {
|
|
112
|
+
const hash = createHash('sha1').update(`${extra}\0`);
|
|
113
|
+
for (const file of [...files].sort()) hash.update(`${file}\0`).update(codeOf(join(base, file))).update('\0');
|
|
114
|
+
return hash.digest('hex');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* A module package's content: the TypeScript and the includes it publishes
|
|
119
|
+
* (its package.json's `files`, when it lists them), and what its
|
|
120
|
+
* package.json says to the build.
|
|
121
|
+
*/
|
|
122
|
+
function packageHash(pkg: ModulePackage): string {
|
|
123
|
+
const json = JSON.parse(readFileSync(join(pkg.dir, 'package.json'), 'utf8'));
|
|
124
|
+
const listed: string[] | null = Array.isArray(json.files) ? json.files.map((each: string) => each.replace(/^\.\/|\/$/g, '')) : null;
|
|
125
|
+
const published = (file: string) => !listed || listed.some(each => file === each || file.startsWith(`${each}/`));
|
|
126
|
+
const files = filesIn(pkg.dir).filter(file => /\.(?:ts|inc)$/.test(file) && published(file));
|
|
127
|
+
return hashFiles(pkg.dir, files, JSON.stringify({ name: json.name, version: json.version, description: json.description, amxts: json.amxts }));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let coreHashed: string | null = null;
|
|
131
|
+
|
|
132
|
+
/** The core's content: the compile's code, the API, the natives table and the WAMR patch. */
|
|
133
|
+
function coreHash(): string {
|
|
134
|
+
if (coreHashed) return coreHashed;
|
|
135
|
+
const code = codeFiles([join(CORE_DIR, 'scripts/compile.ts')]).filter(existsSync).map(file => posix(relative(CORE_DIR, file)));
|
|
136
|
+
const api = filesIn(CORE_PLUGINS).filter(file => file.endsWith('.ts')).map(file => `as/${file}`);
|
|
137
|
+
const patches = readdirSync(join(CORE_DIR, 'runtime/patches')).map(file => `runtime/patches/${file}`);
|
|
138
|
+
coreHashed = hashFiles(CORE_DIR, [...code, ...api, ...patches, 'runtime/natives.txt']);
|
|
139
|
+
return coreHashed;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** The core or a module package the project has, by name, as a prebuilt module is checked against it. */
|
|
143
|
+
function installed(name: string, sources: Sources): { version: string; dir: string; hash: () => string } | null {
|
|
144
|
+
if (name === CORE_NAME) {
|
|
145
|
+
return { version: String(JSON.parse(readFileSync(join(CORE_DIR, 'package.json'), 'utf8')).version), dir: CORE_DIR, hash: coreHash };
|
|
146
|
+
}
|
|
147
|
+
const pkg = sources.project.packages.find(each => each.name === name);
|
|
148
|
+
return pkg ? { version: pkg.version, dir: pkg.dir, hash: () => packageHash(pkg) } : null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** How a forward's declaration is compared: what decides how its arguments cross. */
|
|
152
|
+
function declarationOf(name: string): string | null {
|
|
153
|
+
const found = includeForward(name);
|
|
154
|
+
return found && JSON.stringify(found.params.map(param => [param.type, Boolean(param.isArray)]));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* The prebuilt .aot of a module from npm for `system`, when it is what the
|
|
159
|
+
* project would compile; else why not. Null for a module that has none - a
|
|
160
|
+
* folder on this machine, or a package without prebuilt/ - which is compiled
|
|
161
|
+
* as any plugin is.
|
|
162
|
+
*/
|
|
163
|
+
export function prebuiltOf(pkg: ModulePackage, system: System, sources: Sources): PrebuiltUse | null {
|
|
164
|
+
const file = join(pkg.dir, PREBUILT_DIR, MANIFEST);
|
|
165
|
+
if (!fromRegistry(pkg.dir) || !existsSync(file)) return null;
|
|
166
|
+
const named = `${pkg.short} ${pkg.version}`;
|
|
167
|
+
let manifest: PrebuiltManifest;
|
|
168
|
+
try {
|
|
169
|
+
manifest = JSON.parse(readFileSync(file, 'utf8'));
|
|
170
|
+
} catch {
|
|
171
|
+
return { why: `${named}: its ${PREBUILT_DIR}/${MANIFEST} cannot be read` };
|
|
172
|
+
}
|
|
173
|
+
if (manifest.format !== FORMAT) return { why: `${named} comes compiled for another build of amxts` };
|
|
174
|
+
const aot = manifest.systems[system];
|
|
175
|
+
if (!aot) return { why: `${named} comes compiled for ${Object.keys(manifest.systems).map(each => SYSTEM_NAME[each as System]).join(' and ')}, not ${SYSTEM_NAME[system]}` };
|
|
176
|
+
|
|
177
|
+
for (const [name, built] of Object.entries(manifest.from)) {
|
|
178
|
+
const have = installed(name, sources);
|
|
179
|
+
if (!have) return { why: `${named} was built with ${name}, which the project does not have` };
|
|
180
|
+
if (have.version !== built.version) return { why: `${named} was built for ${name} ${built.version}, the project has ${have.version}` };
|
|
181
|
+
if (!fromRegistry(have.dir) && have.hash() !== built.hash) {
|
|
182
|
+
return { why: `${named} was built from another ${name} ${built.version} than the one in ${posix(relative(sources.project.dir, have.dir)) || '.'}` };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
for (const [name, options] of Object.entries(manifest.options)) {
|
|
186
|
+
const module = sources.project.packages.find(each => each.name === name)!;
|
|
187
|
+
if (JSON.stringify(optionsOf(sources.project, module.definition)) !== JSON.stringify(options)) {
|
|
188
|
+
return { why: `${named} was built with ${name === pkg.name ? 'its' : `${module.short}'s`} default options, and amxts.config.ts sets ${module.definition.configKey}` };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const [name, declared] of Object.entries(manifest.forwards)) {
|
|
192
|
+
if (declarationOf(name) !== declared) return { why: `the includes declare the forward ${name} otherwise than when ${named} was built` };
|
|
193
|
+
}
|
|
194
|
+
const own = resolve(sources.project.pluginsDir) !== resolve(CORE_PLUGINS);
|
|
195
|
+
const shadow = own ? manifest.places.find(place => existsSync(join(sources.project.pluginsDir, place))) : undefined;
|
|
196
|
+
if (shadow) return { why: `${posix(relative(sources.project.dir, join(sources.project.pluginsDir, shadow)))} takes the place of a file ${named} was built from` };
|
|
197
|
+
|
|
198
|
+
const bytes = new Uint8Array(readFileSync(join(pkg.dir, aot.file)));
|
|
199
|
+
if (sha256(bytes) !== aot.sha256) return { why: `${named}: ${aot.file} is not the file its manifest lists` };
|
|
200
|
+
return { aot: bytes, natives: manifest.natives, beside: manifest.beside };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** The `new Forward<...>("name")` calls of a package whose arguments are not all text: their names. */
|
|
204
|
+
function typedForwards(pkg: ModulePackage): string[] {
|
|
205
|
+
const names: string[] = [];
|
|
206
|
+
for (const file of filesIn(pkg.dir).filter(each => each.endsWith('.ts'))) {
|
|
207
|
+
const text = readFileSync(join(pkg.dir, file), 'utf8');
|
|
208
|
+
for (const at of text.matchAll(/\bnew\s+Forward\b/g)) {
|
|
209
|
+
const call = text.slice(at.index).match(/^new\s+Forward(?:\s*<([^<>]*)>)?\s*\(\s*["']([^"']+)["']/);
|
|
210
|
+
if (!call) throw new Error(`${pkg.name}: ${file} - a Forward whose name and types the prebuilt build cannot read: new Forward<...>("name") with plain types`);
|
|
211
|
+
if ((call[1] ?? '').split(',').some(type => type.trim() !== 'string')) names.push(call[2]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return names;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Compiles one module into its package's prebuilt/: one wasm, an .aot for each system, the manifest. */
|
|
218
|
+
async function prebuild(pkg: ModulePackage, sources: Sources): Promise<string> {
|
|
219
|
+
const started = performance.now();
|
|
220
|
+
const dir = join(pkg.dir, PREBUILT_DIR);
|
|
221
|
+
rmSync(dir, { recursive: true, force: true });
|
|
222
|
+
mkdirSync(dir, { recursive: true });
|
|
223
|
+
const owner = sources.ownerSource(pkg);
|
|
224
|
+
const plugin = { source: owner, output: '', root: CORE_PLUGINS, wamrc: wamrcPath(), signatures: join(CORE_DIR, 'runtime/natives.txt'), quick: false };
|
|
225
|
+
const natives: PluginNative[] = [];
|
|
226
|
+
const wasm = join(dir, `${pkg.short}.wasm`);
|
|
227
|
+
const problem = await compileToWasm(plugin, wasm, false, natives);
|
|
228
|
+
if (problem) throw new Error(`${pkg.name} does not compile:\n${problem}`);
|
|
229
|
+
|
|
230
|
+
const systems: PrebuiltManifest['systems'] = {};
|
|
231
|
+
for (const system of SYSTEMS) {
|
|
232
|
+
const output = join(dir, system, `${pkg.short}.aot`);
|
|
233
|
+
const failed = compileToMachineCode({ ...plugin, output, system }, wasm, natives);
|
|
234
|
+
if (failed) throw new Error(`${pkg.name} for ${SYSTEM_NAME[system]}:\n${failed}`);
|
|
235
|
+
// The include is written from the natives where the build puts the .aot.
|
|
236
|
+
for (const name of readdirSync(join(dir, system)).filter(name => name.endsWith('.inc'))) rmSync(join(dir, system, name));
|
|
237
|
+
const bytes = readFileSync(output);
|
|
238
|
+
systems[system] = { file: `${PREBUILT_DIR}/${system}/${pkg.short}.aot`, size: bytes.length, sha256: sha256(bytes) };
|
|
239
|
+
}
|
|
240
|
+
rmSync(wasm, { force: true });
|
|
241
|
+
|
|
242
|
+
// What the compile read: its places in the tree, and the packages they are in.
|
|
243
|
+
const reached = sources.reach(join(CORE_PLUGINS, 'facade.ts'), sources.reach(join(CORE_PLUGINS, sources.entry(owner))));
|
|
244
|
+
const places = [...reached].map(place => posix(relative(CORE_PLUGINS, place))).sort();
|
|
245
|
+
const used = sources.project.modules.filter(each => each === pkg || [...reached].some(place => sources.packageOf(sources.real(place) ?? place) === each));
|
|
246
|
+
const core = installed(CORE_NAME, sources)!;
|
|
247
|
+
const manifest: PrebuiltManifest = {
|
|
248
|
+
format: FORMAT,
|
|
249
|
+
module: pkg.name,
|
|
250
|
+
version: pkg.version,
|
|
251
|
+
from: Object.fromEntries([[CORE_NAME, { version: core.version, hash: core.hash() }], ...used.map(each => [each.name, { version: each.version, hash: packageHash(each) }])]),
|
|
252
|
+
options: Object.fromEntries(used.map(each => [each.name, optionsOf(sources.project, each.definition)])),
|
|
253
|
+
forwards: Object.fromEntries(used.flatMap(typedForwards).map(name => [name, declarationOf(name)])),
|
|
254
|
+
places,
|
|
255
|
+
natives,
|
|
256
|
+
beside: nativesBeside(natives),
|
|
257
|
+
systems,
|
|
258
|
+
};
|
|
259
|
+
writeFileSync(join(dir, MANIFEST), `${JSON.stringify(manifest, null, '\t')}\n`);
|
|
260
|
+
const sizes = SYSTEMS.map(system => `${SYSTEM_NAME[system]} ${(systems[system]!.size / 1024).toFixed(0)} KB`).join(', ');
|
|
261
|
+
return `prebuilt ${c.bold(pkg.short)} ${c.dim(`${sizes} (${since(started)})`)}`;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (import.meta.main) {
|
|
265
|
+
const project = loadProject(process.cwd());
|
|
266
|
+
if (project.problems.length) throw new Error(project.problems.join('\n'));
|
|
267
|
+
for (const pkg of project.modules) log.success(await prebuild(pkg, sourcesFor(CORE_PLUGINS)));
|
|
268
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// What an editor needs to read a project: .amxts/tsconfig.json, which the
|
|
2
|
+
// project's tsconfig.json extends.
|
|
3
|
+
//
|
|
4
|
+
// npx amxts prepare (also the first step of `amxts build`, with --quiet:
|
|
5
|
+
// the line it prints only under --debug)
|
|
6
|
+
//
|
|
7
|
+
// The project's own tsconfig.json extends it: { "extends": "./.amxts/tsconfig.json" }.
|
|
8
|
+
// It says what the build says - `~/` is the project's plugins over the
|
|
9
|
+
// core's as/, "@amxts/core" is the facade, a module package is its module
|
|
10
|
+
// file - and it takes in amxts.config.ts and every module the config lists, so
|
|
11
|
+
// that the options each module declares (ModuleOptions) type the config.
|
|
12
|
+
// Beside it, imports.d.ts makes what plugins use without an import - the
|
|
13
|
+
// facade's API, the modules' namespaces - globals for the editor
|
|
14
|
+
// (scripts/auto-imports.ts).
|
|
15
|
+
import { existsSync, mkdirSync, realpathSync, writeFileSync } from 'node:fs';
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
17
|
+
import { dirname, isAbsolute, join, relative } from 'node:path';
|
|
18
|
+
import { applyProject, docsLang } from './apply-docs';
|
|
19
|
+
import { importsDeclaration } from './auto-imports';
|
|
20
|
+
import { CONFIG_FILE, CORE_DIR, CORE_PLUGINS, loadProject } from './project';
|
|
21
|
+
import { c, debug, log } from './ui';
|
|
22
|
+
|
|
23
|
+
function fail(message: string): void {
|
|
24
|
+
log.error(message);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const project = loadProject(process.cwd());
|
|
28
|
+
if (project.problems.length) {
|
|
29
|
+
for (const problem of project.problems) fail(problem);
|
|
30
|
+
const missing = project.problems.map(problem => problem.match(/module "([^"]+)" is not installed/)?.[1]).filter(Boolean);
|
|
31
|
+
if (missing.length) log.hint(`Install ${missing.length > 1 ? 'them' : 'it'}: amxts module add ${missing.join(' ')}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// The hood's tooltips - the core's and the modules' - in the language .env
|
|
36
|
+
// picks (AMXTS_DOCS_LANG), as the generated API has them. A core it cannot
|
|
37
|
+
// write to keeps English: the editor still has words, only not these.
|
|
38
|
+
let docs = '';
|
|
39
|
+
try {
|
|
40
|
+
docs = await applyProject(project.dir, docsLang());
|
|
41
|
+
} catch (error) {
|
|
42
|
+
fail(`docs: ${(error as Error).message}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// A module's own folder, without a project config, has its own tsconfig.json
|
|
46
|
+
// (extending the core's as/tsconfig.json): nothing to write there.
|
|
47
|
+
if (!project.config && project.packages.some(pkg => pkg.dir === project.dir)) process.exit(0);
|
|
48
|
+
|
|
49
|
+
const out = join(project.dir, '.amxts');
|
|
50
|
+
/** A path as the generated config writes it: from .amxts/, with forward slashes. */
|
|
51
|
+
function from(path: string) {
|
|
52
|
+
const rel = relative(out, path).replace(/\\/g, '/');
|
|
53
|
+
// Another drive has no relative path: the absolute one, then.
|
|
54
|
+
if (isAbsolute(rel)) return rel;
|
|
55
|
+
return rel.startsWith('.') ? rel : `./${rel}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// AssemblyScript's own config - its types for the standard library - is the
|
|
59
|
+
// core's: the project does not install AssemblyScript itself.
|
|
60
|
+
const assembly = createRequire(join(CORE_DIR, 'package.json')).resolve('assemblyscript/std/assembly.json');
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Whether `name` is found from the project as a package - in node_modules, as
|
|
64
|
+
* Node looks, and the same folder the build takes (a link counts as its
|
|
65
|
+
* target). Such a package is resolved by its package.json ("exports",
|
|
66
|
+
* "types"), not mapped to a file: tools that read tsconfig (knip) take a
|
|
67
|
+
* mapped name for a folder of the project, and its dependency for unused.
|
|
68
|
+
*/
|
|
69
|
+
function installed(name: string, dir: string) {
|
|
70
|
+
for (let at = project.dir; ; at = dirname(at)) {
|
|
71
|
+
const path = join(at, 'node_modules', name);
|
|
72
|
+
if (existsSync(path)) return realpathSync(path) === realpathSync(dir);
|
|
73
|
+
if (dirname(at) === at) return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// `~/` is not a package. The core and the modules are, once installed; one
|
|
78
|
+
// that is not (a module in modules/, a core run from elsewhere) is mapped to
|
|
79
|
+
// its file, as the build finds it.
|
|
80
|
+
const paths: Record<string, string[]> = {
|
|
81
|
+
'~/*': [...new Set([`${from(project.pluginsDir)}/*`, `${from(CORE_PLUGINS)}/*`])],
|
|
82
|
+
};
|
|
83
|
+
if (!installed('@amxts/core', CORE_DIR)) {
|
|
84
|
+
paths['@amxts/core'] = [from(join(CORE_PLUGINS, 'facade.ts'))];
|
|
85
|
+
paths['@amxts/core/*'] = [`${from(CORE_PLUGINS)}/*`];
|
|
86
|
+
}
|
|
87
|
+
for (const pkg of project.modules) {
|
|
88
|
+
if (!installed(pkg.name, pkg.dir)) paths[pkg.name] = [from(pkg.module)];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const tsconfig = {
|
|
92
|
+
extends: from(assembly),
|
|
93
|
+
compilerOptions: {
|
|
94
|
+
// The core's: the lowest target TypeScript 7 keeps. `for (const x of
|
|
95
|
+
// list)` checks against the iterator the core's patched typings give
|
|
96
|
+
// arrays and strings; the compiler lowers the loop itself.
|
|
97
|
+
target: 'es2015',
|
|
98
|
+
// A package by its package.json "exports", as Bun and TypeScript 6 and
|
|
99
|
+
// later read it; TypeScript 5.9 takes "bundler" only with an ES module.
|
|
100
|
+
// asc does not read this: scripts/project.ts answers the names for it.
|
|
101
|
+
module: 'esnext',
|
|
102
|
+
moduleResolution: 'bundler',
|
|
103
|
+
// Every file is a module, one without an import line too: what a
|
|
104
|
+
// plugin declares is its own, never a global another plugin's name
|
|
105
|
+
// collides with.
|
|
106
|
+
moduleDetection: 'force',
|
|
107
|
+
paths,
|
|
108
|
+
},
|
|
109
|
+
include: [
|
|
110
|
+
`${from(project.pluginsDir)}/**/*.ts`,
|
|
111
|
+
from(join(project.dir, CONFIG_FILE)),
|
|
112
|
+
`${from(CORE_PLUGINS)}/*.d.ts`,
|
|
113
|
+
'./modules.d.ts',
|
|
114
|
+
'./imports.d.ts',
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
mkdirSync(out, { recursive: true });
|
|
119
|
+
writeFileSync(join(out, 'tsconfig.json'), `${JSON.stringify(tsconfig, null, '\t')}\n`);
|
|
120
|
+
writeFileSync(join(out, 'modules.d.ts'), [
|
|
121
|
+
'// GENERATED by amxts prepare: the modules amxts.config.ts lists, for the',
|
|
122
|
+
'// options each one adds to ModuleOptions.',
|
|
123
|
+
...project.modules.map(pkg => `import "${pkg.name}";`),
|
|
124
|
+
'',
|
|
125
|
+
'export {};',
|
|
126
|
+
'',
|
|
127
|
+
].join('\n'));
|
|
128
|
+
|
|
129
|
+
writeFileSync(join(out, 'imports.d.ts'), importsDeclaration(project.autoImports));
|
|
130
|
+
|
|
131
|
+
// A step of dev, build and typecheck, which say what the project is
|
|
132
|
+
// themselves: they pass --quiet, and --debug shows it all the same.
|
|
133
|
+
const modules = project.modules.map(pkg => pkg.short).join(', ') || 'no modules';
|
|
134
|
+
if (!process.argv.includes('--quiet') || debug()) log.step(c.dim(`prepared ${(relative(process.cwd(), out) || '.').replace(/\\/g, '/')}/tsconfig.json (${modules})${docs ? ` · ${docs}` : ''}`));
|