jaml-ui 0.13.1 → 0.14.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/assets/Balatro Seed Curator (DesignsV2)/Assets/Decks/playing_cards_metadata.json +230 -55
- package/dist/components/AnalyzerExplorer.js +75 -90
- package/dist/components/CardFan.js +2 -2
- package/dist/components/GameCard.js +9 -9
- package/dist/components/JamlAestheticSelector.d.ts +9 -0
- package/dist/components/JamlAestheticSelector.js +36 -0
- package/dist/components/JamlIde.d.ts +2 -1
- package/dist/components/JamlIde.js +6 -4
- package/dist/components/JamlIdeToolbar.js +1 -0
- package/dist/components/JamlSeedInput.d.ts +9 -0
- package/dist/components/JamlSeedInput.js +30 -0
- package/dist/components/JamlSpeedometer.d.ts +11 -0
- package/dist/components/JamlSpeedometer.js +54 -0
- package/dist/components/Standardcard.d.ts +18 -0
- package/dist/components/Standardcard.js +80 -0
- package/dist/decode/motelyItemDecoder.d.ts +3 -3
- package/dist/decode/motelyItemDecoder.js +12 -12
- package/dist/decode/packedBalatroItem.d.ts +1 -1
- package/dist/decode/packedBalatroItem.js +2 -2
- package/dist/hooks/searchWorkerCode.d.ts +1 -1
- package/dist/hooks/searchWorkerCode.js +31 -5
- package/dist/hooks/useSearch.d.ts +9 -0
- package/dist/hooks/useSearch.js +73 -17
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/motely.d.ts +1 -1
- package/dist/motely.js +1 -1
- package/dist/ui/jimboTabs.js +1 -1
- package/dist/utils/fileSystem.d.ts +1 -0
- package/dist/utils/fileSystem.js +23 -0
- package/dist/utils/itemUtils.d.ts +1 -1
- package/dist/utils/itemUtils.js +3 -3
- package/package.json +4 -3
package/dist/hooks/useSearch.js
CHANGED
|
@@ -8,16 +8,20 @@ function createWorker(motelyWasmUrl) {
|
|
|
8
8
|
worker.postMessage({ type: "init", url: motelyWasmUrl });
|
|
9
9
|
return worker;
|
|
10
10
|
}
|
|
11
|
+
const INITIAL_STATE = {
|
|
12
|
+
results: [],
|
|
13
|
+
totalSearched: 0n,
|
|
14
|
+
matchingSeeds: 0n,
|
|
15
|
+
status: "idle",
|
|
16
|
+
error: null,
|
|
17
|
+
seedsPerSecond: 0,
|
|
18
|
+
tallyLabels: [],
|
|
19
|
+
};
|
|
11
20
|
export function useSearch(motelyWasmUrl) {
|
|
12
|
-
const [state, setState] = useState(
|
|
13
|
-
results: [],
|
|
14
|
-
totalSearched: 0n,
|
|
15
|
-
matchingSeeds: 0n,
|
|
16
|
-
status: "idle",
|
|
17
|
-
error: null,
|
|
18
|
-
});
|
|
21
|
+
const [state, setState] = useState(INITIAL_STATE);
|
|
19
22
|
const workerRef = useRef(null);
|
|
20
23
|
const readyRef = useRef(false);
|
|
24
|
+
const speedRef = useRef({ lastSearched: 0n, lastTime: 0, ema: 0 });
|
|
21
25
|
useEffect(() => {
|
|
22
26
|
setState((s) => ({ ...s, status: "booting" }));
|
|
23
27
|
const worker = createWorker(motelyWasmUrl);
|
|
@@ -30,16 +34,51 @@ export function useSearch(motelyWasmUrl) {
|
|
|
30
34
|
setState((s) => s.status === "booting" ? { ...s, status: "idle" } : s);
|
|
31
35
|
}
|
|
32
36
|
else if (msg.type === "result") {
|
|
33
|
-
setState((s) => ({
|
|
37
|
+
setState((s) => ({
|
|
38
|
+
...s,
|
|
39
|
+
results: [...s.results, {
|
|
40
|
+
seed: msg.seed,
|
|
41
|
+
score: msg.score,
|
|
42
|
+
tallyColumns: msg.tallyColumns,
|
|
43
|
+
}],
|
|
44
|
+
}));
|
|
34
45
|
}
|
|
35
46
|
else if (msg.type === "progress") {
|
|
36
|
-
|
|
47
|
+
const searched = BigInt(msg.searched);
|
|
48
|
+
const matching = BigInt(msg.matching);
|
|
49
|
+
const now = performance.now();
|
|
50
|
+
const ref = speedRef.current;
|
|
51
|
+
let sps = ref.ema;
|
|
52
|
+
if (ref.lastTime > 0) {
|
|
53
|
+
const dtMs = now - ref.lastTime;
|
|
54
|
+
if (dtMs > 0) {
|
|
55
|
+
const delta = Number(searched - ref.lastSearched);
|
|
56
|
+
const instantSps = delta / (dtMs / 1000);
|
|
57
|
+
sps = ref.ema === 0 ? instantSps : ref.ema * 0.7 + instantSps * 0.3;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
ref.lastSearched = searched;
|
|
61
|
+
ref.lastTime = now;
|
|
62
|
+
ref.ema = sps;
|
|
63
|
+
setState((s) => ({ ...s, totalSearched: searched, matchingSeeds: matching, seedsPerSecond: Math.round(sps) }));
|
|
37
64
|
}
|
|
38
65
|
else if (msg.type === "complete") {
|
|
39
|
-
|
|
66
|
+
speedRef.current = { lastSearched: 0n, lastTime: 0, ema: 0 };
|
|
67
|
+
setState((s) => ({
|
|
68
|
+
...s,
|
|
69
|
+
status: msg.status === "Completed" ? "completed" : "error",
|
|
70
|
+
error: msg.status !== "Completed" ? msg.status : null,
|
|
71
|
+
totalSearched: BigInt(msg.searched),
|
|
72
|
+
matchingSeeds: BigInt(msg.matched),
|
|
73
|
+
seedsPerSecond: 0,
|
|
74
|
+
}));
|
|
40
75
|
}
|
|
41
76
|
else if (msg.type === "cancelled") {
|
|
42
|
-
|
|
77
|
+
speedRef.current = { lastSearched: 0n, lastTime: 0, ema: 0 };
|
|
78
|
+
setState((s) => ({ ...s, status: "cancelled", seedsPerSecond: 0 }));
|
|
79
|
+
}
|
|
80
|
+
else if (msg.type === "tally_labels") {
|
|
81
|
+
setState((s) => ({ ...s, tallyLabels: msg.labels }));
|
|
43
82
|
}
|
|
44
83
|
else if (msg.type === "error") {
|
|
45
84
|
setState((s) => ({ ...s, status: "error", error: msg.message }));
|
|
@@ -50,13 +89,15 @@ export function useSearch(motelyWasmUrl) {
|
|
|
50
89
|
workerRef.current = null;
|
|
51
90
|
};
|
|
52
91
|
}, [motelyWasmUrl]);
|
|
53
|
-
const
|
|
92
|
+
const sendStart = useCallback((payload) => {
|
|
54
93
|
const worker = workerRef.current;
|
|
55
94
|
if (!worker)
|
|
56
95
|
return;
|
|
57
|
-
|
|
96
|
+
speedRef.current = { lastSearched: 0n, lastTime: 0, ema: 0 };
|
|
97
|
+
setState({ ...INITIAL_STATE, status: "running", tallyLabels: state.tallyLabels });
|
|
98
|
+
const send = () => worker.postMessage(payload);
|
|
58
99
|
if (readyRef.current) {
|
|
59
|
-
|
|
100
|
+
send();
|
|
60
101
|
}
|
|
61
102
|
else {
|
|
62
103
|
const orig = worker.onmessage;
|
|
@@ -64,16 +105,31 @@ export function useSearch(motelyWasmUrl) {
|
|
|
64
105
|
orig?.call(worker, e);
|
|
65
106
|
if (e.data.type === "ready") {
|
|
66
107
|
worker.onmessage = orig;
|
|
67
|
-
|
|
108
|
+
send();
|
|
68
109
|
}
|
|
69
110
|
};
|
|
70
111
|
}
|
|
71
|
-
}, []);
|
|
112
|
+
}, [state.tallyLabels]);
|
|
113
|
+
const start = useCallback((jaml, count) => {
|
|
114
|
+
sendStart({ type: "start", mode: "random", jaml, count });
|
|
115
|
+
}, [sendStart]);
|
|
116
|
+
const startAesthetic = useCallback((jaml, aesthetic) => {
|
|
117
|
+
sendStart({ type: "start", mode: "aesthetic", jaml, aesthetic });
|
|
118
|
+
}, [sendStart]);
|
|
119
|
+
const startSeedList = useCallback((jaml, seeds) => {
|
|
120
|
+
sendStart({ type: "start", mode: "seedList", jaml, seeds });
|
|
121
|
+
}, [sendStart]);
|
|
122
|
+
const startKeyword = useCallback((jaml, keywords, padding) => {
|
|
123
|
+
sendStart({ type: "start", mode: "keyword", jaml, keywords, padding });
|
|
124
|
+
}, [sendStart]);
|
|
72
125
|
const cancel = useCallback(() => {
|
|
73
126
|
workerRef.current?.postMessage({ type: "stop" });
|
|
74
127
|
}, []);
|
|
75
128
|
const clearError = useCallback(() => {
|
|
76
129
|
setState((s) => (s.error || s.status === "error" ? { ...s, error: null, status: "idle" } : s));
|
|
77
130
|
}, []);
|
|
78
|
-
|
|
131
|
+
const fetchTallyLabels = useCallback((jaml) => {
|
|
132
|
+
workerRef.current?.postMessage({ type: "get_tally_labels", jaml });
|
|
133
|
+
}, []);
|
|
134
|
+
return { ...state, start, startAesthetic, startSeedList, startKeyword, cancel, clearError, fetchTallyLabels };
|
|
79
135
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,10 +18,14 @@ export { JimboTooltip, type JimboTooltipProps, type JimboTooltipMode, type Jimbo
|
|
|
18
18
|
export { JamlIdeToolbar, type JamlIdeMode, type JamlIdeToolbarProps, } from "./components/JamlIdeToolbar.js";
|
|
19
19
|
export { CardList, type CardListProps } from "./components/CardList.js";
|
|
20
20
|
export { CardFan, type CardFanProps } from "./components/CardFan.js";
|
|
21
|
-
export {
|
|
21
|
+
export { RealStandardcard, type CardSuit, type CardRank, type CardEnhancement, type CardSeal, type CardEdition, } from "./components/Standardcard.js";
|
|
22
22
|
export { DeckSprite, DECK_SPRITE_POS, STAKE_SPRITE_POS, type DeckSpriteProps, } from "./components/DeckSprite.js";
|
|
23
23
|
export { MotelyVersionBadge, type MotelyVersionBadgeProps, type MotelyCapabilities, } from "./components/MotelyVersionBadge.js";
|
|
24
24
|
export { extractVisualJamlItems, type JamlPreviewGroups, type JamlPreviewItem, type JamlPreviewSection, type JamlPreviewVisualType, } from "./utils/jamlMapPreview.js";
|
|
25
25
|
export { useMotelyStream, type StreamItem, type StreamState } from "./hooks/useShopStream.js";
|
|
26
26
|
export { useSearch, type SearchResult, type SearchStatus, type UseSearchState, } from "./hooks/useSearch.js";
|
|
27
27
|
export { useAnalyzer, type AnalyzerStatus, type AnalyzerLive, type MotelyJsRunState, } from "./hooks/useAnalyzer.js";
|
|
28
|
+
export { JamlSpeedometer, type JamlSpeedometerProps, } from "./components/JamlSpeedometer.js";
|
|
29
|
+
export { JamlAestheticSelector, type JamlAestheticSelectorProps, type JamlAestheticOption, } from "./components/JamlAestheticSelector.js";
|
|
30
|
+
export { JamlSeedInput, type JamlSeedInputProps, } from "./components/JamlSeedInput.js";
|
|
31
|
+
export { initJamlFileSystem } from "./utils/fileSystem.js";
|
package/dist/index.js
CHANGED
|
@@ -19,10 +19,14 @@ export { JimboTooltip, } from "./ui/jimboTooltip.js";
|
|
|
19
19
|
export { JamlIdeToolbar, } from "./components/JamlIdeToolbar.js";
|
|
20
20
|
export { CardList } from "./components/CardList.js";
|
|
21
21
|
export { CardFan } from "./components/CardFan.js";
|
|
22
|
-
export {
|
|
22
|
+
export { RealStandardcard, } from "./components/Standardcard.js";
|
|
23
23
|
export { DeckSprite, DECK_SPRITE_POS, STAKE_SPRITE_POS, } from "./components/DeckSprite.js";
|
|
24
24
|
export { MotelyVersionBadge, } from "./components/MotelyVersionBadge.js";
|
|
25
25
|
export { extractVisualJamlItems, } from "./utils/jamlMapPreview.js";
|
|
26
26
|
export { useMotelyStream } from "./hooks/useShopStream.js";
|
|
27
27
|
export { useSearch, } from "./hooks/useSearch.js";
|
|
28
28
|
export { useAnalyzer, } from "./hooks/useAnalyzer.js";
|
|
29
|
+
export { JamlSpeedometer, } from "./components/JamlSpeedometer.js";
|
|
30
|
+
export { JamlAestheticSelector, } from "./components/JamlAestheticSelector.js";
|
|
31
|
+
export { JamlSeedInput, } from "./components/JamlSeedInput.js";
|
|
32
|
+
export { initJamlFileSystem } from "./utils/fileSystem.js";
|
package/dist/motely.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { decodeMotelyItem, decodeMotelyItemToJamlCard, motelyItemTypeName, motelyItemCategory, motelyItemDisplayName, motelyItemRenderCategory, motelyItemEditionName, motelyItemSealName, motelyItemEnhancementName,
|
|
1
|
+
export { decodeMotelyItem, decodeMotelyItemToJamlCard, motelyItemTypeName, motelyItemCategory, motelyItemDisplayName, motelyItemRenderCategory, motelyItemEditionName, motelyItemSealName, motelyItemEnhancementName, motelyStandardcardRankName, motelyStandardcardSuitName, decodeMotelyItemName, resolveMotelyItemType, warmMotelyItemCache, motelyItemCacheSize, type DecodedMotelyItem, type MotelyItemInput, type MotelyJamlCard, type MotelyRenderableCategory, type MotelyRuntimeItem, } from "./decode/motelyItemDecoder.js";
|
|
2
2
|
export { MOTELY_DISPLAY_SCHEMA, motelyBossDisplayName, motelyBossDisplayNameFromKey, motelyBossKeyFromDisplayName, motelyBoosterPackDisplayName, motelyBoosterPackDisplayNameFromKey, motelyBoosterPackKeyFromDisplayName, motelyItemDisplayNameFromKey, motelyItemDisplayNameFromValue, motelyTagDisplayName, motelyTagDisplayNameFromKey, motelyTagKeyFromDisplayName, motelyVoucherDisplayName, motelyVoucherDisplayNameFromKey, motelyVoucherKeyFromDisplayName, type MotelyBoosterPackKey, type MotelyBossKey, type MotelyDisplaySchema, type MotelyTagKey, type MotelyVoucherKey, } from "./motelyDisplay.js";
|
package/dist/motely.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { decodeMotelyItem, decodeMotelyItemToJamlCard, motelyItemTypeName, motelyItemCategory, motelyItemDisplayName, motelyItemRenderCategory, motelyItemEditionName, motelyItemSealName, motelyItemEnhancementName,
|
|
2
|
+
export { decodeMotelyItem, decodeMotelyItemToJamlCard, motelyItemTypeName, motelyItemCategory, motelyItemDisplayName, motelyItemRenderCategory, motelyItemEditionName, motelyItemSealName, motelyItemEnhancementName, motelyStandardcardRankName, motelyStandardcardSuitName, decodeMotelyItemName, resolveMotelyItemType, warmMotelyItemCache, motelyItemCacheSize, } from "./decode/motelyItemDecoder.js";
|
|
3
3
|
export { MOTELY_DISPLAY_SCHEMA, motelyBossDisplayName, motelyBossDisplayNameFromKey, motelyBossKeyFromDisplayName, motelyBoosterPackDisplayName, motelyBoosterPackDisplayNameFromKey, motelyBoosterPackKeyFromDisplayName, motelyItemDisplayNameFromKey, motelyItemDisplayNameFromValue, motelyTagDisplayName, motelyTagDisplayNameFromKey, motelyTagKeyFromDisplayName, motelyVoucherDisplayName, motelyVoucherDisplayNameFromKey, motelyVoucherKeyFromDisplayName, } from "./motelyDisplay.js";
|
package/dist/ui/jimboTabs.js
CHANGED
|
@@ -9,7 +9,7 @@ import { JimboText } from './jimboText.js';
|
|
|
9
9
|
* button and animates only on the active one.
|
|
10
10
|
*/
|
|
11
11
|
export function JimboTabs({ tabs, activeTab, onTabChange, className = '', style }) {
|
|
12
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: className, style: { display: 'flex', gap: 8, alignItems: 'flex-end', ...style }, children: tabs.map((tab) => (_jsx(TabButton, { label: tab.label, active: activeTab === tab.id, onClick: () => onTabChange(tab.id) }, tab.id))) }), _jsx("style", { children: JIMBO_BOUNCE_KEYFRAMES })] }));
|
|
12
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: className, style: { display: 'flex', gap: 8, alignItems: 'flex-end', flexWrap: 'wrap', ...style }, children: tabs.map((tab) => (_jsx(TabButton, { label: tab.label, active: activeTab === tab.id, onClick: () => onTabChange(tab.id) }, tab.id))) }), _jsx("style", { children: JIMBO_BOUNCE_KEYFRAMES })] }));
|
|
13
13
|
}
|
|
14
14
|
const JIMBO_BOUNCE_KEYFRAMES = `
|
|
15
15
|
@keyframes jimbo-bounce {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function initJamlFileSystem(): boolean;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { init } from "@rewaffle/bootsharp-file-system";
|
|
2
|
+
// Assuming motely-wasm exposes Bootsharp APIs
|
|
3
|
+
// We need to pass the FileMounter export generated by Bootsharp
|
|
4
|
+
import * as motelyWasm from "motely-wasm";
|
|
5
|
+
export function initJamlFileSystem() {
|
|
6
|
+
if (motelyWasm && motelyWasm.Bootsharp && motelyWasm.Bootsharp.FileSystem) {
|
|
7
|
+
const fileMounter = motelyWasm.Bootsharp.FileSystem.FileMounter;
|
|
8
|
+
if (fileMounter) {
|
|
9
|
+
init(fileMounter);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
// Also try lowercase namespaces depending on how bootsharp generates it
|
|
14
|
+
if (motelyWasm && motelyWasm.bootsharp && motelyWasm.bootsharp.fileSystem) {
|
|
15
|
+
const fileMounter = motelyWasm.bootsharp.fileSystem.fileMounter;
|
|
16
|
+
if (fileMounter) {
|
|
17
|
+
init(fileMounter);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
console.warn("Could not initialize Jaml File System: Bootsharp.FileSystem.FileMounter not found in motely-wasm.");
|
|
22
|
+
return false;
|
|
23
|
+
}
|
package/dist/utils/itemUtils.js
CHANGED
|
@@ -17,7 +17,7 @@ export function getItemDisplayName(enumKey) {
|
|
|
17
17
|
};
|
|
18
18
|
if (specials[enumKey])
|
|
19
19
|
return specials[enumKey];
|
|
20
|
-
//
|
|
20
|
+
// Standard cards: C2 = 2 of Clubs, D10 = 10 of Diamonds, etc.
|
|
21
21
|
const suitMap = { C: "♣", D: "♦", H: "♥", S: "♠" };
|
|
22
22
|
const cardMatch = enumKey.match(/^([CDHS])([2-9JQKA]|10)$/);
|
|
23
23
|
if (cardMatch) {
|
|
@@ -52,7 +52,7 @@ export function getItemCategory(enumKey) {
|
|
|
52
52
|
return "planet";
|
|
53
53
|
if (SPECTRAL_NAMES.has(enumKey))
|
|
54
54
|
return "spectral";
|
|
55
|
-
// Everything else between the
|
|
55
|
+
// Everything else between the standard cards and Invalid is a joker
|
|
56
56
|
return "joker";
|
|
57
57
|
}
|
|
58
58
|
export const CATEGORY_COLORS = {
|
|
@@ -63,7 +63,7 @@ export const CATEGORY_COLORS = {
|
|
|
63
63
|
playing: { bg: "bg-neutral-100 dark:bg-neutral-800", border: "border-neutral-300 dark:border-neutral-600", text: "text-neutral-900 dark:text-neutral-100" },
|
|
64
64
|
unknown: { bg: "bg-neutral-900/30", border: "border-neutral-500/50", text: "text-neutral-300" },
|
|
65
65
|
};
|
|
66
|
-
/** Suit color for
|
|
66
|
+
/** Suit color for standard cards */
|
|
67
67
|
export function getSuitColor(enumKey) {
|
|
68
68
|
if (enumKey.startsWith("H") || enumKey.startsWith("D"))
|
|
69
69
|
return "text-red-500";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jaml-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Balatro rendering components, sprite metadata, and optional Motely helpers for React apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"@react-spring/three": ">=9.0.0",
|
|
77
77
|
"@react-three/fiber": ">=8.0.0",
|
|
78
78
|
"monaco-editor": ">=0.50.0",
|
|
79
|
-
"motely-wasm": "^10.2.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
|
79
|
+
"motely-wasm": "^10.2.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
|
|
80
80
|
"react": "^18.2.0 || ^19.0.0",
|
|
81
81
|
"react-dom": "^18.2.0 || ^19.0.0",
|
|
82
82
|
"react-icons": ">=5.0.0",
|
|
@@ -108,7 +108,8 @@
|
|
|
108
108
|
"@types/three": "^0.184.0",
|
|
109
109
|
"@vitejs/plugin-react": "^5.0.4",
|
|
110
110
|
"monaco-editor": "^0.55.1",
|
|
111
|
-
"motely-wasm": "
|
|
111
|
+
"motely-wasm": "link:../JammySeedFinder/src/MotelyJAML/Motely.Wasm/bin/motely-wasm",
|
|
112
|
+
"@rewaffle/bootsharp-file-system": "link:D:/extra/bootsharp/dist/packages/file-system",
|
|
112
113
|
"react": "^19.2.4",
|
|
113
114
|
"react-dom": "^19.2.4",
|
|
114
115
|
"react-icons": "^5.6.0",
|