chore: 添加第三方依赖库

This commit is contained in:
yhh
2025-12-03 16:24:08 +08:00
parent cb1b171216
commit 83aee02540
172 changed files with 27480 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
# tsconfig json files
- tsconfig.common.json - shared TypeScript options
- tsconfig.pkg2d.json - config for compiling rapier2d-compat
- tsconfig.pkg3d.json - config for compiling rapier3d-compat
- tconfig.json - for IDE (VSCode) and unit tests. Includes Jest types.
## Generation steps
Check `./package.json scripts`, which are used by CI.
Summary:
- build rust wasm projects into their dedicated folder in `./builds/`
- copy common javascript and generate dimension specific javascript into a common `./pkg` folder
- copy that `pkg` folder in each folder from `./builds`

View File

@@ -0,0 +1,50 @@
#!/bin/bash
help()
{
printf "Usage: %s: [-d 2|3] [-f deterministim|non-deterministic|simd]\n" $0
}
while getopts :d:f: name
do
case $name in
d)
dimension="$OPTARG";;
f)
feature="$OPTARG";;
?) help ; exit 1;;
esac
done
if [[ -z "$dimension" ]]; then
help; exit 2;
fi
if [[ -z "$feature" ]]; then
help; exit 3;
fi
if [[ $feature == "non-deterministic" ]]; then
feature_postfix=""
else
feature_postfix="-${feature}"
fi
rust_source_directory="../builds/rapier${dimension}d${feature_postfix}"
if [ ! -d "$rust_source_directory" ]; then
echo "Directory $rust_source_directory does not exist";
echo "You may want to generate rust projects first.";
help
exit 4;
fi
# Working dir in wasm-pack is the project root so we need that "../../"
if [[ $feature == "simd" ]]; then
export additional_rustflags='-C target-feature=+simd128'
else
export additional_rustflags=''
fi
RUSTFLAGS="${additional_rustflags}" wasm-pack --verbose build --target web --out-dir "../../rapier-compat/builds/${dimension}d${feature_postfix}/wasm-build" "$rust_source_directory"

View File

@@ -0,0 +1,11 @@
#!/bin/bash
for feature in \
2d 2d-deterministic 2d-simd \
3d 3d-deterministic 3d-simd
do
echo 'export * from "'"./rapier_wasm$feature"'"' > builds/${feature}/pkg/raw.d.ts
echo 'export * from "'"./rapier_wasm$feature"'"' > builds/${feature}/pkg/raw.d.ts
done;

View File

@@ -0,0 +1,58 @@
# Copy source and remove #if sections - similar to script in ../rapierXd
set -e
gen_js() {
DIM=$1
GENOUT="./gen${DIM}"
# Make output directories
mkdir -p ${GENOUT}
# Copy common sources
cp -r ../src.ts/* $GENOUT
# Copy compat mode override sources
rm -f "${GENOUT}/raw.ts" "${GENOUT}/init.ts"
cp -r ./src${DIM}/* $GENOUT
}
gen_js "2d"
gen_js "3d"
# See https://serverfault.com/a/137848
find gen2d/ -type f -print0 | LC_ALL=C xargs -0 sed -i.bak '\:#if DIM3:,\:#endif:d'
find gen3d/ -type f -print0 | LC_ALL=C xargs -0 sed -i.bak '\:#if DIM2:,\:#endif:d'
# Clean up backup files.
find gen2d/ -type f -name '*.bak' | xargs rm
find gen3d/ -type f -name '*.bak' | xargs rm
for features_set in \
"2" "2 deterministic" "2 simd" \
"3" "3 deterministic" "3 simd"
do
set -- $features_set # Convert the "tuple" into the param args $1 $2...
dimension=$1
if [ -z "$2" ]; then
feature="${1}d";
else
feature="${1}d-${2}";
fi
mkdir -p ./builds/${feature}/pkg/
cp ./builds/${feature}/wasm-build/rapier_wasm* ./builds/${feature}/pkg/
cp -r ./gen${dimension}d ./builds/${feature}/
# copy tsconfig, as they contain paths
cp ./tsconfig.common.json ./tsconfig.json ./builds/${feature}/
cp ./tsconfig.pkg${dimension}d.json ./builds/${feature}/tsconfig.pkg.json
# "import.meta" causes Babel to choke, but the code path is never taken so just remove it.
sed -i.bak 's/import.meta.url/"<deleted>"/g' ./builds/${feature}/pkg/rapier_wasm${dimension}d.js
# Clean up backup files.
find ./builds/${feature}/pkg/ -type f -name '*.bak' | xargs rm
done

View File

@@ -0,0 +1,59 @@
{
"name": "build-rapier",
"description": "Build scripts for compatibility package with inlined webassembly as base64.",
"private": true,
"scripts": {
"build-rust-2d-non-deterministic": "./build-rust.sh -f non-deterministic -d 2",
"build-rust-2d-deterministic": "./build-rust.sh -f deterministic -d 2",
"build-rust-2d-simd": "./build-rust.sh -f simd -d 2",
"build-rust-2d-all": "npm run build-rust-2d-non-deterministic && npm run build-rust-2d-deterministic && npm run build-rust-2d-simd",
"build-rust-3d-non-deterministic": "./build-rust.sh -f non-deterministic -d 3",
"build-rust-3d-deterministic": "./build-rust.sh -f deterministic -d 3",
"build-rust-3d-simd": "./build-rust.sh -f simd -d 3",
"build-rust-3d-all": "npm run build-rust-3d-non-deterministic && npm run build-rust-3d-deterministic && npm run build-rust-3d-simd",
"build-rust-all": "npm run build-rust-2d-all && npm run build-rust-3d-all",
"build-genjs": "sh ./gen_src.sh",
"build-js": "rollup --config rollup.config.js --bundleConfigAsCjs",
"fix-raw-file": "sh ./fix_raw_file.sh",
"build": "npm run clean && npm run build-rust-all && npm run build-genjs && npm run build-js && npm run fix-raw-file",
"clean": "rimraf gen2d gen3d builds",
"test": "jest --detectOpenHandles",
"all": "npm run build"
},
"dependencies": {
"base64-js": "^1.5.1"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^23.0.2",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-typescript": "^9.0.2",
"@rollup/plugin-terser": "0.1.0",
"@types/jest": "^29.2.1",
"jest": "^29.2.2",
"rimraf": "^3.0.2",
"rollup": "^3.2.5",
"rollup-plugin-base64": "^1.0.1",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-filesize": "^9.1.2",
"ts-jest": "^29.0.3",
"tslib": "^2.4.1",
"typescript": "^4.8.4"
},
"jest": {
"roots": [
"<rootDir>/tests"
],
"preset": "ts-jest",
"collectCoverageFrom": [
"builds/**/pkg/**/*.js"
],
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|ts)$",
"builds/.*/[/\\\\]pkg[/\\\\].+\\.(js|ts)$"
],
"moduleFileExtensions": [
"ts",
"js"
]
}
}

