aminus 0.1.0-alpha.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 (2) hide show
  1. package/README.md +442 -0
  2. package/package.json +77 -0
package/README.md ADDED
@@ -0,0 +1,442 @@
1
+ # Aminus JavaScript/TypeScript Bindings
2
+
3
+ JavaScript and TypeScript bindings for the Aminus Genshin Impact calculation library.
4
+
5
+ ## Features
6
+
7
+ - **Full TypeScript Support**: Complete type definitions for all functions and classes
8
+ - **ESM Module Support**: Uses modern ES modules
9
+ - **WebAssembly**: High-performance calculations compiled from Rust
10
+ - **Cross-Platform**: Works in Node.js, browsers, and bundlers
11
+ - **Zero Dependencies**: No runtime dependencies besides the WASM module
12
+ - **Artifact Optimization**: Advanced algorithms for finding optimal artifact combinations
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install aminus-js
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### TypeScript
23
+
24
+ ```typescript
25
+ import { loadWasm, Stat, Element, DamageType, BaseScaling, Amplifier } from 'aminus-js';
26
+
27
+ async function calculateDamage() {
28
+ // Load the WASM module
29
+ const aminus = await loadWasm();
30
+
31
+ // Create a character stat table
32
+ const character = aminus.StatTableWrapper.fromArray([
33
+ [Stat.BaseATK, 334.85],
34
+ [Stat.ATKPercent, 0.5],
35
+ [Stat.CritRate, 0.6],
36
+ [Stat.CritDMG, 1.2],
37
+ [Stat.PyroDMGBonus, 0.466],
38
+ ]);
39
+
40
+ // Calculate damage
41
+ const damage = aminus.calculateDamage(
42
+ Element.Pyro,
43
+ DamageType.Skill,
44
+ BaseScaling.ATK,
45
+ Amplifier.None,
46
+ 1.0, // instances
47
+ 2.5, // motion value
48
+ character
49
+ );
50
+
51
+ console.log(`Skill damage: ${damage}`);
52
+ }
53
+
54
+ calculateDamage();
55
+ ```
56
+
57
+ ### JavaScript (ESM)
58
+
59
+ ```javascript
60
+ import { loadWasm, Stat, Element, DamageType, BaseScaling, Amplifier } from 'aminus-js';
61
+
62
+ const aminus = await loadWasm();
63
+
64
+ // Create artifact builder
65
+ const builder = aminus.ArtifactBuilderWrapper.kqmAll5Star(
66
+ Stat.ATKPercent, // sands
67
+ Stat.PyroDMGBonus, // goblet
68
+ Stat.CritRate // circlet
69
+ );
70
+
71
+ // Add substat rolls
72
+ builder.roll(Stat.CritDMG, 4, 5, 6); // RollQuality.AVG, rarity 5, 6 rolls
73
+
74
+ // Get final stats
75
+ const artifacts = builder.build();
76
+ console.log(`Total Crit DMG: ${artifacts.get(Stat.CritDMG)}`);
77
+ ```
78
+
79
+ ### Artifact Optimization
80
+
81
+ ```typescript
82
+ import {
83
+ createStatTable,
84
+ createRotation,
85
+ optimizeArtifactMainStats,
86
+ optimizeArtifactSubstats,
87
+ Stat, Element, DamageType, BaseScaling, Amplifier
88
+ } from 'aminus-js';
89
+
90
+ async function optimizeCharacter() {
91
+ // Create character stats
92
+ const characterStats = createStatTable();
93
+ characterStats.set(Stat.BaseATK, 106.0);
94
+ characterStats.set(Stat.CritRate, 0.05);
95
+ characterStats.set(Stat.CritDMG, 0.5);
96
+
97
+ // Create rotation (damage sequence)
98
+ const rotation = createRotation();
99
+ rotationadd(
100
+ 'pyro_attack',
101
+ Element.Pyro,
102
+ DamageType.Normal,
103
+ BaseScaling.ATK,
104
+ Amplifier.None,
105
+ 1.0, // instances
106
+ 1.0 // motion value
107
+ );
108
+
109
+ // Optimize artifact main stats
110
+ const bestMainStats = await optimizeArtifactMainStats(characterStats, rotation);
111
+ console.log('Best main stats:', bestMainStats); // [sands, goblet, circlet]
112
+
113
+ // Optimize artifact substats
114
+ const substatDistribution = await optimizeArtifactSubstats(
115
+ characterStats,
116
+ rotation,
117
+ 1.2, // energy recharge requirement
118
+ flower, feather, sands, goblet, circlet
119
+ );
120
+ console.log('Optimal substat distribution:', substatDistribution);
121
+ }
122
+ ```
123
+
124
+ ## Building
125
+
126
+ ### Prerequisites
127
+
128
+ - [Rust](https://rustup.rs/) (latest stable)
129
+ - [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
130
+ - [Node.js](https://nodejs.org/) (16+)
131
+
132
+ ### Build Commands
133
+
134
+ ```bash
135
+ # Install dependencies
136
+ npm install
137
+
138
+ # Build for bundlers (default)
139
+ npm run build
140
+
141
+ # Build for Node.js
142
+ npm run build:nodejs
143
+
144
+ # Build for web browsers
145
+ npm run build:web
146
+
147
+ # Run tests
148
+ npm test
149
+
150
+ # Development mode (build + test)
151
+ npm run dev
152
+ ```
153
+
154
+ ## API Reference
155
+
156
+ ### Types
157
+
158
+ #### Enums
159
+
160
+ - `Stat`: Character and artifact statistics
161
+ - `Element`: Elemental types (Pyro, Hydro, etc.)
162
+ - `DamageType`: Attack types (Normal, Charged, Skill, Burst, etc.)
163
+ - `BaseScaling`: Damage scaling base (ATK, DEF, HP)
164
+ - `Amplifier`: Reaction amplifiers (None, Forward, Reverse)
165
+ - `RollQuality`: Artifact substat roll quality
166
+
167
+ #### Core Classes
168
+
169
+ ##### StatTableWrapper
170
+
171
+ Manages character statistics.
172
+
173
+ ```typescript
174
+ const stats = new StatTableWrapper();
175
+ stats.add(Stat.ATKPercent, 0.5);
176
+ const atkPercent = stats.get(Stat.ATKPercent);
177
+
178
+ // Create from array
179
+ const stats2 = StatTableWrapper.fromArray([
180
+ [Stat.BaseATK, 100],
181
+ [Stat.ATKPercent, 0.5]
182
+ ]);
183
+ ```
184
+
185
+ ##### ArtifactBuilderWrapper
186
+
187
+ Builds artifact stat combinations.
188
+
189
+ ```typescript
190
+ // Manual construction
191
+ const builder = new ArtifactBuilderWrapper(flower, feather, sands, goblet, circlet);
192
+
193
+ // KQM presets
194
+ const builder = ArtifactBuilderWrapper.kqmAll5Star(
195
+ Stat.ATKPercent, // sands main stat
196
+ Stat.PyroDMGBonus, // goblet main stat
197
+ Stat.CritRate // circlet main stat
198
+ );
199
+
200
+ // Roll substats
201
+ builder.roll(Stat.CritDMG, RollQuality.AVG, 5, 4);
202
+ const finalStats = builder.build();
203
+ ```
204
+
205
+ ##### Rotation
206
+
207
+ Defines a sequence of damage operations for optimization.
208
+
209
+ ```typescript
210
+ const rotation = createRotation();
211
+
212
+ // Add damage operations
213
+ rotationadd(
214
+ 'normal_attack',
215
+ Element.Pyro,
216
+ DamageType.Normal,
217
+ BaseScaling.ATK,
218
+ Amplifier.None,
219
+ 1.0, // instances
220
+ 1.0 // motion value
221
+ );
222
+
223
+ rotationadd(
224
+ 'skill_attack',
225
+ Element.Pyro,
226
+ DamageType.Skill,
227
+ BaseScaling.ATK,
228
+ Amplifier.None,
229
+ 1.0,
230
+ 2.5
231
+ );
232
+
233
+ // Evaluate total damage
234
+ const totalDamage = rotation.evaluate(characterStats);
235
+ ```
236
+
237
+ ### Functions
238
+
239
+ #### Damage Calculation
240
+
241
+ ```typescript
242
+ const damage = calculateDamage(
243
+ element: Element,
244
+ damageType: DamageType,
245
+ scaling: BaseScaling,
246
+ amplifier: Amplifier,
247
+ instances: number,
248
+ motionValue: number,
249
+ character: StatTableWrapper,
250
+ buffs?: StatTableWrapper
251
+ ): number;
252
+ ```
253
+
254
+ #### Artifact Optimization
255
+
256
+ ```typescript
257
+ // Optimize artifact main stats
258
+ const bestMainStats = await optimizeArtifactMainStats(
259
+ characterStats: StatTableWrapper,
260
+ target: Rotation
261
+ ): Promise<number[]>; // [sands, goblet, circlet] stat IDs
262
+
263
+ // Optimize artifact substats
264
+ const substatDistribution = await optimizeArtifactSubstats(
265
+ characterStats: StatTableWrapper,
266
+ target: Rotation,
267
+ energyRechargeRequirements?: number,
268
+ flower?: ArtifactPiece,
269
+ feather?: ArtifactPiece,
270
+ sands?: ArtifactPiece,
271
+ goblet?: ArtifactPiece,
272
+ circlet?: ArtifactPiece
273
+ ): Promise<Record<number, number>>; // stat ID -> roll count
274
+
275
+ // Calculate stat gradients
276
+ const gradients = await calculateStatGradients(
277
+ base: StatTableWrapper,
278
+ target: Rotation,
279
+ slopes: Record<number, number>
280
+ ): Promise<Record<number, number>>;
281
+
282
+ // Find effective stats (ReLU heuristic)
283
+ const effectiveStats = await calculateReluHeuristic(
284
+ base: StatTableWrapper,
285
+ target: Rotation,
286
+ slopes: Record<number, number>
287
+ ): Promise<number[]>;
288
+ ```
289
+
290
+ #### Formula Functions
291
+
292
+ ```typescript
293
+ // Calculate total stats
294
+ const totalATK = calculateTotalAtkFromTable(stats);
295
+ const totalDEF = calculateTotalDefFromTable(stats);
296
+ const totalHP = calculateTotalHpFromTable(stats);
297
+
298
+ // Calculate multipliers
299
+ const critMultiplier = calculateAvgCritMultiplierFromTable(stats);
300
+ const defMultiplier = calculateDefMultiplier(charLevel, enemyLevel, defReduction, defIgnore);
301
+ ```
302
+
303
+ #### Utility Functions
304
+
305
+ ```typescript
306
+ // Convert stat names
307
+ const stat = statFromString('atk'); // Returns Stat.ATKPercent
308
+ const name = getStatName(Stat.ATKPercent); // Returns 'ATKPercent'
309
+
310
+ // Check stat properties
311
+ const isElemental = isElementalDmgBonus(Stat.PyroDMGBonus); // true
312
+ ```
313
+
314
+ ## Examples
315
+
316
+ ### Character Damage Calculation
317
+
318
+ ```typescript
319
+ import { loadWasm, Stat, Element, DamageType, BaseScaling, Amplifier } from 'aminus-js';
320
+
321
+ async function calculateDilucDamage() {
322
+ const aminus = await loadWasm();
323
+
324
+ // Diluc base stats
325
+ const character = aminus.StatTableWrapper.fromArray([
326
+ [Stat.BaseATK, 334.85],
327
+ [Stat.CritRate, 0.242],
328
+ [Stat.CritDMG, 0.5],
329
+ ]);
330
+
331
+ // Wolf's Gravestone weapon
332
+ const weapon = aminus.StatTableWrapper.fromArray([
333
+ [Stat.BaseATK, 608],
334
+ [Stat.ATKPercent, 0.496],
335
+ ]);
336
+
337
+ // Artifact stats
338
+ const artifacts = aminus.StatTableWrapper.fromArray([
339
+ [Stat.FlatATK, 311],
340
+ [Stat.ATKPercent, 0.466],
341
+ [Stat.PyroDMGBonus, 0.466],
342
+ [Stat.CritRate, 0.311],
343
+ [Stat.CritDMG, 0.622],
344
+ ]);
345
+
346
+ // Combine all stats
347
+ character.addTable(weapon);
348
+ character.addTable(artifacts);
349
+
350
+ // Calculate E skill damage
351
+ const skillDamage = aminus.calculateDamage(
352
+ Element.Pyro,
353
+ DamageType.Skill,
354
+ BaseScaling.ATK,
355
+ Amplifier.None,
356
+ 1.0,
357
+ 2.016, // Diluc E motion value
358
+ character
359
+ );
360
+
361
+ console.log(`Diluc E damage: ${skillDamage.toFixed(0)}`);
362
+ }
363
+ ```
364
+
365
+ ### Artifact Optimization
366
+
367
+ ```typescript
368
+ import { loadWasm, Stat, RollQuality } from 'aminus-js';
369
+
370
+ async function optimizeArtifacts() {
371
+ const aminus = await loadWasm();
372
+
373
+ // Create KQM 5-star artifact set
374
+ const builder = aminus.ArtifactBuilderWrapper.kqmAll5Star(
375
+ Stat.ATKPercent, // sands
376
+ Stat.PyroDMGBonus, // goblet
377
+ Stat.CritRate // circlet
378
+ );
379
+
380
+ // Simulate rolling substats
381
+ builder.roll(Stat.CritDMG, RollQuality.HIGH, 5, 6);
382
+ builder.roll(Stat.ATKPercent, RollQuality.AVG, 5, 4);
383
+ builder.roll(Stat.FlatATK, RollQuality.LOW, 5, 2);
384
+
385
+ const artifacts = builder.build();
386
+
387
+ console.log('Final artifact stats:');
388
+ console.log(`ATK%: ${(artifacts.get(Stat.ATKPercent) * 100).toFixed(1)}%`);
389
+ console.log(`Crit Rate: ${(artifacts.get(Stat.CritRate) * 100).toFixed(1)}%`);
390
+ console.log(`Crit DMG: ${(artifacts.get(Stat.CritDMG) * 100).toFixed(1)}%`);
391
+ console.log(`Pyro DMG: ${(artifacts.get(Stat.PyroDMGBonus) * 100).toFixed(1)}%`);
392
+ }
393
+ ```
394
+
395
+ ## Browser Usage
396
+
397
+ For browser environments, you may need to handle WASM loading differently:
398
+
399
+ ```html
400
+ <!DOCTYPE html>
401
+ <html>
402
+ <head>
403
+ <script type="module">
404
+ import { loadWasm, Stat } from './node_modules/aminus-js/pkg/aminus_js.js';
405
+
406
+ async function main() {
407
+ const aminus = await loadWasm();
408
+
409
+ const stats = new aminus.StatTableWrapper();
410
+ stats.add(Stat.ATKPercent, 0.5);
411
+
412
+ console.log('ATK%:', stats.get(Stat.ATKPercent));
413
+ }
414
+
415
+ main().catch(console.error);
416
+ </script>
417
+ </head>
418
+ <body>
419
+ <h1>Aminus Web Example</h1>
420
+ </body>
421
+ </html>
422
+ ```
423
+
424
+ ## Running Tests
425
+
426
+ Run all tests:
427
+ ```bash
428
+ npm test
429
+ ```
430
+
431
+ Run tests in watch mode:
432
+ ```bash
433
+ npm run test:watch
434
+ ```
435
+
436
+ Test files are located in the `tests/` directory.
437
+
438
+ ## Contributing
439
+
440
+ 1. Make changes to the Rust source code in `src/`
441
+ 2. Run `npm run build` to compile WASM
442
+ 3. Add or update tests in `
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "aminus",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "JavaScript/TypeScript bindings for the aminus Genshin Impact calculation library",
5
+ "type": "module",
6
+ "main": "./pkg/aminus_js.js",
7
+ "types": "./pkg/aminus_js.d.ts",
8
+ "files": [
9
+ "pkg/"
10
+ ],
11
+ "scripts": {
12
+ "build": "wasm-pack build --target bundler --out-dir pkg",
13
+ "build:nodejs": "wasm-pack build --target nodejs --out-dir pkg",
14
+ "build:web": "wasm-pack build --target web --out-dir pkg",
15
+ "test": "npm run build:nodejs && jest",
16
+ "test:watch": "jest --watch",
17
+ "dev": "npm run build && npm test",
18
+ "generate-types": "wasm-pack build --target bundler --out-dir pkg",
19
+ "example": "npm run build:nodejs && node --loader ts-node/esm examples/basic-usage.ts",
20
+ "prepublishOnly": "npm run build:nodejs && npm test",
21
+ "prepack": "npm run build:nodejs"
22
+ },
23
+ "devDependencies": {
24
+ "@babel/core": "^7.27.4",
25
+ "@babel/preset-env": "^7.27.2",
26
+ "@types/jest": "^29.5.0",
27
+ "@types/node": "^20.0.0",
28
+ "babel-jest": "^30.0.2",
29
+ "jest": "^29.5.0",
30
+ "jest-environment-node": "^29.5.0",
31
+ "ts-jest": "^29.1.0",
32
+ "ts-node": "^10.9.0",
33
+ "typescript": "^5.0.0"
34
+ },
35
+ "jest": {
36
+ "preset": "ts-jest/presets/default-esm",
37
+ "extensionsToTreatAsEsm": [".ts"],
38
+ "testEnvironment": "node",
39
+ "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json"],
40
+ "testMatch": ["<rootDir>/tests/*.test.{ts,js}"],
41
+ "transform": {
42
+ "^.+\\.(ts|tsx)$": ["ts-jest", {
43
+ "useESM": true
44
+ }]
45
+ },
46
+ "moduleNameMapper": {
47
+ "^(\\.{1,2}/.*)\\.js$": "$1"
48
+ },
49
+ "modulePathIgnorePatterns": ["<rootDir>/pkg/"]
50
+ },
51
+ "keywords": [
52
+ "genshin-impact",
53
+ "calculation",
54
+ "wasm",
55
+ "typescript",
56
+ "javascript",
57
+ "artifact-optimization",
58
+ "damage-calculator"
59
+ ],
60
+ "author": "Lambdev",
61
+ "license": "MIT",
62
+ "repository": {
63
+ "type": "git",
64
+ "url": "https://github.com/your-username/aminus.git",
65
+ "directory": "bindings/js"
66
+ },
67
+ "bugs": {
68
+ "url": "https://github.com/your-username/aminus/issues"
69
+ },
70
+ "homepage": "https://github.com/your-username/aminus#readme",
71
+ "engines": {
72
+ "node": ">=16.0.0"
73
+ },
74
+ "publishConfig": {
75
+ "access": "public"
76
+ }
77
+ }