Skip to content

Commit d7a934d

Browse files
committed
close
1 parent 746c0fc commit d7a934d

File tree

6 files changed

+222
-36
lines changed

6 files changed

+222
-36
lines changed

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4-
<MotelyVersion>4.3.1</MotelyVersion>
4+
<MotelyVersion>4.3.8</MotelyVersion>
55
</PropertyGroup>
66
<ItemGroup>
77
<PackageVersion Include="Bootsharp" Version="0.7.0" />

Motely.Node/Motely.Node.csproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PublishAot>true</PublishAot>
1111
<PublishTrimmed>true</PublishTrimmed>
1212
<PublishNodeModule>true</PublishNodeModule>
13+
<NpmPackDirectory>..\..\motely-node</NpmPackDirectory>
1314
<GenerateNodeApiTypeDefinitionsForReferences>false</GenerateNodeApiTypeDefinitionsForReferences>
1415
</PropertyGroup>
1516
<ItemGroup>
@@ -20,4 +21,14 @@
2021
<PackageReference Include="Microsoft.JavaScript.NodeApi" />
2122
<PackageReference Include="Microsoft.JavaScript.NodeApi.Generator" PrivateAssets="all" GeneratePathProperty="true" />
2223
</ItemGroup>
24+
25+
<Target Name="CopyToNpmPackage" AfterTargets="Publish">
26+
<ItemGroup>
27+
<GeneratedFiles Include="$(PublishDir)MotelyNode.cjs;$(PublishDir)MotelyNode.mjs;$(PublishDir)MotelyNode.d.ts" />
28+
<NativeBinary Include="$(PublishDir)MotelyNode.node" />
29+
</ItemGroup>
30+
<Copy SourceFiles="@(GeneratedFiles)" DestinationFolder="$(MSBuildProjectDirectory)\..\..\motely-node" SkipUnchangedFiles="false" />
31+
<Copy SourceFiles="@(NativeBinary)" DestinationFolder="$(MSBuildProjectDirectory)\..\..\motely-node\linux-x64" SkipUnchangedFiles="false" />
32+
<Message Text="Copied generated files to motely-node package directory" Importance="high" />
33+
</Target>
2334
</Project>

Motely.npm-staging/motely-wasm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "motely-wasm",
3-
"version": "4.3.1",
3+
"version": "4.3.8",
44
"description": "Motely WebAssembly (Bootsharp) for browser.",
55
"type": "module",
66
"main": "dist/index.mjs",