View File

@@ -0,0 +1,85 @@
import commonjs from "@rollup/plugin-commonjs";
import {nodeResolve} from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import terser from "@rollup/plugin-terser";
import path from "path";
import {base64} from "rollup-plugin-base64";
import copy from "rollup-plugin-copy";
import filesize from "rollup-plugin-filesize";
const config = (dim, features_postfix) => ({
input: `builds/${features_postfix}/gen${dim}/rapier.ts`,
output: [
{
file: `builds/${features_postfix}/pkg/rapier.mjs`,
format: "es",
sourcemap: true,
exports: "named",
},
{
file: `builds/${features_postfix}/pkg/rapier.cjs`,
format: "cjs",
sourcemap: true,
exports: "named",
},
],
plugins: [
copy({
targets: [
{
src: `builds/${features_postfix}/wasm-build/package.json`,
dest: `builds/${features_postfix}/pkg/`,
transform(content) {
let config = JSON.parse(content.toString());
config.name = `@dimforge/rapier${features_postfix}-compat`;
config.description +=
" Compatibility package with inlined webassembly as base64.";
config.types = "rapier.d.ts";
config.main = "rapier.cjs";
config.module = "rapier.mjs";
config.exports = {
".": {
types: "./rapier.d.ts",
require: "./rapier.cjs",
import: "./rapier.mjs",
},
};
// delete config.module;
config.files = ["*"];
return JSON.stringify(config, undefined, 2);
},
},
{
src: `../rapier${features_postfix}/LICENSE`,
dest: `builds/${features_postfix}/pkg`,
},
{
src: `../rapier${features_postfix}/README.md`,
dest: `builds/${features_postfix}/pkg`,
},
],
}),
base64({include: "**/*.wasm"}),
terser(),
nodeResolve(),
commonjs(),
typescript({
tsconfig: path.resolve(
__dirname,
`builds/${features_postfix}/tsconfig.pkg.json`,
),
sourceMap: true,
inlineSources: true,
}),
filesize(),
],
});
export default [
config("2d", "2d"),
config("2d", "2d-deterministic"),
config("2d", "2d-simd"),
config("3d", "3d"),
config("3d", "3d-deterministic"),
config("3d", "3d-simd"),
];

View File

