motely-wasm 19.1.1 → 19.4.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 +134 -199
- package/dist/bcl/cancellation.d.mts +4 -7
- package/dist/bcl/cancellation.mjs +5 -10
- package/dist/bcl/collection.d.mts +1 -4
- package/dist/bcl/collection.mjs +1 -4
- package/dist/bcl/dictionary.d.mts +25 -0
- package/dist/bcl/dictionary.mjs +47 -0
- package/dist/bcl/event.d.mts +1 -1
- package/dist/bcl/event.mjs +1 -1
- package/dist/bcl/index.d.mts +1 -0
- package/dist/bcl/index.mjs +1 -0
- package/dist/bcl/list.d.mts +5 -8
- package/dist/bcl/list.mjs +9 -12
- package/dist/bin/motely-wasm.wasm +0 -0
- package/dist/dotnet/dotnet.native.js +1 -1
- package/dist/generated/imports.g.mjs +12 -2
- package/dist/generated/instances.g.mjs +111 -847
- package/dist/generated/modules/index.g.d.mts +1 -1222
- package/dist/generated/modules/index.g.mjs +1 -1975
- package/dist/generated/modules/motely/analysis.g.d.mts +49 -0
- package/dist/generated/modules/motely/analysis.g.mjs +6 -0
- package/dist/generated/modules/motely/enums.g.d.mts +136 -0
- package/dist/generated/modules/motely/enums.g.mjs +262 -0
- package/dist/generated/modules/motely/filters/jaml.g.d.mts +30 -0
- package/dist/generated/modules/motely/filters/jaml.g.mjs +48 -0
- package/dist/generated/modules/motely/filters.g.d.mts +8 -0
- package/dist/generated/modules/motely/filters.g.mjs +6 -0
- package/dist/generated/modules/motely/wasm.g.d.mts +36 -0
- package/dist/generated/modules/motely/wasm.g.mjs +42 -0
- package/dist/generated/modules/motely.g.d.mts +141 -0
- package/dist/generated/modules/motely.g.mjs +139 -0
- package/dist/generated/resources.g.mjs +1 -15
- package/dist/generated/serializer.g.mjs +0 -270
- package/package.json +10 -13
- package/motely-item-formats.d.ts +0 -535
- package/motely-item-formats.mjs +0 -525
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# motely-wasm
|
|
2
2
|
|
|
3
|
-
WebAssembly
|
|
4
|
-
|
|
5
|
-
The package ships `jaml.schema.json` (JSON Schema for the JAML filter format) at the package root, so editors can wire it up for autocomplete / validation without an extra fetch.
|
|
3
|
+
Balatro seed finder and per-seed analyzer, compiled to WebAssembly via [Bootsharp](https://bootsharp.com). Runs in browsers and Node/Deno/Bun.
|
|
6
4
|
|
|
7
5
|
## Install
|
|
8
6
|
|
|
@@ -10,255 +8,192 @@ The package ships `jaml.schema.json` (JSON Schema for the JAML filter format) at
|
|
|
10
8
|
npm install motely-wasm
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
##
|
|
11
|
+
## Module layout
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
import bootsharp, { Motely } from "motely-wasm";
|
|
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:
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
+
```
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
const jaml = `
|
|
24
|
-
name: WeeMonday
|
|
25
|
-
deck: Erratic
|
|
26
|
-
stake: Black
|
|
27
|
-
must:
|
|
28
|
-
- joker: WeeJoker
|
|
29
|
-
antes: [1]
|
|
30
|
-
`;
|
|
21
|
+
Additional submodules: `motely-wasm/motely/analysis`, `motely-wasm/motely/filters/jaml`, `motely-wasm/motely/filters`.
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
const status = Motely.validateJaml(jaml);
|
|
34
|
-
if (status !== "valid") throw new Error(status);
|
|
23
|
+
## Boot
|
|
35
24
|
|
|
36
|
-
|
|
37
|
-
Motely.onScoredResult.subscribe(r => console.log("match:", r.seed, r.score));
|
|
38
|
-
Motely.onProgress.subscribe(p => console.log(`${p.percentComplete.toFixed(1)}%`));
|
|
25
|
+
Binaries are sideloaded (published to `dist/bin/` as separate files). Pass the wasm bytes directly — `boot()` accepts either raw bytes or a URL root.
|
|
39
26
|
|
|
40
|
-
|
|
27
|
+
### Node
|
|
41
28
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
```js
|
|
30
|
+
import { readFile } from "node:fs/promises";
|
|
31
|
+
import { resolve, dirname } from "node:path";
|
|
32
|
+
import { fileURLToPath } from "node:url";
|
|
33
|
+
import bootsharp from "motely-wasm";
|
|
34
|
+
import { Program as Motely } from "motely-wasm/motely/wasm";
|
|
35
|
+
import * as enums from "motely-wasm/motely/enums";
|
|
45
36
|
|
|
46
|
-
|
|
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
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
// import.meta.resolve("motely-wasm") → <pkg>/dist/index.mjs; dirname is already <pkg>/dist.
|
|
42
|
+
const distDir = dirname(fileURLToPath(import.meta.resolve("motely-wasm")));
|
|
43
|
+
const wasm = await readFile(resolve(distDir, "bin", bootsharp.manifest.wasm));
|
|
44
|
+
await bootsharp.boot({ wasm });
|
|
45
|
+
```
|
|
49
46
|
|
|
50
|
-
|
|
47
|
+
### Browser
|
|
51
48
|
|
|
52
49
|
```js
|
|
53
50
|
import bootsharp from "motely-wasm";
|
|
51
|
+
import { Program as Motely } from "motely-wasm/motely/wasm";
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
53
|
+
Motely.reportWasmError = (message) => console.error("[WASM ERROR]", message);
|
|
54
|
+
Motely.jimmolateProbe = () => false;
|
|
58
55
|
|
|
59
|
-
|
|
56
|
+
// Pass the URL root where dist/bin/ is served.
|
|
57
|
+
await bootsharp.boot("/assets/motely-wasm/dist/bin");
|
|
60
58
|
```
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
`node Motely.Wasm/motely.test.mjs` and `node Motely.Wasm/pack-consumer-smoke.mjs`.
|
|
60
|
+
## Core API
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
All methods are on the `Motely` (i.e. `Program`) namespace.
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
import { Motely } from "motely-wasm";
|
|
64
|
+
### Parse a JAML filter
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
const
|
|
66
|
+
```js
|
|
67
|
+
const cfg = Motely.parseJaml(`
|
|
68
|
+
name: My Filter
|
|
69
|
+
deck: Red
|
|
70
|
+
stake: White
|
|
71
|
+
must:
|
|
72
|
+
- joker: Triboulet
|
|
73
|
+
antes: [1, 2, 3]
|
|
74
|
+
`);
|
|
75
|
+
```
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
const explanation = Motely.explainJaml(jaml);
|
|
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.
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
const plan = Motely.createPlan(jaml);
|
|
79
|
+
### Search
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
const result = Motely.analyzeJamlSeeds(jaml, ["ABCD1234", "XYZ99"]);
|
|
81
|
+
All `run*Search` methods return an `IMotelySearch` — call `.start()` then listen to events, or call `.runSearchUntilCompletion()` / `await .runSearchAsync()` for synchronous / async use.
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
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();
|
|
84
102
|
```
|
|
85
103
|
|
|
86
|
-
|
|
104
|
+
### Analyze a seed
|
|
87
105
|
|
|
88
|
-
`
|
|
89
|
-
autocomplete and inline validation while writing filters:
|
|
106
|
+
`jamlyzer` runs the JAMLyzer on all seeds in `cfg.seeds` and returns per-ante detail: boss blind, voucher, tags, shop queue, booster packs.
|
|
90
107
|
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
```js
|
|
109
|
+
cfg.seeds = ["PIFREAK1"];
|
|
110
|
+
const result = Motely.jamlyzer(cfg);
|
|
111
|
+
for (const { seed, analysis } of result.seeds) {
|
|
112
|
+
for (const ante of analysis.antes) {
|
|
113
|
+
console.log(`ante ${ante.ante} boss: ${enums.MotelyBossBlind[ante.boss]}`);
|
|
114
|
+
for (const { item, matched } of ante.shopQueue) {
|
|
115
|
+
console.log(" shop item", item.value, matched ? "(matched)" : "");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
94
118
|
}
|
|
95
119
|
```
|
|
96
120
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```yaml
|
|
100
|
-
# yaml-language-server: $schema=node_modules/motely-wasm/jaml.schema.json
|
|
101
|
-
name: WeeMonday
|
|
102
|
-
deck: Erratic
|
|
103
|
-
stake: Black
|
|
104
|
-
must:
|
|
105
|
-
- joker: WeeJoker
|
|
106
|
-
antes: [1]
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
JAML is a YAML dialect (JSON-compatible). A filter is a flat document:
|
|
110
|
-
|
|
111
|
-
| Key | Purpose | Example |
|
|
112
|
-
|---|---|---|
|
|
113
|
-
| `name` | Human label | `WeeMonday` |
|
|
114
|
-
| `deck` | Starting deck | `Erratic`, `Red`, `Ghost`, … |
|
|
115
|
-
| `stake` | Difficulty floor | `White`, `Black`, `Gold`, … |
|
|
116
|
-
| `must` | All clauses must match | list of clause objects |
|
|
117
|
-
| `mustNot` | All clauses must NOT match | list of clause objects |
|
|
118
|
-
| `should` | Scored clauses (use with `score:`) | list of clause objects |
|
|
121
|
+
### Seed context (low-level)
|
|
119
122
|
|
|
120
|
-
|
|
121
|
-
optional filters (`antes`, `sources`, `min`, `score`):
|
|
123
|
+
For custom logic, get a `MotelySingleSearchContext` and query PRNG streams directly:
|
|
122
124
|
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
sources:
|
|
128
|
-
shopItems: [0, 1] # shop slot indices
|
|
129
|
-
boosterPacks: [0] # pack slot indices
|
|
130
|
-
- tag: NegativeTag
|
|
131
|
-
antes: [1]
|
|
132
|
-
- voucher: Telescope
|
|
133
|
-
antes: [1, 2]
|
|
134
|
-
min: 2 # appear at least N times across all listed antes
|
|
125
|
+
```js
|
|
126
|
+
const ctx = Motely.seedContext("PIFREAK1", enums.MotelyDeck.Red, enums.MotelyStake.White);
|
|
127
|
+
const voucher = ctx.getAnteFirstVoucher(1);
|
|
128
|
+
console.log("ante 1 voucher:", enums.MotelyVoucher[voucher]);
|
|
135
129
|
```
|
|
136
130
|
|
|
137
|
-
|
|
138
|
-
returns a human-readable plan; `Motely.createPlan(jaml)` returns the scoring structure.
|
|
139
|
-
|
|
140
|
-
## Running a search
|
|
131
|
+
## Jimmolate
|
|
141
132
|
|
|
142
|
-
|
|
143
|
-
`Motely.fromJaml(jaml)` — then chain modes. Callbacks are registered once per WASM load on `Motely`.
|
|
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:
|
|
144
134
|
|
|
145
135
|
```js
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const search = Motely.fromJaml(jaml).withSequentialSearch().start();
|
|
153
|
-
|
|
154
|
-
// Async (yields between batches — good on the main thread or in a Worker)
|
|
155
|
-
await search.waitForCompletionAsync();
|
|
136
|
+
// Must be set BEFORE boot.
|
|
137
|
+
Motely.jimmolateProbe = (ctx) => {
|
|
138
|
+
// ctx is MotelySingleSearchContext — same API as seedContext().
|
|
139
|
+
return ctx.getSeed().startsWith("PI");
|
|
140
|
+
};
|
|
156
141
|
|
|
157
|
-
|
|
158
|
-
|
|
142
|
+
await bootsharp.boot({ wasm });
|
|
143
|
+
Motely.enableJimmolate();
|
|
159
144
|
|
|
160
|
-
|
|
161
|
-
|
|
145
|
+
cfg.seeds = ["PIFREAK1", "XYZABCDE"];
|
|
146
|
+
Motely.onSeedMatch.subscribe((s) => console.log("jimmolate match:", s));
|
|
147
|
+
Motely.runPassthroughListSearch(cfg.seeds).runSearchUntilCompletion();
|
|
162
148
|
```
|
|
163
149
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
Callbacks are registered on `Motely` once per `bootsharp.boot()` — not on each settings
|
|
167
|
-
chain. Every search started from that WASM load shares the same handlers; run one search at
|
|
168
|
-
a time or use separate worker boots if you need isolated callbacks.
|
|
150
|
+
Use `runPassthroughListSearch` to skip the JAML filter entirely and let Jimmolate do all the culling.
|
|
169
151
|
|
|
170
|
-
|
|
171
|
-
|---|---|
|
|
172
|
-
| `Motely.onSeedMatch` | `string` — matching seed |
|
|
173
|
-
| `Motely.onScoredResult` | `{ seed, score, tallies }` |
|
|
174
|
-
| `Motely.onProgress` | `MotelyProgress` — `percentComplete`, `seedsSearched`, `matchingSeeds`, `seedsPerMillisecond`, `elapsedMilliseconds` |
|
|
175
|
-
| `Motely.onFileChanges` | `Change[]` — fires when files change under a directory mounted via `Motely.mountRoot` (browser File System Access API, requires `Bootsharp.FileSystem`). Ignore if your app doesn't mount local directories. |
|
|
152
|
+
## JAML quick reference
|
|
176
153
|
|
|
177
|
-
|
|
154
|
+
```yaml
|
|
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
|
|
159
|
+
|
|
160
|
+
must: # all clauses must match
|
|
161
|
+
- joker: Triboulet
|
|
162
|
+
antes: [1, 2] # ante numbers (1–8)
|
|
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
|
|
178
170
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
Motely.onScoredResult.unsubscribe(handler);
|
|
171
|
+
mustNot: # any match rejects the seed
|
|
172
|
+
- boss: TheHook
|
|
173
|
+
antes: [1]
|
|
183
174
|
```
|
|
184
175
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
| Import path | Contents |
|
|
188
|
-
|---|---|
|
|
189
|
-
| `motely-wasm` | Default export: `boot`, `getStatus`, `BootStatus`. Named export: `Motely` (main API) |
|
|
190
|
-
| `motely-wasm/motely` | `IMotelySearch`, `SearchSettings`, `MotelyProgress`, `MotelyScoredSeedResult`, `MotelyStreamKind` |
|
|
191
|
-
| `motely-wasm/motely/enums` | All Balatro enums — `MotelyItemType`, `MotelyItemTypeCategory`, `MotelyJokerRarity`, `MotelyItemEdition`, `MotelyItemSeal`, `MotelyItemEnhancement`, `MotelyTag`, `MotelyVoucher`, `MotelyBoosterPack`, `MotelyDeck`, `MotelyStake`, `MotelyBossBlind`, etc. |
|
|
192
|
-
| `motely-wasm/motely/filters` | `JamlAesthetic`, `JamlSearchPlan` |
|
|
193
|
-
| `motely-wasm/motely/analysis` | `MotelyJamlyzerResult`, `MotelySeedAnalysis` |
|
|
194
|
-
| `motely-wasm/bootsharp/file-system` | File-system interop (browser OPFS) — `PermissionMode`, `IFileMounter` |
|
|
195
|
-
|
|
196
|
-
## Using in a Web Worker
|
|
176
|
+
Clause types: `joker`, `voucher`, `boss`, `tag`, `spectral`, `tarot`, `planet`, `pack`.
|
|
177
|
+
Sources can be narrowed via `sources: { shopItems: [0, 1], boosterPacks: [0] }`.
|
|
197
178
|
|
|
198
|
-
|
|
199
|
-
Worker and drive it with messages. This mirrors the proven setup in the `jaml-ui`
|
|
200
|
-
package's `searchWorker.ts`.
|
|
179
|
+
## Enums
|
|
201
180
|
|
|
202
|
-
|
|
203
|
-
// search-worker.js
|
|
204
|
-
import bootsharp, { Motely } from "motely-wasm";
|
|
205
|
-
|
|
206
|
-
let currentSearch = null;
|
|
207
|
-
|
|
208
|
-
self.onmessage = async ({ data }) => {
|
|
209
|
-
if (data.type === "stop") {
|
|
210
|
-
currentSearch?.cancel();
|
|
211
|
-
self.postMessage({ type: "cancelled" });
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
if (data.type !== "start") return;
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
if (bootsharp.getStatus() === bootsharp.BootStatus.Standby) {
|
|
218
|
-
await bootsharp.boot();
|
|
219
|
-
}
|
|
181
|
+
All enum values are available in the `enums` module:
|
|
220
182
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
self.postMessage({ type: "progress", percent: p.percentComplete });
|
|
225
|
-
Motely.onScoredResult.subscribe(onResult);
|
|
226
|
-
Motely.onProgress.subscribe(onProgress);
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
currentSearch = Motely.createSearch(data.jaml)
|
|
230
|
-
.withThreadCount(1)
|
|
231
|
-
.withSequentialSearch()
|
|
232
|
-
.start();
|
|
233
|
-
await currentSearch.waitForCompletionAsync();
|
|
234
|
-
self.postMessage({
|
|
235
|
-
type: "complete",
|
|
236
|
-
total: Number(currentSearch.totalSeedsSearched),
|
|
237
|
-
matched: Number(currentSearch.matchingSeeds),
|
|
238
|
-
});
|
|
239
|
-
} finally {
|
|
240
|
-
Motely.onScoredResult.unsubscribe(onResult);
|
|
241
|
-
Motely.onProgress.unsubscribe(onProgress);
|
|
242
|
-
currentSearch = null;
|
|
243
|
-
}
|
|
244
|
-
} catch (error) {
|
|
245
|
-
self.postMessage({ type: "error", message: String(error?.message ?? error) });
|
|
246
|
-
}
|
|
247
|
-
};
|
|
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`
|
|
248
186
|
|
|
249
|
-
|
|
250
|
-
```
|
|
187
|
+
## Utility
|
|
251
188
|
|
|
252
189
|
```js
|
|
253
|
-
//
|
|
254
|
-
const
|
|
190
|
+
// Convert between JAML text and JSON.
|
|
191
|
+
const json = Motely.jamlToJson(jamlText);
|
|
192
|
+
const jaml = Motely.jsonToJaml(json);
|
|
255
193
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if (data.type === "progress") console.log(`${data.percent.toFixed(1)}%`);
|
|
259
|
-
if (data.type === "complete") console.log("done:", data.total, data.matched);
|
|
260
|
-
};
|
|
194
|
+
// Human-readable description of a parsed config.
|
|
195
|
+
const explanation = Motely.explainJaml(cfg);
|
|
261
196
|
|
|
262
|
-
|
|
263
|
-
|
|
197
|
+
// List available native (non-JAML) filter names.
|
|
198
|
+
const names = Motely.nativeFilterNames();
|
|
264
199
|
```
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { Event } from "./event.mjs";
|
|
2
|
-
/**
|
|
3
|
-
* Hand-rolled instances are constructed in user code and passed across the interop boundary;
|
|
4
|
-
* instances received from C# are wrapped into generated proxies that expose the same shape. */
|
|
2
|
+
/** A cancellation token compatible with C# `CancellationToken`. */
|
|
5
3
|
export declare class CancellationToken {
|
|
6
|
-
|
|
7
|
-
/** Fires when the token is cancelled. */
|
|
4
|
+
/** Occurs when the token is cancelled. */
|
|
8
5
|
readonly onCancellationRequested: Event<[]>;
|
|
9
6
|
/** Whether cancellation has been requested. */
|
|
10
7
|
get isCancellationRequested(): boolean;
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
private cancelled;
|
|
9
|
+
/** Signal cancellation. */
|
|
13
10
|
cancel(): void;
|
|
14
11
|
}
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { Event } from "./event.mjs";
|
|
2
|
-
/**
|
|
3
|
-
* Hand-rolled instances are constructed in user code and passed across the interop boundary;
|
|
4
|
-
* instances received from C# are wrapped into generated proxies that expose the same shape. */
|
|
2
|
+
/** A cancellation token compatible with C# `CancellationToken`. */
|
|
5
3
|
export class CancellationToken {
|
|
6
|
-
cancelled
|
|
7
|
-
/** Fires when the token is cancelled. */
|
|
4
|
+
/** Occurs when the token is cancelled. */
|
|
8
5
|
onCancellationRequested = new Event();
|
|
9
6
|
/** Whether cancellation has been requested. */
|
|
10
|
-
get isCancellationRequested() {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/** Signal cancellation: flips <see cref="isCancellationRequested"/> and broadcasts
|
|
14
|
-
* <see cref="onCancellationRequested"/>. Idempotent. */
|
|
7
|
+
get isCancellationRequested() { return this.cancelled; }
|
|
8
|
+
cancelled = false;
|
|
9
|
+
/** Signal cancellation. */
|
|
15
10
|
cancel() {
|
|
16
11
|
if (this.cancelled)
|
|
17
12
|
return;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* <c>System.Collections.Generic.ICollection<T></c>. Hand-rolled instances are constructed in
|
|
3
|
-
* user code and passed across the interop boundary; instances received from C# are wrapped into
|
|
4
|
-
* generated proxies that expose the same shape. */
|
|
1
|
+
/** A collection of items compatible with C# `ICollection<T>`. */
|
|
5
2
|
export declare class Collection<T> {
|
|
6
3
|
protected readonly items: T[];
|
|
7
4
|
constructor(items?: Iterable<T>);
|
package/dist/bcl/collection.mjs
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* <c>System.Collections.Generic.ICollection<T></c>. Hand-rolled instances are constructed in
|
|
3
|
-
* user code and passed across the interop boundary; instances received from C# are wrapped into
|
|
4
|
-
* generated proxies that expose the same shape. */
|
|
1
|
+
/** A collection of items compatible with C# `ICollection<T>`. */
|
|
5
2
|
export class Collection {
|
|
6
3
|
items;
|
|
7
4
|
constructor(items) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** A dictionary of key-value pairs compatible with C# `IDictionary<TKey, TValue>`. */
|
|
2
|
+
export declare class Dictionary<TKey, TValue> {
|
|
3
|
+
protected readonly map: Map<TKey, TValue>;
|
|
4
|
+
constructor(entries?: Iterable<[TKey, TValue]>);
|
|
5
|
+
/** Number of key-value pairs in the dictionary. */
|
|
6
|
+
get count(): number;
|
|
7
|
+
/** Associates the specified value with the specified key. */
|
|
8
|
+
add(key: TKey, value: TValue): void;
|
|
9
|
+
/** Whether the dictionary contains the specified key. */
|
|
10
|
+
containsKey(key: TKey): boolean;
|
|
11
|
+
/** Removes the value with the specified key from the dictionary.
|
|
12
|
+
* @returns true when the key was removed; false when it wasn't found. */
|
|
13
|
+
remove(key: TKey): boolean;
|
|
14
|
+
/** Removes all key-value pairs from the dictionary. */
|
|
15
|
+
clear(): void;
|
|
16
|
+
/** Returns the value associated with the specified key. */
|
|
17
|
+
getAt(key: TKey): TValue;
|
|
18
|
+
/** Associates the specified value with the specified key. */
|
|
19
|
+
setAt(key: TKey, value: TValue): void;
|
|
20
|
+
/** Returns a fresh array with a snapshot of the current keys. */
|
|
21
|
+
getKeys(): TKey[];
|
|
22
|
+
/** Returns a fresh array with a snapshot of the current values. */
|
|
23
|
+
getValues(): TValue[];
|
|
24
|
+
[Symbol.iterator](): IterableIterator<[TKey, TValue]>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** A dictionary of key-value pairs compatible with C# `IDictionary<TKey, TValue>`. */
|
|
2
|
+
export class Dictionary {
|
|
3
|
+
map;
|
|
4
|
+
constructor(entries) {
|
|
5
|
+
this.map = new Map(entries);
|
|
6
|
+
}
|
|
7
|
+
/** Number of key-value pairs in the dictionary. */
|
|
8
|
+
get count() {
|
|
9
|
+
return this.map.size;
|
|
10
|
+
}
|
|
11
|
+
/** Associates the specified value with the specified key. */
|
|
12
|
+
add(key, value) {
|
|
13
|
+
this.map.set(key, value);
|
|
14
|
+
}
|
|
15
|
+
/** Whether the dictionary contains the specified key. */
|
|
16
|
+
containsKey(key) {
|
|
17
|
+
return this.map.has(key);
|
|
18
|
+
}
|
|
19
|
+
/** Removes the value with the specified key from the dictionary.
|
|
20
|
+
* @returns true when the key was removed; false when it wasn't found. */
|
|
21
|
+
remove(key) {
|
|
22
|
+
return this.map.delete(key);
|
|
23
|
+
}
|
|
24
|
+
/** Removes all key-value pairs from the dictionary. */
|
|
25
|
+
clear() {
|
|
26
|
+
this.map.clear();
|
|
27
|
+
}
|
|
28
|
+
/** Returns the value associated with the specified key. */
|
|
29
|
+
getAt(key) {
|
|
30
|
+
return this.map.get(key);
|
|
31
|
+
}
|
|
32
|
+
/** Associates the specified value with the specified key. */
|
|
33
|
+
setAt(key, value) {
|
|
34
|
+
this.map.set(key, value);
|
|
35
|
+
}
|
|
36
|
+
/** Returns a fresh array with a snapshot of the current keys. */
|
|
37
|
+
getKeys() {
|
|
38
|
+
return Array.from(this.map.keys());
|
|
39
|
+
}
|
|
40
|
+
/** Returns a fresh array with a snapshot of the current values. */
|
|
41
|
+
getValues() {
|
|
42
|
+
return Array.from(this.map.values());
|
|
43
|
+
}
|
|
44
|
+
[Symbol.iterator]() {
|
|
45
|
+
return this.map[Symbol.iterator]();
|
|
46
|
+
}
|
|
47
|
+
}
|
package/dist/bcl/event.d.mts
CHANGED
|
@@ -20,7 +20,7 @@ export type EventOptions = {
|
|
|
20
20
|
/** Custom warnings handler; by default <code>console.warn</code> is used. */
|
|
21
21
|
warn?: (message: string) => void;
|
|
22
22
|
};
|
|
23
|
-
/** Allows attaching handlers and broadcasting events. */
|
|
23
|
+
/** Allows attaching handlers and broadcasting events; compatible with C# events. */
|
|
24
24
|
export declare class Event<T extends unknown[]> implements EventBroadcaster<T>, EventSubscriber<T> {
|
|
25
25
|
private readonly handlers;
|
|
26
26
|
private readonly warn;
|
package/dist/bcl/event.mjs
CHANGED
package/dist/bcl/index.d.mts
CHANGED
package/dist/bcl/index.mjs
CHANGED
package/dist/bcl/list.d.mts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { Collection } from "./collection.mjs";
|
|
2
|
-
/**
|
|
3
|
-
* Extends <see cref="Collection"/> with index-based access; like the collection, hand-rolled
|
|
4
|
-
* instances are passed across the interop boundary, while instances received from C# are wrapped
|
|
5
|
-
* into generated proxies that expose the same shape. */
|
|
2
|
+
/** A list of items compatible with C# `IList<T>`. */
|
|
6
3
|
export declare class List<T> extends Collection<T> {
|
|
4
|
+
/** Returns the item at the specified index. */
|
|
5
|
+
getAt(index: number): T;
|
|
6
|
+
/** Assigns the specified item at the specified index. */
|
|
7
|
+
setAt(index: number, item: T): void;
|
|
7
8
|
/** Returns the index of the first occurrence of the specified item, or -1 when not found. */
|
|
8
9
|
indexOf(item: T): number;
|
|
9
10
|
/** Inserts the specified item at the specified index. */
|
|
10
11
|
insert(index: number, item: T): void;
|
|
11
12
|
/** Removes the item at the specified index. */
|
|
12
13
|
removeAt(index: number): void;
|
|
13
|
-
/** Returns the item at the specified index. */
|
|
14
|
-
getAt(index: number): T;
|
|
15
|
-
/** Assigns the specified item at the specified index. */
|
|
16
|
-
setAt(index: number, item: T): void;
|
|
17
14
|
}
|
package/dist/bcl/list.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Collection } from "./collection.mjs";
|
|
2
|
-
/**
|
|
3
|
-
* Extends <see cref="Collection"/> with index-based access; like the collection, hand-rolled
|
|
4
|
-
* instances are passed across the interop boundary, while instances received from C# are wrapped
|
|
5
|
-
* into generated proxies that expose the same shape. */
|
|
2
|
+
/** A list of items compatible with C# `IList<T>`. */
|
|
6
3
|
export class List extends Collection {
|
|
4
|
+
/** Returns the item at the specified index. */
|
|
5
|
+
getAt(index) {
|
|
6
|
+
return this.items[index];
|
|
7
|
+
}
|
|
8
|
+
/** Assigns the specified item at the specified index. */
|
|
9
|
+
setAt(index, item) {
|
|
10
|
+
this.items[index] = item;
|
|
11
|
+
}
|
|
7
12
|
/** Returns the index of the first occurrence of the specified item, or -1 when not found. */
|
|
8
13
|
indexOf(item) {
|
|
9
14
|
return this.items.indexOf(item);
|
|
@@ -16,12 +21,4 @@ export class List extends Collection {
|
|
|
16
21
|
removeAt(index) {
|
|
17
22
|
this.items.splice(index, 1);
|
|
18
23
|
}
|
|
19
|
-
/** Returns the item at the specified index. */
|
|
20
|
-
getAt(index) {
|
|
21
|
-
return this.items[index];
|
|
22
|
-
}
|
|
23
|
-
/** Assigns the specified item at the specified index. */
|
|
24
|
-
setAt(index, item) {
|
|
25
|
-
this.items[index] = item;
|
|
26
|
-
}
|
|
27
24
|
}
|
|
Binary file
|