motely-wasm 18.1.1 → 18.2.2

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 CHANGED
@@ -34,14 +34,11 @@ must:
34
34
  const status = Motely.validateJaml(jaml);
35
35
  if (status !== "valid") throw new Error(status);
36
36
 
37
- // Subscribe to results before starting.
37
+ // One callback set per WASM load — subscribe after boot, before .start().
38
38
  Motely.onScoredResult.subscribe(r => console.log("match:", r.seed, r.score));
39
39
  Motely.onProgress.subscribe(p => console.log(`${p.percentComplete.toFixed(1)}%`));
40
40
 
41
- // Build, start, and await a search.
42
- const search = Motely.createSearch(jaml)
43
- .withSequentialSearch()
44
- .start();
41
+ const search = Motely.fromJaml(jaml).withSequentialSearch().start();
45
42
 
46
43
  await search.waitForCompletionAsync();
47
44
  console.log("done:", search.totalSeedsSearched, "searched,", search.matchingSeeds, "matched");
@@ -182,24 +179,17 @@ returns a human-readable plan; `Motely.createPlan(jaml)` returns the scoring str
182
179
 
183
180
  ## Running a search
184
181
 
185
- `Motely.createSearch(jaml)` returns a settings builder. Chain a search-mode method,
186
- then call `.start()` to get a running `IMotelySearch`.
182
+ Use `Motely.createSearchSettings()`, `Motely.createNativeSearchSettings(name)`, or
183
+ `Motely.fromJaml(jaml)` then chain modes. Callbacks are registered once per WASM load on `Motely`.
187
184
 
188
185
  ```js
189
186
  import { Motely } from "motely-wasm";
190
187
 
191
- Motely.onSeedMatch.subscribe(seed => { /* matching seed string */ });
192
- Motely.onScoredResult.subscribe(r => { /* r.seed, r.score, r.tallies */ });
193
- Motely.onProgress.subscribe(p => { /* p.percentComplete, p.seedsSearched, p.seedsPerMillisecond, … */ });
188
+ Motely.onSeedMatch.subscribe(seed => { /* */ });
189
+ Motely.onScoredResult.subscribe(r => { /* */ });
190
+ Motely.onProgress.subscribe(p => { /* … */ });
194
191
 
195
- const settings = Motely.createSearch(jaml)
196
- .withSequentialSearch() // enumerate all seeds in order
197
- // .withRandomSearch(10_000) // or pick N random seeds
198
- // .withListSearch(seeds, seeds.length) // or supply a seed list
199
- // .withAestheticSearch(0) // or a JamlAesthetic mode
200
- .withProgressReportIntervalMs(500n);
201
-
202
- const search = settings.start();
192
+ const search = Motely.fromJaml(jaml).withSequentialSearch().start();
203
193
 
204
194
  // Async (yields between batches — good on the main thread or in a Worker)
205
195
  await search.waitForCompletionAsync();
@@ -211,48 +201,52 @@ console.log(search.isCompleted, search.totalSeedsSearched, search.matchingSeeds)
211
201
  search.cancel(); // stop early
212
202
  ```
213
203
 
214
- ## Stream pagers
204
+ ## Stream cursor
215
205
 
216
- Pagers expose Balatro's raw PRNG streams one packed int per item, no JAML filter needed.
217
- **Always prefer `getNextChunk(n)` over repeated `getNext()` calls** each call is a WASM
218
- interop crossing, so batching is the right default:
206
+ `Motely.createStreamCursor(seed, deck, stake, ante, kind)` returns a stateful cursor over
207
+ one of Balatro's per-ante PRNG streamsone packed int per item, no JAML filter needed.
208
+ The `kind` argument selects which stream; one factory + one enum arg covers every stream
209
+ type:
219
210
 
220
211
  ```js
221
- import { Motely, MotelyDeck, MotelyStake } from "motely-wasm";
212
+ import { Motely } from "motely-wasm";
213
+ import { MotelyStreamKind } from "motely-wasm/motely";
214
+ import { MotelyDeck, MotelyStake } from "motely-wasm/motely/enums";
222
215
 
223
- const pager = Motely.createShopPager("AAAAAAAA", MotelyDeck.Red, MotelyStake.White, 1);
224
- const items = pager.getNextChunk(6); // 6 packed ints, one crossing
216
+ const cursor = Motely.createStreamCursor("AAAAAAAA", MotelyDeck.Red, MotelyStake.White, 1, MotelyStreamKind.Shop);
217
+ const items = cursor.getNextChunk(6); // 6 packed ints, one WASM crossing
225
218
  ```
226
219
 
227
- Each factory targets a distinct PRNG streamthese are not the same stream filtered, so there
228
- is one factory per stream type:
220
+ **Always prefer `getNextChunk(n)` over repeated `getNext()` calls**each call is a WASM
221
+ interop crossing, so batching is the right default.
229
222
 