@@ -0,0 +1,60 @@
/**
* RAPIER initialization module with dynamic WASM loading support.
* RAPIER 初始化模块,支持动态 WASM 加载。
*/
import wasmInit from "../pkg/rapier_wasm2d";
/**
* Input types for WASM initialization.
* WASM 初始化的输入类型。
*/
export type InitInput =
| RequestInfo // URL string or Request object
| URL // URL object
| Response // Fetch Response object
| BufferSource // ArrayBuffer or TypedArray
| WebAssembly.Module; // Pre-compiled module
let initialized = false;
/**
* Initializes RAPIER.
* Has to be called and awaited before using any library methods.
*
* 初始化 RAPIER。
* 必须在使用任何库方法之前调用并等待。
*
* @param input - WASM source (required). Can be URL, Response, ArrayBuffer, etc.
* WASM 源(必需)。可以是 URL、Response、ArrayBuffer 等。
*
* @example
* // Load from URL | 从 URL 加载
* await RAPIER.init('wasm/rapier_wasm2d_bg.wasm');
*
* @example
* // Load from fetch response | 从 fetch 响应加载
* const response = await fetch('wasm/rapier_wasm2d_bg.wasm');
* await RAPIER.init(response);
*
* @example
* // Load from ArrayBuffer | 从 ArrayBuffer 加载
* const buffer = await fetch('wasm/rapier_wasm2d_bg.wasm').then(r => r.arrayBuffer());
* await RAPIER.init(buffer);
*/
export async function init(input?: InitInput): Promise<void> {
if (initialized) {
return;
}
await wasmInit(input);
initialized = true;
}
/**
* Check if RAPIER is already initialized.
* 检查 RAPIER 是否已初始化。
*/
export function isInitialized(): boolean {
return initialized;
}

View File

@@ -0,0 +1 @@
export * from "../pkg/rapier_wasm2d";

View File

@@ -0,0 +1,12 @@
// @ts-ignore
import wasmBase64 from "../pkg/rapier_wasm3d_bg.wasm";
import wasmInit from "../pkg/rapier_wasm3d";
import base64 from "base64-js";
/**
* Initializes RAPIER.
* Has to be called and awaited before using any library methods.
*/
export async function init() {
await wasmInit(base64.toByteArray(wasmBase64 as unknown as string).buffer);
}

View File

@@ -0,0 +1 @@
export * from "../pkg/rapier_wasm3d";

View File

@@ -0,0 +1,23 @@
import {init, Vector2, World} from "../builds/2d-deterministic/pkg";
describe("2d/World", () => {
let world: World;
beforeAll(init);
afterAll(async () => {
await Promise.resolve();
});
beforeEach(() => {
world = new World(new Vector2(0, 9.8));
});
afterEach(() => {
world.free();
});
test("constructor", () => {
expect(world.colliders.len()).toBe(0);
});
});

View File

@@ -0,0 +1,23 @@
import {init, Vector3, World} from "../builds/3d-deterministic/pkg";
describe("3d/World", () => {
let world: World;
beforeAll(init);
afterAll(async () => {
await Promise.resolve();
});
beforeEach(() => {
world = new World(new Vector3(0, 9.8, 0));
});
afterEach(() => {
world.free();
});
test("constructor", () => {
expect(world.colliders.len()).toBe(0);
});
});

View File

@@ -0,0 +1,15 @@
import {Vector2, VectorOps} from "../builds/2d-deterministic/pkg";
describe("2d/math", () => {
test("Vector2", () => {
const v = new Vector2(0, 1);
expect(v.x).toBe(0);
expect(v.y).toBe(1);
});
test("VectorOps", () => {
const v = VectorOps.new(0, 1);
expect(v.x).toBe(0);
expect(v.y).toBe(1);
});
});

View File

@@ -0,0 +1,17 @@
import {Vector3, VectorOps} from "../builds/3d-deterministic/pkg";
describe("3d/math", () => {
test("Vector3", () => {
const v = new Vector3(0, 1, 2);
expect(v.x).toBe(0);
expect(v.y).toBe(1);
expect(v.z).toBe(2);
});
test("VectorOps", () => {
const v = VectorOps.new(0, 1, 2);
expect(v.x).toBe(0);
expect(v.y).toBe(1);
expect(v.z).toBe(2);
});
});

View File

@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "ES6",
"target": "es6",
"noEmitOnError": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"lib": ["es6", "DOM"],
"moduleResolution": "node",
"esModuleInterop": true,
"sourceMap": true,
"declaration": true
}
}

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.common.json",
"compilerOptions": {
"lib": ["es6", "DOM"],
"esModuleInterop": true,
"types": ["jest"],
"outDir": "./dist"
},
"include": ["./tests/**/*.test.ts"]
}

View File

@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.common.json",
"compilerOptions": {
"rootDir": "./gen2d",
"outDir": "./2d"
},
"files": ["./gen2d/rapier.ts"]
}

View File

@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.common.json",
"compilerOptions": {
"rootDir": "./gen3d",
"outDir": "."
},
"files": ["./gen3d/rapier.ts"]
}