jaml-ui 0.20.1 → 0.21.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/dist/assets.d.ts +0 -5
- package/dist/assets.js +0 -7
- package/dist/components/JamlCurator.d.ts +1 -2
- package/dist/components/JamlCurator.js +2 -2
- package/dist/hooks/searchWorker.d.ts +1 -0
- package/dist/hooks/searchWorker.js +68 -0
- package/dist/hooks/useSearch.d.ts +1 -1
- package/dist/hooks/useSearch.js +8 -13
- package/dist/render/CanvasRenderer.js +2 -2
- package/dist/ui/hooks.d.ts +13 -0
- package/dist/ui/hooks.js +44 -0
- package/dist/ui/jimbo.css +1092 -1086
- package/dist/ui/panel.d.ts +1 -1
- package/dist/ui/panel.js +7 -6
- package/package.json +1 -1
package/dist/assets.d.ts
CHANGED
|
@@ -18,8 +18,3 @@ export declare function setJamlAssetBaseUrl(baseUrl: string | null | undefined):
|
|
|
18
18
|
export declare function clearJamlAssetBaseUrl(): void;
|
|
19
19
|
export declare function resolveJamlAssetUrl(asset: JamlAssetKey | JamlAssetFile): string;
|
|
20
20
|
export declare function getDefaultJamlAssetUrlMap(): Readonly<Record<JamlAssetKey, string>>;
|
|
21
|
-
/**
|
|
22
|
-
* Returns the versioned Vercel Blob URL for motely-wasm's Bootsharp module.
|
|
23
|
-
* Pass the same pinned motely-wasm version the app installed/uploaded.
|
|
24
|
-
*/
|
|
25
|
-
export declare function getMotelyWasmUrl(version: string): string;
|
package/dist/assets.js
CHANGED
|
@@ -68,10 +68,3 @@ export function resolveJamlAssetUrl(asset) {
|
|
|
68
68
|
export function getDefaultJamlAssetUrlMap() {
|
|
69
69
|
return defaultAssetUrls;
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Returns the versioned Vercel Blob URL for motely-wasm's Bootsharp module.
|
|
73
|
-
* Pass the same pinned motely-wasm version the app installed/uploaded.
|
|
74
|
-
*/
|
|
75
|
-
export function getMotelyWasmUrl(version) {
|
|
76
|
-
return `https://cdn.seedfinder.app/motely-wasm/${version}/index.mjs`;
|
|
77
|
-
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export interface JamlCuratorProps {
|
|
2
|
-
motelyWasmUrl: string;
|
|
3
2
|
}
|
|
4
|
-
export declare function JamlCurator({
|
|
3
|
+
export declare function JamlCurator({}: JamlCuratorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -11,10 +11,10 @@ import { useSearch } from "../hooks/useSearch.js";
|
|
|
11
11
|
import { useAnalyzer } from "../hooks/useAnalyzer.js";
|
|
12
12
|
import { JamlSpeedometer } from "./JamlSpeedometer.js";
|
|
13
13
|
const C = JimboColorOption;
|
|
14
|
-
export function JamlCurator({
|
|
14
|
+
export function JamlCurator({}) {
|
|
15
15
|
// Use map editor by default to generate JAML
|
|
16
16
|
const [jamlText, setJamlText] = useState("");
|
|
17
|
-
const search = useSearch(
|
|
17
|
+
const search = useSearch();
|
|
18
18
|
const analyzer = useAnalyzer();
|
|
19
19
|
// Search results pagination
|
|
20
20
|
const [resultIndex, setResultIndex] = useState(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import motely, { MotelyWasm, MotelyWasmEvents } from "motely-wasm";
|
|
2
|
+
// Boot motely immediately when this module is loaded
|
|
3
|
+
motely.boot().catch(console.error);
|
|
4
|
+
let activeSearch = null;
|
|
5
|
+
self.addEventListener('message', function (e) {
|
|
6
|
+
const msg = e.data;
|
|
7
|
+
if (msg.type === 'start') {
|
|
8
|
+
const validation = MotelyWasm.validateJaml(msg.jaml);
|
|
9
|
+
if (validation !== 'valid') {
|
|
10
|
+
self.postMessage({ type: 'error', message: validation });
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
function cleanup() {
|
|
14
|
+
MotelyWasmEvents.notifyResult = () => { };
|
|
15
|
+
MotelyWasmEvents.notifyProgress = () => { };
|
|
16
|
+
MotelyWasmEvents.notifyComplete = () => { };
|
|
17
|
+
activeSearch = null;
|
|
18
|
+
}
|
|
19
|
+
MotelyWasmEvents.notifyResult = function (seed, score, tallyColumns) {
|
|
20
|
+
self.postMessage({ type: 'result', seed, score, tallyColumns: Array.from(tallyColumns) });
|
|
21
|
+
};
|
|
22
|
+
MotelyWasmEvents.notifyProgress = function (searched, matching) {
|
|
23
|
+
self.postMessage({ type: 'progress', searched: searched.toString(), matching: matching.toString() });
|
|
24
|
+
};
|
|
25
|
+
MotelyWasmEvents.notifyComplete = function (status, searched, matched) {
|
|
26
|
+
cleanup();
|
|
27
|
+
self.postMessage({ type: 'complete', status, searched: searched.toString(), matched: matched.toString() });
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
const mode = msg.mode || 'random';
|
|
31
|
+
if (mode === 'random') {
|
|
32
|
+
activeSearch = MotelyWasm.startRandomSearch(msg.jaml, msg.count);
|
|
33
|
+
}
|
|
34
|
+
else if (mode === 'aesthetic') {
|
|
35
|
+
activeSearch = MotelyWasm.startAestheticSearch(msg.jaml, msg.aesthetic);
|
|
36
|
+
}
|
|
37
|
+
else if (mode === 'seedList') {
|
|
38
|
+
activeSearch = MotelyWasm.startSeedListSearch(msg.jaml, msg.seeds);
|
|
39
|
+
}
|
|
40
|
+
else if (mode === 'keyword') {
|
|
41
|
+
activeSearch = MotelyWasm.startKeywordSearch(msg.jaml, msg.keywords, msg.padding || '');
|
|
42
|
+
}
|
|
43
|
+
else if (mode === 'sequential') {
|
|
44
|
+
activeSearch = MotelyWasm.startSequentialSearch(msg.jaml, msg.batchCharCount, BigInt(msg.startBatch), BigInt(msg.endBatch));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
cleanup();
|
|
49
|
+
self.postMessage({ type: 'error', message: String(err) });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (msg.type === 'stop') {
|
|
53
|
+
if (activeSearch) {
|
|
54
|
+
activeSearch.cancel();
|
|
55
|
+
activeSearch = null;
|
|
56
|
+
self.postMessage({ type: 'cancelled' });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (msg.type === 'get_tally_labels') {
|
|
60
|
+
try {
|
|
61
|
+
const labels = MotelyWasm.getTallyLabels(msg.jaml);
|
|
62
|
+
self.postMessage({ type: 'tally_labels', labels: Array.from(labels) });
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
self.postMessage({ type: 'error', message: String(err) });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
@@ -13,7 +13,7 @@ export interface UseSearchState {
|
|
|
13
13
|
seedsPerSecond: number;
|
|
14
14
|
tallyLabels: string[];
|
|
15
15
|
}
|
|
16
|
-
export declare function useSearch(
|
|
16
|
+
export declare function useSearch(): {
|
|
17
17
|
start: (jaml: string, count: number) => void;
|
|
18
18
|
startAesthetic: (jaml: string, aesthetic: number) => void;
|
|
19
19
|
startSeedList: (jaml: string, seeds: string[]) => void;
|
package/dist/hooks/useSearch.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useState, useCallback, useRef, useEffect } from "react";
|
|
3
|
-
import
|
|
4
|
-
function createWorker(
|
|
5
|
-
|
|
6
|
-
const blobUrl = URL.createObjectURL(blob);
|
|
7
|
-
const worker = new Worker(blobUrl);
|
|
8
|
-
worker.postMessage({ type: "init", url: motelyWasmUrl });
|
|
9
|
-
return worker;
|
|
3
|
+
import SearchWorker from "./searchWorker.ts?worker&inline";
|
|
4
|
+
function createWorker() {
|
|
5
|
+
return new SearchWorker();
|
|
10
6
|
}
|
|
11
7
|
const INITIAL_STATE = {
|
|
12
8
|
results: [],
|
|
@@ -17,16 +13,15 @@ const INITIAL_STATE = {
|
|
|
17
13
|
seedsPerSecond: 0,
|
|
18
14
|
tallyLabels: [],
|
|
19
15
|
};
|
|
20
|
-
export function useSearch(
|
|
16
|
+
export function useSearch() {
|
|
21
17
|
const [state, setState] = useState(INITIAL_STATE);
|
|
22
18
|
const workerRef = useRef(null);
|
|
23
|
-
const readyRef = useRef(
|
|
19
|
+
const readyRef = useRef(true); // Worker is ready implicitly since boot is handled by import
|
|
24
20
|
const speedRef = useRef({ lastSearched: 0n, lastTime: 0, ema: 0 });
|
|
25
21
|
useEffect(() => {
|
|
26
|
-
setState((s) => ({ ...s, status: "
|
|
27
|
-
const worker = createWorker(
|
|
22
|
+
setState((s) => ({ ...s, status: "idle" }));
|
|
23
|
+
const worker = createWorker();
|
|
28
24
|
workerRef.current = worker;
|
|
29
|
-
readyRef.current = false;
|
|
30
25
|
worker.onmessage = (e) => {
|
|
31
26
|
const msg = e.data;
|
|
32
27
|
if (msg.type === "ready") {
|
|
@@ -88,7 +83,7 @@ export function useSearch(motelyWasmUrl) {
|
|
|
88
83
|
worker.terminate();
|
|
89
84
|
workerRef.current = null;
|
|
90
85
|
};
|
|
91
|
-
}, [
|
|
86
|
+
}, []);
|
|
92
87
|
const sendStart = useCallback((payload) => {
|
|
93
88
|
const worker = workerRef.current;
|
|
94
89
|
if (!worker)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useJamlCardRenderer } from "../ui/hooks.js";
|
|
4
4
|
export function JamlCardRenderer({ layers, invert = false, className = "", hoverTilt = false }) {
|
|
5
5
|
const { canvasRef, containerStyle, canvasStyle, handlers } = useJamlCardRenderer({
|
|
@@ -7,5 +7,5 @@ export function JamlCardRenderer({ layers, invert = false, className = "", hover
|
|
|
7
7
|
invert,
|
|
8
8
|
hoverTilt
|
|
9
9
|
});
|
|
10
|
-
return (
|
|
10
|
+
return (_jsxs("div", { className: className, style: { ...containerStyle, position: "relative" }, children: [_jsx("canvas", { ref: canvasRef, style: canvasStyle }), hoverTilt && (_jsx("div", { style: { position: "absolute", inset: "-15px", zIndex: 10, cursor: "pointer" }, ...handlers })), !hoverTilt && (_jsx("div", { style: { position: "absolute", inset: "0", zIndex: 10 }, ...handlers }))] }));
|
|
11
11
|
}
|
package/dist/ui/hooks.d.ts
CHANGED
|
@@ -87,3 +87,16 @@ export declare function useJamlIdeDrag(filter: JamlVisualFilter, onChange: (filt
|
|
|
87
87
|
hoverZone: string | null;
|
|
88
88
|
onDragStart: (e: React.MouseEvent | React.TouchEvent, clause: JamlVisualClause, fromZone: JamlZone) => void;
|
|
89
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Provides a magnetic 3D tilt effect for DOM elements, replicating the 'juice' of Balatro cards.
|
|
92
|
+
* Ensures the hit-detection area remains stable by separating container events from the transformed style.
|
|
93
|
+
*/
|
|
94
|
+
export declare function useDOMMagneticTilt(enabled?: boolean): {
|
|
95
|
+
handlers: {
|
|
96
|
+
onPointerEnter: ((event: React.PointerEvent) => void) | undefined;
|
|
97
|
+
onPointerLeave: (() => void) | undefined;
|
|
98
|
+
onPointerMove: ((event: React.PointerEvent) => void) | undefined;
|
|
99
|
+
};
|
|
100
|
+
tiltStyle: React.CSSProperties;
|
|
101
|
+
isHovered: boolean;
|
|
102
|
+
};
|
package/dist/ui/hooks.js
CHANGED
|
@@ -551,3 +551,47 @@ export function useJamlIdeDrag(filter, onChange, rootRef) {
|
|
|
551
551
|
onDragStart,
|
|
552
552
|
};
|
|
553
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* Provides a magnetic 3D tilt effect for DOM elements, replicating the 'juice' of Balatro cards.
|
|
556
|
+
* Ensures the hit-detection area remains stable by separating container events from the transformed style.
|
|
557
|
+
*/
|
|
558
|
+
export function useDOMMagneticTilt(enabled = true) {
|
|
559
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
560
|
+
const [transform, setTransform] = useState('none');
|
|
561
|
+
const onPointerEnter = (event) => {
|
|
562
|
+
if (!enabled || event.pointerType === 'touch')
|
|
563
|
+
return;
|
|
564
|
+
setIsHovered(true);
|
|
565
|
+
};
|
|
566
|
+
const onPointerLeave = () => {
|
|
567
|
+
if (!enabled)
|
|
568
|
+
return;
|
|
569
|
+
setIsHovered(false);
|
|
570
|
+
setTransform('none');
|
|
571
|
+
};
|
|
572
|
+
const onPointerMove = (event) => {
|
|
573
|
+
if (!enabled || event.pointerType === 'touch')
|
|
574
|
+
return;
|
|
575
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
576
|
+
const x = event.clientX - rect.left;
|
|
577
|
+
const y = event.clientY - rect.top;
|
|
578
|
+
const rotateY = (x / rect.width) * 12 - 6;
|
|
579
|
+
const rotateX = (y / rect.height) * -16 + 8;
|
|
580
|
+
const juiceScale = 1.05;
|
|
581
|
+
const juiceY = -2; // slight move up
|
|
582
|
+
setTransform(`perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${juiceScale}) translateY(${juiceY}px)`);
|
|
583
|
+
};
|
|
584
|
+
const handlers = {
|
|
585
|
+
onPointerEnter: enabled ? onPointerEnter : undefined,
|
|
586
|
+
onPointerLeave: enabled ? onPointerLeave : undefined,
|
|
587
|
+
onPointerMove: enabled ? onPointerMove : undefined,
|
|
588
|
+
};
|
|
589
|
+
const tiltStyle = {
|
|
590
|
+
transition: enabled && !isHovered ? 'transform 0.4s ease, box-shadow 0.4s ease-out' : 'transform 0.1s ease-out',
|
|
591
|
+
transform: enabled ? (isHovered ? transform : 'none') : undefined,
|
|
592
|
+
transformStyle: enabled ? 'preserve-3d' : undefined,
|
|
593
|
+
transformOrigin: enabled ? 'center center' : undefined,
|
|
594
|
+
willChange: enabled ? 'transform' : undefined,
|
|
595
|
+
};
|
|
596
|
+
return { handlers, tiltStyle, isHovered };
|
|
597
|
+
}
|