230
- | Factory | Stream |
231
- |---|---|
232
- | `createShopPager(seed, deck, stake, ante)` | Mixed shop (jokers, tarots, planets, spectrals on Ghost, standard cards with MagicTrick) |
233
- | `createJokerPager(seed, deck, stake, ante)` | Shop jokers — includes edition + sticker bits |
234
- | `createTarotPager(seed, deck, stake, ante)` | Shop tarots |
235
- | `createPlanetPager(seed, deck, stake, ante)` | Shop planets |
236
- | `createSpectralPager(seed, deck, stake, ante)` | Shop spectrals (non-Ghost returns `SpectralExcludedByStream`) |
237
- | `createLegendaryJokerPager(seed, deck, stake, ante)` | Legendary fixed-rarity joker stream |
238
- | `createRareTagJokerPager(seed, deck, stake, ante)` | Rare Tag hand-out joker stream |
239
- | `createTagPager(seed, deck, stake, ante)` | Tags — value is `MotelyTag` cast to int |
240
- | `createVoucherPager(seed, deck, stake, ante)` | Vouchers — value is `MotelyVoucher` cast to int |
223
+ | `MotelyStreamKind` value | Stream | Returned int |
224
+ |---|---|---|
225
+ | `Shop` | Mixed shop (jokers, tarots, planets, spectrals on Ghost, standard cards with MagicTrick) | Packed item (`decodeItemType`, `decodeItemCategory`, …) |
226
+ | `Joker` | Shop jokers — includes edition + sticker bits | Packed item |
227
+ | `Tarot` | Shop tarots | Packed item |
228
+ | `Planet` | Shop planets | Packed item |
229
+ | `Spectral` | Shop spectrals (non-Ghost returns `SpectralExcludedByStream`) | Packed item |
230
+ | `LegendaryJoker` | Legendary fixed-rarity joker stream | Packed item |
231
+ | `RareTagJoker` | Rare Tag hand-out joker stream | Packed item |
232
+ | `Tag` | Tags — raw `MotelyTag` enum cast to int. Decoders do not apply; use `MotelyTag[value]`. | `(int)MotelyTag` |
233
+ | `Voucher` | Vouchers — raw `MotelyVoucher` enum cast to int. Uses an empty run state, so odd-indexed (prerequisite-required) vouchers are skipped by the engine. Use `MotelyVoucher[value]`. | `(int)MotelyVoucher` |
241
234
 
242
235
  ## Packed-int decoders
243
236
 
244
- All pager streams return packed integers. Bit fields are extracted with the decode helpers
245
- exported from the entry point:
237
+ Stream cursors return packed integers. Bit fields are extracted with the decode helpers
238
+ on `Motely`:
246
239
 
247
240
  ```js
241
+ import { Motely } from "motely-wasm";
242
+ import { MotelyStreamKind } from "motely-wasm/motely";
248
243
  import {
249
- Motely,
250
244
  MotelyItemType, MotelyItemTypeCategory, MotelyJokerRarity,
251
245
  MotelyItemEdition, MotelyItemSeal, MotelyItemEnhancement,
252
- } from "motely-wasm";
246
+ } from "motely-wasm/motely/enums";
253
247
 
254
- const pager = Motely.createJokerPager("AAAAAAAA", 0, 0, 1);
255
- const v = pager.getNext();
248
+ const cursor = Motely.createStreamCursor("AAAAAAAA", 0, 0, 1, MotelyStreamKind.Joker);
249
+ const v = cursor.getNext();
256
250
 
257
251
  const type = Motely.decodeItemType(v); // → MotelyItemType value
258
252
  const category = Motely.decodeItemCategory(v); // → MotelyItemTypeCategory value
@@ -271,11 +265,16 @@ console.log(MotelyJokerRarity[rarity]); // e.g. "Common"
271
265
 
272
266
  All enum tables (`MotelyItemType`, `MotelyItemTypeCategory`, `MotelyJokerRarity`,
273
267
  `MotelyItemEdition`, `MotelyItemSeal`, `MotelyItemEnhancement`, `MotelyTag`,
274
- `MotelyVoucher`, `MotelyBoosterPack`, `MotelyDeck`, `MotelyStake`) are exported from
275
- `motely-wasm` and can be used for reverse-lookup by numeric value or forward-lookup by name.
268
+ `MotelyVoucher`, `MotelyBoosterPack`, `MotelyDeck`, `MotelyStake`) live at
269
+ `motely-wasm/motely/enums` and can be used for reverse-lookup by numeric value or
270
+ forward-lookup by name. `MotelyStreamKind` lives at `motely-wasm/motely`.
276
271
 
277
272
  ## Events
278
273
 
274
+ Callbacks are registered on `Motely` once per `bootsharp.boot()` — not on each settings
275
+ chain. Every search started from that WASM load shares the same handlers; run one search at
276
+ a time or use separate worker boots if you need isolated callbacks.
277
+
279
278
  | Event | Payload |
280
279
  |---|---|
281
280
  | `Motely.onSeedMatch` | `string` — matching seed |
@@ -296,7 +295,8 @@ Motely.onScoredResult.unsubscribe(handler);
296
295
  | Import path | Contents |
297
296
  |---|---|
298
297
  | `motely-wasm` | Default export: `boot`, `getStatus`, `BootStatus`. Named export: `Motely` (main API) |
299
- | `motely-wasm/motely` | Types: `IMotelySearch`, `IMotelySearchSettingsInterop`, `MotelyProgress`, `MotelyScoredSeedResult`, `MotelyDeck`, `MotelyStake`, enums |
298
+ | `motely-wasm/motely` | `IMotelySearch`, `SearchSettings`, `IMotelyStreamCursor`, `MotelyProgress`, `MotelyScoredSeedResult`, `MotelyStreamKind` |
299
+ | `motely-wasm/motely/enums` | All Balatro enums — `MotelyItemType`, `MotelyItemTypeCategory`, `MotelyJokerRarity`, `MotelyItemEdition`, `MotelyItemSeal`, `MotelyItemEnhancement`, `MotelyTag`, `MotelyVoucher`, `MotelyBoosterPack`, `MotelyDeck`, `MotelyStake`, `MotelyBossBlind`, etc. |
300
300
  | `motely-wasm/motely/filters` | `JamlAesthetic`, `JamlSearchPlan` |
301
301
  | `motely-wasm/motely/analysis` | `MotelyJamlyzerResult`, `MotelySeedAnalysis` |
302
302
  | `motely-wasm/bootsharp/file-system` | File-system interop (browser OPFS) — `PermissionMode`, `IFileMounter` |
Binary file