@amxts/core 0.2.4 → 0.3.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/README.md +5 -5
- package/README.ru.md +5 -5
- package/as/amxts.d.ts +13 -3
- package/as/entities.ts +571 -501
- package/as/events.ts +3323 -557
- package/as/facade.ts +3079 -718
- package/as/fetch.ts +2 -2
- package/as/fs.ts +352 -59
- package/as/hlds.ts +121 -120
- package/as/hooks.ts +10585 -5177
- package/as/lib/check.ts +3 -2
- package/as/natives.ts +856 -1272
- package/as/promise.ts +37 -27
- package/as/vector.ts +94 -14
- package/includes/order.txt +17 -19
- package/node_modules/assemblyscript/std/assembly/index.d.ts +1 -1
- package/package.json +9 -6
- package/runtime/deps/assemblyscript/dist/asc.js +136 -42
- package/runtime/deps/assemblyscript/dist/assemblyscript.js +141 -141
- package/runtime/licenses/README.md +9 -7
- package/runtime/licenses/ReGameDLL-LICENSE +21 -0
- package/runtime/licenses/ReHLDS-LICENSE +21 -0
- package/runtime/licenses/zlib-LICENSE +22 -0
- package/runtime/natives.txt +618 -523
- package/runtime/patches/README.md +87 -1
- package/runtime/patches/assemblyscript-0.28.20-amxts.patch +4838 -416
- package/runtime/patches/wamr-2.4.5-amxts.patch +417 -5
- package/scripts/auto-imports.ts +1 -1
- package/scripts/build-identity.ts +102 -65
- package/scripts/build-wasm.ts +12 -12
- package/scripts/check.ts +4 -1
- package/scripts/client-messages.ts +73 -1
- package/scripts/compile-cache.ts +11 -8
- package/scripts/compile-pool.ts +6 -3
- package/scripts/compile-worker.ts +23 -23
- package/scripts/compile.ts +142 -19
- package/scripts/docs/as/amxts.ts +10 -4
- package/scripts/docs/as/facade.ts +1779 -275
- package/scripts/docs/as/fetch.ts +2 -2
- package/scripts/docs/as/fs.ts +190 -6
- package/scripts/docs/as/vector.ts +81 -0
- package/scripts/docs/entities.ts +12 -0
- package/scripts/docs/events.ts +49 -13
- package/scripts/docs/game.ts +6 -0
- package/scripts/docs/messages.ts +10 -1
- package/scripts/hlds-events.ts +11 -11
- package/scripts/includes.ts +3 -4
- package/scripts/leaf-natives.ts +84 -0
- package/scripts/player-fields.ts +1 -1
- package/scripts/plugin-natives.ts +1 -1
- package/scripts/prebuilt.ts +41 -10
- package/scripts/project.ts +2 -3
- package/scripts/reapi-events.ts +9 -9
- package/scripts/server-env.ts +145 -0
- package/scripts/shared-modules.ts +23 -7
- package/scripts/system.ts +1 -1
- package/scripts/tracked-fs.ts +11 -2
- package/scripts/typed-commands.ts +153 -15
- package/scripts/upgrade-calls.ts +225 -0
- package/scripts/upgrade-names.ts +1 -4
- package/scripts/upgrade.ts +26 -11
- package/src/cli-api.mjs +3 -2
- package/src/system.mjs +21 -11
- package/src/testing/compile.ts +31 -8
- package/src/testing/coroutines.ts +0 -10
- package/src/testing/memory.ts +89 -2
- package/src/testing/natives.ts +67 -30
- package/src/testing/server.ts +1094 -155
- package/src/testing/tables.ts +23 -6
- package/src/typecheck.mjs +110 -0
- package/runtime/licenses/Bun-LICENSE.md +0 -84
package/src/testing/tables.ts
CHANGED
|
@@ -17,6 +17,17 @@ function generated(file: string): string {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/** A hook's answer, by how its event's result getter reads it: text and a vector are only Ham Sandwich's. */
|
|
21
|
+
function answerOf(result: string | undefined): HookAnswer {
|
|
22
|
+
if (!result) return 'none';
|
|
23
|
+
if (result.includes('__resultText')) return 'text';
|
|
24
|
+
if (result.includes('__resultVector')) return 'vector';
|
|
25
|
+
if (result.startsWith('cellFloat')) return 'float';
|
|
26
|
+
return result.endsWith('!= 0') ? 'bool' : 'int';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type HookAnswer = 'int' | 'float' | 'bool' | 'text' | 'vector' | 'none';
|
|
30
|
+
|
|
20
31
|
/** A hookchain as the fake fires it: which arguments are floats or text, and what it answers. */
|
|
21
32
|
export interface HookShape {
|
|
22
33
|
/** reapi's short name: "take_damage". */
|
|
@@ -25,8 +36,8 @@ export interface HookShape {
|
|
|
25
36
|
floats: Set<number>;
|
|
26
37
|
/** Zero-based arguments the event reads as text. */
|
|
27
38
|
texts: Set<number>;
|
|
28
|
-
/**
|
|
29
|
-
answer:
|
|
39
|
+
/** What the chain answers with: a number, a float, a boolean, text, a vector, or nothing. */
|
|
40
|
+
answer: HookAnswer;
|
|
30
41
|
/** The Ham_* function a Ham Sandwich hook of the event is on, when it has one. */
|
|
31
42
|
ham?: number;
|
|
32
43
|
}
|
|
@@ -36,6 +47,8 @@ export interface Tables {
|
|
|
36
47
|
constants: Map<string, number>;
|
|
37
48
|
/** The dispatcher's native ids (`NATIVE_x`) to names. */
|
|
38
49
|
dispatched: Map<number, string>;
|
|
50
|
+
/** A native's arguments as they cross, by its name: runtime/natives.txt's marks (`s` text in, `t` text back), without the `leaf` after them. */
|
|
51
|
+
crossings: Map<string, string[]>;
|
|
39
52
|
/** A hookchain's number (hookIdOf) to its short name. */
|
|
40
53
|
hookNames: Map<number, string>;
|
|
41
54
|
/** A hookchain by its short name, or by its event name ("takeDamage"). */
|
|
@@ -90,6 +103,10 @@ export function tables(): Tables {
|
|
|
90
103
|
dispatched.set(Number(id), name);
|
|
91
104
|
}
|
|
92
105
|
|
|
106
|
+
const crossings = new Map<string, string[]>();
|
|
107
|
+
const natives = readFileSync(join(PLUGINS_ROOT, '../runtime/natives.txt'), 'utf-8');
|
|
108
|
+
for (const [, name, marks] of natives.matchAll(/^(\w+) \([^)]*\)\S* (\S+)(?: leaf)?$/gm)) crossings.set(name, marks.split(','));
|
|
109
|
+
|
|
93
110
|
const hookNames = new Map<number, string>();
|
|
94
111
|
const switchBody = constantsSource.slice(constantsSource.indexOf('export function hookIdOf'));
|
|
95
112
|
for (const [, name, id] of switchBody.slice(0, switchBody.indexOf('\n}\n')).matchAll(/case "(\w+)": return (-?\d+);/g)) {
|
|
@@ -104,15 +121,14 @@ export function tables(): Tables {
|
|
|
104
121
|
const kind = body.match(/private readonly kind: string = "(\w+)";/)?.[1];
|
|
105
122
|
if (!kind) continue;
|
|
106
123
|
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const answer = !result ? '' : result[1] ?? (result[2] === 'Text' ? 'ATYPE_STRING' : 'ATYPE_VECTOR');
|
|
124
|
+
const result = body.match(/get result\(\)[^{]*\{ return ([^;]*);/)?.[1];
|
|
125
|
+
const answer = answerOf(result);
|
|
110
126
|
const ham = body.match(/private static readonly ham: i32 = (Ham_\w+);/)?.[1];
|
|
111
127
|
const shape: HookShape = {
|
|
112
128
|
kind,
|
|
113
129
|
floats: new Set([...body.matchAll(/cellFloat\(this\.__cell\((\d+)\)\)/g)].map(m => Number(m[1]))),
|
|
114
130
|
texts: new Set([...body.matchAll(/this\.__text\((\d+)\)/g)].map(m => Number(m[1]))),
|
|
115
|
-
answer
|
|
131
|
+
answer,
|
|
116
132
|
...(ham ? { ham: constants.get(ham) } : {}),
|
|
117
133
|
};
|
|
118
134
|
|
|
@@ -144,6 +160,7 @@ export function tables(): Tables {
|
|
|
144
160
|
cached = {
|
|
145
161
|
constants,
|
|
146
162
|
dispatched,
|
|
163
|
+
crossings,
|
|
147
164
|
hookNames,
|
|
148
165
|
hooks,
|
|
149
166
|
floatFields: fieldsOf(kind => (kind & 3) === 1),
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// `amxts typecheck`: TypeScript over the project (.amxts/tsconfig.json, which
|
|
2
|
+
// `prepare` writes), and what TypeScript allows and the build does not:
|
|
3
|
+
//
|
|
4
|
+
// - an event or a message named by a variable. A parameter typed
|
|
5
|
+
// `K extends keyof M` (server.addEventListener, addMessageListener, ...)
|
|
6
|
+
// picks the event's type by the name written in the call, so the build
|
|
7
|
+
// needs a string literal there; a loop over `["a", "b"] as const` gives
|
|
8
|
+
// TypeScript a union, which it takes;
|
|
9
|
+
// - a setting's name or default in a variable: `env(name)`. The build reads
|
|
10
|
+
// which settings a plugin needs, and of which kind, from the call
|
|
11
|
+
// (scripts/server-env.ts);
|
|
12
|
+
// - `const rows = []`: TypeScript reads the element type off the later
|
|
13
|
+
// pushes, the build needs it written.
|
|
14
|
+
//
|
|
15
|
+
// node src/typecheck.mjs in the project's folder; exits 1 on any error
|
|
16
|
+
import { resolve, sep } from 'node:path';
|
|
17
|
+
import process from 'node:process';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import ts from 'typescript';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* What the project's own files - in `root`, outside node_modules and .amxts
|
|
23
|
+
* - write that TypeScript takes and the build does not: each the node it is
|
|
24
|
+
* about and what to write instead.
|
|
25
|
+
*
|
|
26
|
+
* @param {ts.Program} program
|
|
27
|
+
* @param {string} [root] the project's folder
|
|
28
|
+
* @returns {{ node: ts.Node, message: string }[]} the problems, in the files' order
|
|
29
|
+
*/
|
|
30
|
+
export function buildProblems(program, root = process.cwd()) {
|
|
31
|
+
const inside = resolve(root) + sep;
|
|
32
|
+
const checker = program.getTypeChecker();
|
|
33
|
+
const found = [];
|
|
34
|
+
|
|
35
|
+
const visit = (node) => {
|
|
36
|
+
if (ts.isCallExpression(node)) {
|
|
37
|
+
const declaration = checker.getResolvedSignature(node)?.declaration;
|
|
38
|
+
const [name, fallback] = node.arguments;
|
|
39
|
+
if (isFacadeEnv(declaration) && ((name && !ts.isStringLiteralLike(name)) || (fallback && !writtenOut(fallback)))) {
|
|
40
|
+
found.push({ node, message: 'env() takes its name and its default written out - env("MYPLUGIN_TOKEN"), env("MYPLUGIN_LIMIT", 100), env("MYPLUGIN_DEBUG", false), env("MYPLUGIN_URL", "https://...") - the build reads what a plugin needs from the call.' });
|
|
41
|
+
}
|
|
42
|
+
declaration?.parameters?.forEach((parameter, i) => {
|
|
43
|
+
const argument = node.arguments[i];
|
|
44
|
+
if (argument && !ts.isStringLiteral(argument) && namesAKey(parameter, declaration)) {
|
|
45
|
+
found.push({ node: argument, message: `'${argument.getText()}' has to be written out as a string literal - the build picks the event by the name in the call; write a call for each name.` });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (ts.isVariableDeclaration(node) && !node.type && node.initializer && ts.isArrayLiteralExpression(node.initializer) && node.initializer.elements.length === 0) {
|
|
50
|
+
found.push({ node, message: `the build does not read an empty array's element type off its later use - write it: const ${node.name.getText()}: Row[] = []` });
|
|
51
|
+
}
|
|
52
|
+
ts.forEachChild(node, visit);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
for (const file of program.getSourceFiles()) {
|
|
56
|
+
const path = resolve(file.fileName);
|
|
57
|
+
if (!file.isDeclarationFile && path.startsWith(inside) && !/[\\/](?:node_modules|\.amxts)[\\/]/.test(path)) visit(file);
|
|
58
|
+
}
|
|
59
|
+
return found;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Whether a call's function is the facade's env(). */
|
|
63
|
+
function isFacadeEnv(declaration) {
|
|
64
|
+
return declaration?.name?.text === 'env' && /[\\/]facade\.ts$/.test(declaration.getSourceFile().fileName);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Whether a default is written out: text, a number, `-` a number, true or false. */
|
|
68
|
+
function writtenOut(node) {
|
|
69
|
+
if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.MinusToken) return ts.isNumericLiteral(node.operand);
|
|
70
|
+
return ts.isStringLiteralLike(node) || ts.isNumericLiteral(node) || node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Whether the parameter is typed with a type parameter of its function that is `extends keyof ...`. */
|
|
74
|
+
function namesAKey(parameter, declaration) {
|
|
75
|
+
const type = parameter.type;
|
|
76
|
+
if (!type || !ts.isTypeReferenceNode(type) || !ts.isIdentifier(type.typeName)) return false;
|
|
77
|
+
const constraint = declaration.typeParameters?.find(each => each.name.text === type.typeName.text)?.constraint;
|
|
78
|
+
return !!constraint && ts.isTypeOperatorNode(constraint) && constraint.operator === ts.SyntaxKind.KeyOfKeyword;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** `file(line,col): error amxts: ...`, as tsc writes its own. */
|
|
82
|
+
function described({ node, message }) {
|
|
83
|
+
const file = node.getSourceFile();
|
|
84
|
+
const { line, character } = file.getLineAndCharacterOfPosition(node.getStart());
|
|
85
|
+
return `${file.fileName}(${line + 1},${character + 1}): error amxts: ${message}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function main() {
|
|
89
|
+
const config = ts.getParsedCommandLineOfConfigFile('.amxts/tsconfig.json', { noEmit: true }, { ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} });
|
|
90
|
+
if (!config) {
|
|
91
|
+
process.stdout.write('error: .amxts/tsconfig.json cannot be read - run npx amxts prepare\n');
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const program = ts.createProgram({ rootNames: config.fileNames, options: config.options });
|
|
96
|
+
const diagnostics = [...config.errors, ...ts.getPreEmitDiagnostics(program)];
|
|
97
|
+
const format = process.stdout.isTTY ? ts.formatDiagnosticsWithColorAndContext : ts.formatDiagnostics;
|
|
98
|
+
process.stdout.write(format(diagnostics, {
|
|
99
|
+
getCanonicalFileName: name => name,
|
|
100
|
+
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
101
|
+
getNewLine: () => ts.sys.newLine,
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
const problems = buildProblems(program);
|
|
105
|
+
for (const problem of problems) process.stdout.write(`${described(problem)}\n`);
|
|
106
|
+
const errors = diagnostics.filter(each => each.category === ts.DiagnosticCategory.Error).length + problems.length;
|
|
107
|
+
process.exit(errors > 0 ? 1 : 0);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) main();
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
Bun itself is MIT-licensed.
|
|
2
|
-
|
|
3
|
-
## JavaScriptCore
|
|
4
|
-
|
|
5
|
-
Bun statically links JavaScriptCore (and WebKit) which is LGPL-2 licensed. WebCore files from WebKit are also licensed under LGPL2. Per LGPL2:
|
|
6
|
-
|
|
7
|
-
> (1) If you statically link against an LGPL’d library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
|
|
8
|
-
|
|
9
|
-
You can find the patched version of WebKit used by Bun here: <https://github.com/oven-sh/webkit>. If you would like to relink Bun with changes:
|
|
10
|
-
|
|
11
|
-
- `git clone https://github.com/oven-sh/WebKit vendor/WebKit`
|
|
12
|
-
- `bun sync-webkit-source` (checks out the version pinned in `WEBKIT_VERSION` in `scripts/build/deps/webkit.ts`)
|
|
13
|
-
- `bun run build:local`
|
|
14
|
-
|
|
15
|
-
This compiles JavaScriptCore, compiles Bun’s `.cpp` bindings for JavaScriptCore (which are the object files using JavaScriptCore) and outputs a new `bun` binary with your changes.
|
|
16
|
-
|
|
17
|
-
## Linked libraries
|
|
18
|
-
|
|
19
|
-
Bun statically links these libraries:
|
|
20
|
-
|
|
21
|
-
| Library | License |
|
|
22
|
-
|---------|---------|
|
|
23
|
-
| [`boringssl`](https://boringssl.googlesource.com/boringssl/) | [several licenses](https://boringssl.googlesource.com/boringssl/+/refs/heads/master/LICENSE) |
|
|
24
|
-
| [`brotli`](https://github.com/google/brotli) | MIT |
|
|
25
|
-
| [`libarchive`](https://github.com/libarchive/libarchive) | [several licenses](https://github.com/libarchive/libarchive/blob/master/COPYING) |
|
|
26
|
-
| [`lol-html`](https://github.com/cloudflare/lol-html/tree/master/c-api) | BSD 3-Clause |
|
|
27
|
-
| [`ls-hpack`](https://github.com/litespeedtech/ls-hpack) | MIT |
|
|
28
|
-
| [`ls-qpack`](https://github.com/litespeedtech/ls-qpack) | MIT |
|
|
29
|
-
| [`lsquic`](https://github.com/litespeedtech/lsquic) | MIT (portions derived from [Chromium proto-quic](https://github.com/litespeedtech/lsquic/blob/master/LICENSE.chrome), BSD 3-Clause) |
|
|
30
|
-
| [`mimalloc`](https://github.com/microsoft/mimalloc) | MIT |
|
|
31
|
-
| [`picohttp`](https://github.com/h2o/picohttpparser) | dual-licensed under the Perl License or the MIT License |
|
|
32
|
-
| [`zstd`](https://github.com/facebook/zstd) | dual-licensed under the BSD License or GPLv2 license |
|
|
33
|
-
| [`simdutf`](https://github.com/simdutf/simdutf) | Apache 2.0 |
|
|
34
|
-
| [`tinycc`](https://github.com/tinycc/tinycc) | LGPL v2.1 |
|
|
35
|
-
| [`uSockets`](https://github.com/uNetworking/uSockets) | Apache 2.0 |
|
|
36
|
-
| [`zlib-ng`](https://github.com/zlib-ng/zlib-ng) | zlib |
|
|
37
|
-
| [`c-ares`](https://github.com/c-ares/c-ares) | MIT licensed |
|
|
38
|
-
| [`libicu`](https://github.com/unicode-org/icu) 78 | [license here](https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE) |
|
|
39
|
-
| [`libbase64`](https://github.com/aklomp/base64/blob/master/LICENSE) | BSD 2-Clause |
|
|
40
|
-
| [`libuv`](https://github.com/libuv/libuv) (on Windows) | MIT |
|
|
41
|
-
| [`libdeflate`](https://github.com/ebiggers/libdeflate) | MIT |
|
|
42
|
-
| [`libjpeg-turbo`](https://github.com/libjpeg-turbo/libjpeg-turbo) | [BSD 3-Clause / IJG / zlib](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/LICENSE.md) |
|
|
43
|
-
| [`libspng`](https://github.com/randy408/libspng) | BSD 2-Clause |
|
|
44
|
-
| [`libwebp`](https://github.com/webmproject/libwebp) | BSD 3-Clause |
|
|
45
|
-
| [`highway`](https://github.com/google/highway) | Apache 2.0 |
|
|
46
|
-
| [`uucode`](https://github.com/jacobsandlund/uucode) | MIT |
|
|
47
|
-
| A fork of [`uWebsockets`](https://github.com/jarred-sumner/uwebsockets) | Apache 2.0 licensed |
|
|
48
|
-
| Parts of [Tigerbeetle's IO code](https://github.com/tigerbeetle/tigerbeetle/blob/532c8b70b9142c17e07737ab6d3da68d7500cbca/src/io/windows.zig#L1) | Apache 2.0 licensed |
|
|
49
|
-
| `__cxa_thread_atexit` fallback from [LLVM libc++abi](https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/libcxxabi/src/cxa_thread_atexit.cpp) | Apache 2.0 with LLVM exception |
|
|
50
|
-
|
|
51
|
-
## Polyfills
|
|
52
|
-
|
|
53
|
-
For compatibility reasons, the following packages are embedded into Bun's binary and injected if imported.
|
|
54
|
-
|
|
55
|
-
| Package | License |
|
|
56
|
-
|---------|---------|
|
|
57
|
-
| [`acorn`](https://github.com/acornjs/acorn) | MIT |
|
|
58
|
-
| [`acorn-walk`](https://github.com/acornjs/acorn) | MIT |
|
|
59
|
-
| [`assert`](https://npmjs.com/package/assert) | MIT |
|
|
60
|
-
| [`browserify-zlib`](https://npmjs.com/package/browserify-zlib) | MIT |
|
|
61
|
-
| [`buffer`](https://npmjs.com/package/buffer) | MIT |
|
|
62
|
-
| [`constants-browserify`](https://npmjs.com/package/constants-browserify) | MIT |
|
|
63
|
-
| [`crypto-browserify`](https://npmjs.com/package/crypto-browserify) | MIT |
|
|
64
|
-
| [`domain-browser`](https://npmjs.com/package/domain-browser) | MIT |
|
|
65
|
-
| [`events`](https://npmjs.com/package/events) | MIT |
|
|
66
|
-
| [`https-browserify`](https://npmjs.com/package/https-browserify) | MIT |
|
|
67
|
-
| [`os-browserify`](https://npmjs.com/package/os-browserify) | MIT |
|
|
68
|
-
| [`path-browserify`](https://npmjs.com/package/path-browserify) | MIT |
|
|
69
|
-
| [`process`](https://npmjs.com/package/process) | MIT |
|
|
70
|
-
| [`punycode`](https://npmjs.com/package/punycode) | MIT |
|
|
71
|
-
| [`querystring-es3`](https://npmjs.com/package/querystring-es3) | MIT |
|
|
72
|
-
| [`stream-browserify`](https://npmjs.com/package/stream-browserify) | MIT |
|
|
73
|
-
| [`stream-http`](https://npmjs.com/package/stream-http) | MIT |
|
|
74
|
-
| [`string_decoder`](https://npmjs.com/package/string_decoder) | MIT |
|
|
75
|
-
| [`timers-browserify`](https://npmjs.com/package/timers-browserify) | MIT |
|
|
76
|
-
| [`tty-browserify`](https://npmjs.com/package/tty-browserify) | MIT |
|
|
77
|
-
| [`url`](https://npmjs.com/package/url) | MIT |
|
|
78
|
-
| [`util`](https://npmjs.com/package/util) | MIT |
|
|
79
|
-
| [`vm-browserify`](https://npmjs.com/package/vm-browserify) | MIT |
|
|
80
|
-
|
|
81
|
-
## Additional credits
|
|
82
|
-
|
|
83
|
-
- Bun's JS transpiler, CSS lexer, and Node.js module resolver source code is a port of [@evanw](https://github.com/evanw)’s [esbuild](https://github.com/evanw/esbuild) project.
|
|
84
|
-
- Credit to [@kipply](https://github.com/kipply) for the name "Bun"!
|