motely-wasm 19.4.0 → 20.0.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.
- package/README.md +73 -146
- package/dist/bin/motely-wasm.wasm +0 -0
- package/dist/dotnet/dotnet.native.js +1 -1
- package/dist/generated/instances.g.mjs +0 -52
- package/dist/generated/modules/motely/analysis.g.d.mts +20 -30
- package/dist/generated/modules/motely/filters/jaml.g.d.mts +10 -0
- package/dist/generated/modules/motely/wasm.g.d.mts +3 -5
- package/dist/generated/modules/motely/wasm.g.mjs +6 -6
- package/dist/generated/modules/motely.g.d.mts +9 -103
- package/dist/generated/modules/motely.g.mjs +17 -98
- package/dist/generated/serializer.g.mjs +73 -188
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# motely-wasm
|
|
2
2
|
|
|
3
|
-
Balatro seed
|
|
3
|
+
WebAssembly build of [MotelyJAML](https://github.com/OptimusPi/MotelyJAML) — the SIMD Balatro seed search engine with JAML filter support. Powers [seedfinder.app](https://seedfinder.app).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,192 +8,119 @@ Balatro seed finder and per-seed analyzer, compiled to WebAssembly via [Bootshar
|
|
|
8
8
|
npm install motely-wasm
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
## Module layout
|
|
12
|
-
|
|
13
|
-
The root barrel (`motely-wasm`) re-exports only the Bootsharp runtime (`boot`, `getStatus`, `manifest`, …). The Motely API and enums live in generated submodules and **must be imported directly** via the package's subpath exports:
|
|
14
|
-
|
|
15
|
-
```js
|
|
16
|
-
import bootsharp from "motely-wasm";
|
|
17
|
-
import { Program as Motely } from "motely-wasm/motely/wasm";
|
|
18
|
-
import * as enums from "motely-wasm/motely/enums";
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Additional submodules: `motely-wasm/motely/analysis`, `motely-wasm/motely/filters/jaml`, `motely-wasm/motely/filters`.
|
|
22
|
-
|
|
23
11
|
## Boot
|
|
24
12
|
|
|
25
|
-
|
|
13
|
+
The WASM binary is **sideloaded** — a separate `dist/bin/motely-wasm.wasm`, **not** base64-embedded — so `boot()` **must** be told where to find it. A no-arg `boot()` will not load the runtime and every search silently does nothing.
|
|
26
14
|
|
|
27
|
-
|
|
15
|
+
In Node, read the bytes and pass them directly (`fetch` can't read `file://` URLs):
|
|
28
16
|
|
|
29
17
|
```js
|
|
30
18
|
import { readFile } from "node:fs/promises";
|
|
31
|
-
import {
|
|
19
|
+
import { dirname, resolve } from "node:path";
|
|
32
20
|
import { fileURLToPath } from "node:url";
|
|
33
21
|
import bootsharp from "motely-wasm";
|
|
34
|
-
import { Program as Motely } from "motely-wasm/motely/wasm";
|
|
35
|
-
import * as enums from "motely-wasm/motely/enums";
|
|
36
|
-
|
|
37
|
-
// [Import] callbacks must be assigned BEFORE boot.
|
|
38
|
-
Motely.reportWasmError = (message) => console.error("[WASM ERROR]", message);
|
|
39
|
-
Motely.jimmolateProbe = () => false; // required even when not using Jimmolate
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const wasm = await readFile(resolve(distDir, "bin", bootsharp.manifest.wasm));
|
|
23
|
+
const dist = resolve(dirname(fileURLToPath(import.meta.url)), "node_modules/motely-wasm/dist");
|
|
24
|
+
const wasm = await readFile(resolve(dist, "bin", bootsharp.manifest.wasm));
|
|
44
25
|
await bootsharp.boot({ wasm });
|
|
45
26
|
```
|
|
46
27
|
|
|
47
|
-
|
|
28
|
+
In the browser, pass the root URL your host serves `dist/` at:
|
|
48
29
|
|
|
49
30
|
```js
|
|
50
|
-
|
|
51
|
-
import { Program as Motely } from "motely-wasm/motely/wasm";
|
|
52
|
-
|
|
53
|
-
Motely.reportWasmError = (message) => console.error("[WASM ERROR]", message);
|
|
54
|
-
Motely.jimmolateProbe = () => false;
|
|
55
|
-
|
|
56
|
-
// Pass the URL root where dist/bin/ is served.
|
|
57
|
-
await bootsharp.boot("/assets/motely-wasm/dist/bin");
|
|
31
|
+
await bootsharp.boot("/motely-wasm/dist");
|
|
58
32
|
```
|
|
59
33
|
|
|
60
|
-
|
|
34
|
+
Guard re-boots with `bootsharp.getStatus() === bootsharp.BootStatus.Standby`.
|
|
61
35
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
### Parse a JAML filter
|
|
36
|
+
## Imports
|
|
65
37
|
|
|
66
38
|
```js
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
deck: Red
|
|
70
|
-
stake: White
|
|
71
|
-
must:
|
|
72
|
-
- joker: Triboulet
|
|
73
|
-
antes: [1, 2, 3]
|
|
74
|
-
`);
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
`parseJaml` throws on invalid YAML. Use `jamlToJson` / `jsonToJaml` to convert between representations. Use `explainJaml` to get a human-readable summary of a parsed config.
|
|
39
|
+
// Main API — the C# Program class, renamed to Motely
|
|
40
|
+
import { Program as Motely } from "motely-wasm/dist/generated/modules/motely/wasm.g.mjs";
|
|
78
41
|
|
|
79
|
-
|
|
42
|
+
// Enums — MotelyDeck, MotelyStake, etc.
|
|
43
|
+
import * as enums from "motely-wasm/dist/generated/modules/motely/enums.g.mjs";
|
|
80
44
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```js
|
|
84
|
-
// Subscribe to results before starting.
|
|
85
|
-
Motely.onSeedMatch.subscribe((seed) => console.log("match:", seed));
|
|
86
|
-
Motely.onProgress.subscribe((p) => console.log(`${p.percentComplete.toFixed(1)}%`));
|
|
87
|
-
|
|
88
|
-
// Sequential: scan all seeds in batch range [0, 1).
|
|
89
|
-
const search = Motely.runSequentialSearch(cfg, 0n, 1n);
|
|
90
|
-
await search.runSearchAsync();
|
|
91
|
-
|
|
92
|
-
// List: check specific seeds.
|
|
93
|
-
cfg.seeds = ["PIFREAK1", "DEADBEEF"];
|
|
94
|
-
const listSearch = Motely.runSeedListSearch(cfg);
|
|
95
|
-
listSearch.runSearchUntilCompletion();
|
|
96
|
-
console.log(listSearch.matchingSeeds); // bigint
|
|
97
|
-
|
|
98
|
-
// Scored: emits onScoredResult instead of onSeedMatch.
|
|
99
|
-
Motely.onScoredResult.subscribe((r) => console.log(r.seed, r.score));
|
|
100
|
-
const scored = Motely.runSequentialSearch(cfg, 0n, 1n);
|
|
101
|
-
await scored.runSearchAsync();
|
|
45
|
+
// Types — MotelyProgress, IMotelySearch, MotelyScoredSeedResult, etc.
|
|
46
|
+
import * as types from "motely-wasm/dist/generated/modules/motely.g.mjs";
|
|
102
47
|
```
|
|
103
48
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
`jamlyzer` runs the JAMLyzer on all seeds in `cfg.seeds` and returns per-ante detail: boss blind, voucher, tags, shop queue, booster packs.
|
|
49
|
+
## Quick start
|
|
107
50
|
|
|
108
51
|
```js
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
52
|
+
// Optional [Import] hook — surface WASM-side errors. Bind BEFORE boot:
|
|
53
|
+
// Bootsharp snapshots [Import] bindings at boot().
|
|
54
|
+
Motely.reportWasmError = (msg) => console.error("[WASM]", msg);
|
|
55
|
+
|
|
56
|
+
// Subscribe to events
|
|
57
|
+
Motely.onSeedMatch.subscribe(seed => console.log("match:", seed));
|
|
58
|
+
Motely.onProgress.subscribe(p => console.log(`${p.percentComplete.toFixed(1)}%`));
|
|
59
|
+
|
|
60
|
+
// Parse a JAML filter. JAML is YAML, and YAML is a JSON superset — a JSON
|
|
61
|
+
// object string parses too, which is what makes it round-trip cleanly over MCP.
|
|
62
|
+
const config = Motely.parseJaml(`
|
|
63
|
+
name: WeeMonday
|
|
64
|
+
deck: Erratic
|
|
65
|
+
stake: Black
|
|
66
|
+
must:
|
|
67
|
+
- joker: WeeJoker
|
|
68
|
+
antes: [1]
|
|
69
|
+
`);
|
|
120
70
|
|
|
121
|
-
|
|
71
|
+
// Run a search (blocks until complete — run in a Worker for non-blocking UI).
|
|
72
|
+
const search = Motely.runSequentialSearch(config);
|
|
73
|
+
console.log(search.matchingSeeds, "matches out of", search.totalSeedsSearched);
|
|
74
|
+
```
|
|
122
75
|
|
|
123
|
-
|
|
76
|
+
## API
|
|
124
77
|
|
|
125
78
|
```js
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
79
|
+
Motely.parseJaml(jaml) // string → JamlConfig (throws on invalid JAML)
|
|
80
|
+
Motely.explainJaml(config) // human-readable plan summary
|
|
81
|
+
Motely.createPlan(config) // JamlSearchPlan (tally columns, CSV header)
|
|
82
|
+
Motely.jamlToJson(jaml) // JAML string → JSON string
|
|
83
|
+
Motely.jsonToJaml(json) // JSON string → JAML string
|
|
84
|
+
Motely.jamlyzer(seed, lens) // analyze ONE seed through a JamlConfig lens → JamlyzerSnapshot
|
|
85
|
+
Motely.nativeFilterNames() // built-in native filter names
|
|
86
|
+
|
|
87
|
+
Motely.runSequentialSearch(config, ...) // sequential seed search
|
|
88
|
+
Motely.runRandomSearch(config, count) // random seed sample
|
|
89
|
+
Motely.runSeedListSearch(config) // search only config.seeds
|
|
90
|
+
Motely.runAestheticSearch(config, aesthetic) // aesthetic / scored search
|
|
91
|
+
Motely.runNativeListSearch(name, seeds) // named native filter over a seed list
|
|
92
|
+
Motely.runPassthroughListSearch(seeds) // no filter, just iterate seeds
|
|
129
93
|
```
|
|
130
94
|
|
|
131
|
-
##
|
|
132
|
-
|
|
133
|
-
Jimmolate is a custom JS scalar predicate that runs on every seed that passes the base JAML filter. Wire it up and call `enableJimmolate()` after boot:
|
|
95
|
+
## Events
|
|
134
96
|
|
|
135
97
|
```js
|
|
136
|
-
//
|
|
137
|
-
Motely.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
await bootsharp.boot({ wasm });
|
|
143
|
-
Motely.enableJimmolate();
|
|
144
|
-
|
|
145
|
-
cfg.seeds = ["PIFREAK1", "XYZABCDE"];
|
|
146
|
-
Motely.onSeedMatch.subscribe((s) => console.log("jimmolate match:", s));
|
|
147
|
-
Motely.runPassthroughListSearch(cfg.seeds).runSearchUntilCompletion();
|
|
98
|
+
Motely.onSeedMatch.subscribe(seed => {}) // string — each matching seed
|
|
99
|
+
Motely.onScoredResult.subscribe(result => {}) // MotelyScoredSeedResult { seed, score, tallies }
|
|
100
|
+
Motely.onProgress.subscribe(p => {}) // MotelyProgress
|
|
101
|
+
Motely.onFileChanges.subscribe(changes => {}) // file system changes (browser OPFS)
|
|
148
102
|
```
|
|
149
103
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
## JAML quick reference
|
|
104
|
+
## File system (browser)
|
|
153
105
|
|
|
154
|
-
|
|
155
|
-
name: string # optional display name
|
|
156
|
-
deck: Red # MotelyDeck value (case-insensitive)
|
|
157
|
-
stake: White # MotelyStake value
|
|
158
|
-
seeds: [] # pre-populate for list searches
|
|
106
|
+
`Motely.pickRoot`, `mountRoot`, `unmountRoot`, `readTextFile`, `writeTextFile` use the browser File System Access API via `Bootsharp.FileSystem`. Initialize the JS extension before booting:
|
|
159
107
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
min: 1 # default 1
|
|
164
|
-
max: 2 # optional upper bound
|
|
165
|
-
|
|
166
|
-
should: # scoring; doesn't filter, raises score
|
|
167
|
-
- voucher: Telescope
|
|
168
|
-
antes: [1, 2]
|
|
169
|
-
score: 10
|
|
108
|
+
```js
|
|
109
|
+
import * as fs from "@rewaffle/bootsharp-file-system";
|
|
110
|
+
import { Bootsharp } from "motely-wasm/dist/generated/modules/bootsharp/file-system.g.mjs";
|
|
170
111
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
antes: [1]
|
|
112
|
+
fs.init(Bootsharp.FileSystem.FileMounter);
|
|
113
|
+
await bootsharp.boot("/motely-wasm/dist");
|
|
174
114
|
```
|
|
175
115
|
|
|
176
|
-
|
|
177
|
-
Sources can be narrowed via `sources: { shopItems: [0, 1], boosterPacks: [0] }`.
|
|
178
|
-
|
|
179
|
-
## Enums
|
|
180
|
-
|
|
181
|
-
All enum values are available in the `enums` module:
|
|
182
|
-
|
|
183
|
-
- `MotelyDeck` — Red, Blue, Yellow, Green, Black, Magic, Nebula, Ghost, Abandoned, Checkered, Zodiac, Painted, Anaglyph, Plasma, Erratic
|
|
184
|
-
- `MotelyStake` — White, Red, Green, Black, Blue, Purple, Orange, Gold
|
|
185
|
-
- `MotelyBossBlind`, `MotelyVoucher`, `MotelyTag`, `MotelyBoosterPack`
|
|
116
|
+
## Jimmolate
|
|
186
117
|
|
|
187
|
-
|
|
118
|
+
Scalar predicate filtering after the base SIMD pass. Bind the predicate **before** boot (Bootsharp snapshots `[Import]` bindings at boot), then enable it:
|
|
188
119
|
|
|
189
120
|
```js
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const explanation = Motely.explainJaml(cfg);
|
|
196
|
-
|
|
197
|
-
// List available native (non-JAML) filter names.
|
|
198
|
-
const names = Motely.nativeFilterNames();
|
|
121
|
+
Motely.jimmolatePredicate = (result) => {
|
|
122
|
+
// result is MotelyScoredSeedResult — { seed, score, tallies }
|
|
123
|
+
return result.score > 0; // return true to keep the seed
|
|
124
|
+
};
|
|
125
|
+
Motely.jimmolateEnabled = true;
|
|
199
126
|
```
|
|
Binary file
|