Motely/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "motely",
3-
"version": "4.3.1",
3+
"version": "4.3.8",
44
"description": "MotelyJAML — Balatro seed search, analysis, and JAML filtering. Native Node.js module + Browser WASM.",
55
"type": "module",
66
"exports": {

build-and-pack.ps1

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
#!/usr/bin/env pwsh
22
# Build and pack motely-node (NativeAOT) and motely-wasm (Bootsharp NativeAOT-LLVM)
3-
# Usage: ./build-and-pack.ps1 [-Node] [-Wasm] [-All]
4-
# Default: -All
5-
6-
param(
7-
[switch]$Node,
8-
[switch]$Wasm,
9-
[switch]$All
10-
)
11-
12-
if (-not $Node -and -not $Wasm) { $All = $true }
13-
if ($All) { $Node = $true; $Wasm = $true }
3+
# Usage: ./build-and-pack.ps1
144

155
$ErrorActionPreference = "Stop"
166

@@ -30,31 +20,34 @@ $propsContent = $propsContent -replace "<MotelyVersion>$oldVersion</MotelyVersio
3020
Set-Content $propsPath $propsContent -NoNewline
3121
Write-Host "Version: $oldVersion -> $version" -ForegroundColor Green
3222

33-
# Keep npm package.json versions aligned with <MotelyVersion>
23+
# Keep npm package.json versions aligned
3424
node (Join-Path $PSScriptRoot "sync-version.mjs")
3525
if ($LASTEXITCODE -ne 0) { throw "sync-version.mjs failed" }
3626

37-
# Phase 1: Node.js NativeAOT (.node addon via Docker)
38-
if ($Node) {
39-
Write-Host "`n=== Node.js NativeAOT (linux-x64) ===" -ForegroundColor Cyan
40-
Write-Host "Building in Docker..." -ForegroundColor Yellow
41-
docker run --rm -v "${PWD}:/src" -w "//src" mcr.microsoft.com/dotnet/sdk:10.0 bash -c "apt-get update -qq && apt-get install -y -qq clang zlib1g-dev npm >/dev/null 2>&1 && dotnet publish Motely.Node/Motely.Node.csproj -c Release -f net10.0 -r linux-x64 -p:PublishAot=true"
42-
if ($LASTEXITCODE -ne 0) { throw "Node NativeAOT build failed" }
43-
node (Join-Path $PSScriptRoot "Motely/build/stage-node.mjs")
44-
if ($LASTEXITCODE -ne 0) { throw "stage-node.mjs failed" }
45-
Write-Host " motely-node/ staged (MotelyNode.cjs + linux-x64/MotelyNode.node + generator .d.ts)" -ForegroundColor Green
46-
}
27+
# Phase 1: Node.js NativeAOT
28+
Write-Host "`n=== Node.js NativeAOT (linux-x64) ===" -ForegroundColor Cyan
29+
docker run --rm -v "${PWD}:/src" -w "/src" mcr.microsoft.com/dotnet/sdk:10.0 bash -c "apt-get update -qq && apt-get install -y -qq clang zlib1g-dev npm >/dev/null 2>&1 && dotnet publish Motely.Node/Motely.Node.csproj -c Release -f net10.0 -r linux-x64 -p:PublishAot=true"
30+
if ($LASTEXITCODE -ne 0) { throw "Node NativeAOT build failed" }
4731

48-
# Phase 2: Browser WASM (Bootsharp NativeAOT-LLVM)
49-
if ($Wasm) {
50-
Write-Host "`n=== Browser WASM (Bootsharp NativeAOT-LLVM) ===" -ForegroundColor Cyan
51-
dotnet publish Motely.BrowserWasm/Motely.BrowserWasm.csproj -c Release
52-
if ($LASTEXITCODE -ne 0) { throw "WASM build failed" }
53-
node (Join-Path $PSScriptRoot "Motely/build/stage-wasm.mjs")
54-
if ($LASTEXITCODE -ne 0) { throw "stage-wasm.mjs failed" }
55-
Write-Host " motely-wasm/dist ready (dist/index.mjs + full dist/bootsharp/)" -ForegroundColor Green
56-
}
32+
Push-Location motely-node
33+
npm pack
34+
if ($LASTEXITCODE -ne 0) { throw "npm pack failed for motely-node" }
35+
Pop-Location
36+
Write-Host " motely-node packed" -ForegroundColor Green
37+
38+
# Phase 2: Browser WASM
39+
Write-Host "`n=== Browser WASM (Bootsharp NativeAOT-LLVM) ===" -ForegroundColor Cyan
40+
dotnet publish Motely.BrowserWasm/Motely.BrowserWasm.csproj -c Release
41+
if ($LASTEXITCODE -ne 0) { throw "WASM build failed" }
42+
43+
node (Join-Path $PSScriptRoot "Motely/build/stage-wasm.mjs")
44+
if ($LASTEXITCODE -ne 0) { throw "stage-wasm.mjs failed" }
45+
46+
Push-Location Motely.npm-staging\motely-wasm
47+
npm pack
48+
if ($LASTEXITCODE -ne 0) { throw "npm pack failed for motely-wasm" }
49+
Pop-Location
50+
Write-Host " motely-wasm packed" -ForegroundColor Green
5751

5852
Write-Host "`n=== DONE ===" -ForegroundColor Cyan
59-
if ($Node) { Write-Host " Node: cd motely-node && npm pack" -ForegroundColor White }
60-
if ($Wasm) { Write-Host " WASM: cd Motely.npm-staging/motely-wasm && npm pack" -ForegroundColor White }
53+
Write-Host "Tarballs ready in motely-node/ and motely-wasm/" -ForegroundColor White

seed-finder.html

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Motely Seed Finder (WASM)</title>
7+
<style>
8+
* { box-sizing: border-box; margin: 0; padding: 0; }
9+
body {
10+
font-family: 'Courier New', monospace;
11+
background: #0d0d12;
12+
color: #e0e0e0;
13+
padding: 20px;
14+
line-height: 1.6;
15+
}
16+
.container { max-width: 900px; margin: 0 auto; }
17+
h1 { color: #00ff88; margin-bottom: 20px; font-size: 24px; }
18+
label { display: block; margin-top: 15px; font-weight: bold; color: #00ff88; }
19+
textarea, input, select {
20+
width: 100%;
21+
padding: 10px;
22+
margin-top: 5px;
23+
background: #1a1a1f;
24+
border: 1px solid #333;
25+
color: #e0e0e0;
26+
font-family: inherit;
27+
font-size: 14px;
28+
}
29+
textarea { min-height: 200px; resize: vertical; }
30+
.row { display: flex; gap: 10px; }
31+
.row > * { flex: 1; }
32+
button {
33+
background: #00ff88;
34+
color: #0d0d12;
35+
border: none;
36+
padding: 12px 24px;
37+
font-weight: bold;
38+
cursor: pointer;
39+
margin-top: 20px;
40+
font-size: 16px;
41+
}
42+
button:hover { background: #00cc6a; }
43+
button:disabled { background: #333; color: #666; cursor: not-allowed; }
44+
#results {
45+
margin-top: 30px;
46+
padding: 20px;
47+
background: #1a1a1f;
48+
border: 1px solid #333;
49+
min-height: 100px;
50+
}
51+
.error { color: #ff4444; }
52+
.success { color: #00ff88; }
53+
.result-item {
54+
padding: 8px;
55+
margin: 5px 0;
56+
background: #0d0d12;
57+
border-left: 3px solid #00ff88;
58+
}
59+
.status {
60+
color: #888;
61+
font-size: 12px;
62+
margin-top: 10px;
63+
}
64+
small { color: #888; }
65+
</style>
66+
</head>
67+
<body>
68+
<div class="container">
69+
<h1>🎰 Motely Seed Finder</h1>
70+
71+
<label for="jaml">JAML Filter *</label>
72+
<textarea id="jaml" placeholder='Paste JAML here'></textarea>
73+
74+
<div class="row">
75+
<div>
76+
<label for="threadCount">Threads</label>
77+
<input type="number" id="threadCount" value="4" min="1">
78+
</div>
79+
<div>
80+
<label for="batchCharCount">Batch Chars</label>
81+
<input type="number" id="batchCharCount" value="8" min="1" max="8">
82+
</div>
83+
</div>
84+
85+
<div class="row">
86+
<div>
87+
<label for="startBatch">Start Batch</label>
88+
<input type="number" id="startBatch" placeholder="Optional">
89+
</div>
90+
<div>
91+
<label for="endBatch">End Batch</label>
92+
<input type="number" id="endBatch" placeholder="Optional">
93+
</div>
94+
</div>
95+
96+
<label for="specificSeed">Specific Seed</label>
97+
<input type="text" id="specificSeed" placeholder="e.g., BALATRO1">
98+
99+
<label for="keyword">Keyword</label>
100+
<input type="text" id="keyword" placeholder="e.g., LUCKY">
101+
102+
<label for="padding">Padding</label>
103+
<input type="text" id="padding" placeholder="e.g., ABC">
104+
105+
<div class="row">
106+
<div>
107+
<label for="randomSeeds">Random Seeds</label>
108+
<input type="number" id="randomSeeds" placeholder="Optional">
109+
</div>
110+
<div style="padding-top: 30px;">
111+
<label><input type="checkbox" id="palindrome" style="width:auto"> Palindrome</label>
112+
</div>
113+
</div>
114+
115+
<button id="searchBtn" onclick="runSearch()">Search</button>
116+
117+
<div id="results">
118+
<p class="status">Paste your JAML filter and hit Search.</p>
119+
</div>
120+
</div>
121+
122+
<script type="module">
123+
// NOTE: Update this import path to match your motely-wasm package location
124+
// For local testing: './Motely.npm-staging/motely-wasm/dist/index.mjs'
125+
// For published npm: 'https://unpkg.com/motely-wasm@latest/dist/index.mjs'
126+
127+
let MotelyWasm = null;
128+
let searchRunning = false;
129+
130+
async function loadWasm() {
131+
try {
132+
const module = await import('./Motely.npm-staging/motely-wasm/dist/index.mjs');
133+
MotelyWasm = module;
134+
document.getElementById('results').innerHTML = '<p class="success">✓ WASM ready</p>';
135+
} catch (err) {
136+
document.getElementById('results').innerHTML =
137+
`<p class="error">✗ Failed to load WASM: ${err.message}</p>`;
138+
}
139+
}
140+
141+
loadWasm();
142+
143+
window.runSearch = async function() {
144+
if (!MotelyWasm) {
145+
alert('WASM not loaded. Wait and try again.');
146+
return;
147+
}
148+
149+
const jaml = document.getElementById('jaml').value.trim();
150+
if (!jaml) {
151+
alert('Paste a JAML filter first.');
152+
return;
153+
}
154+
155+
const options = {
156+
threadCount: parseInt(document.getElementById('threadCount').value) || 4,
157+
batchCharCount: parseInt(document.getElementById('batchCharCount').value) || 8,
158+
};
159+
160+
const val = (id) => document.getElementById(id).value.trim();
161+
if (val('startBatch')) options.startBatch = parseInt(val('startBatch'));
162+
if (val('endBatch')) options.endBatch = parseInt(val('endBatch'));
163+
if (val('specificSeed')) options.specificSeed = val('specificSeed');
164+
if (val('keyword')) options.keyword = val('keyword');
165+
if (val('padding')) options.padding = val('padding');
166+
if (val('randomSeeds')) options.randomSeeds = parseInt(val('randomSeeds'));
167+
options.palindrome = document.getElementById('palindrome').checked;
168+
169+
searchRunning = true;
170+
document.getElementById('searchBtn').disabled = true;
171+
document.getElementById('results').innerHTML = '<p class="status">Searching...</p>';
172+
173+
try {
174+
let resultCount = 0;
175+
const result = await MotelyWasm.runSearch(jaml, options, {
176+
onProgress: (searched, found, elapsed) => {
177+
const status = document.querySelector('.status');
178+
if (status) status.textContent =
179+
`Searched: ${searched} | Found: ${found} | Elapsed: ${elapsed}ms`;
180+
},
181+
onResult: (seed, score) => {
182+
resultCount++;

0 commit comments

Comments
 (0)