Package-level declarations
Types
Runtime access-widening requests from TypeScript (ratph6.tessera.api.AccessWidener). Like Fabric's static access widener, but applied live by MixinTransformer when a class is (re)loaded — so scripts can open up private/final Minecraft members on demand.
A module compiled to JVM bytecode by swc4j. Exported functions live on defaultClass as static methods; Tessera looks them up (and caches a MethodHandle) when a trigger needs to call one.
The execution engine a module runs on (see TesseraManifest.engine).
A raw GraalJS guest function. JavaScript tolerates arity mismatches (extra args ignored, missing ones become undefined), so every provided arg is passed through as-is. Must be called on the JS thread (the GraalJS org.graalvm.polyglot.Context is single-threaded) — which is where dispatch already runs.
A module evaluated as an ES module by GraalJS. Its top-level code already ran on load (so top-level Tessera.register(...) calls are live); namespace is the module's export namespace, from which named exported functions (for the main/init entry and trigger-name conventions) are read.
The GraalJS execution engine — the "real JavaScript" path. A Tessera module's TypeScript is first transpiled to JavaScript by swc4j (here used as a plain TS→JS transpiler, not its bytecode compiler) and then evaluated as an ES module on a GraalJS Context. Scripts get full ECMAScript: real arrays with .map/.filter, closures over reassigned lets, objects, JSON, etc. — none of the bytecode path's "half-Java" workarounds (Store/Num/Args).
A JVM-side callable invoked through a MethodHandle, padded/truncated to paramCount.
Obtains a live Instrumentation for the running JVM by loading a tiny java agent (see ratph6.tessera.agent.TesseraAgent). This is what lets TypeScript mixins rewrite Minecraft classes that are already loaded by the time a script runs — a static .mixins.json only gets a shot during early class loading.
Static entry points that the bytecode injected by MixinTransformer calls into. The signatures here are an ABI — MixinTransformer emits INVOKESTATIC calls against these exact names/descriptors, so changing them means changing the transformer too.
Front door for TypeScript mixins. Lazily self-attaches the instrumentation agent and installs MixinTransformer on the first injection, registers each hook in MixinRegistry, and triggers a retransform so the change takes effect immediately — even for Minecraft classes that are already loaded. Reverting (on /te reload or module unload) retransforms the affected classes back to their original bytes.
The set of TypeScript-defined injections currently active. Indexed two ways: by the internal class name (net/minecraft/...) so MixinTransformer can find what to inject when a class is (re)loaded, and by a small integer Hook.id that the injected bytecode passes back to MixinHooks to identify which callback to run.
The single retransform-capable ClassFileTransformer behind TypeScript mixins. For any class that has registered MixinRegistry hooks, it rewrites the matching methods to call MixinHooks — at HEAD (with the option to cancel or substitute the return value) and/or at every RETURN site.
Reflection-backed member access for scripts — the part of "access widening" that works on classes that are already loaded (where bytecode modifier-flipping is illegal). Mod code runs with full Java access and net.minecraft lives in the unnamed module, so setAccessible(true) succeeds; GraalJS can't reach java.lang.reflect itself, so these helpers are the bridge.
A script callback, normalized so the engine can invoke it the same way regardless of which engine produced it:
Compiles a Tessera script (TypeScript / modern JS) straight to JVM bytecode using swc4j's ByteCodeCompiler. Scripts run as native JVM classes — every export function becomes a static method on the default $ class, and scripts reach the Tessera API by importing our Kotlin objects by package, e.g. import { Tessera, Event } from 'ratph6.tessera.api'.
The heart of Tessera. Compiles each module's TypeScript to JVM bytecode (via TesseraCompiler), invokes its main() entry point, and dispatches triggers by invoking the named exported function through a cached MethodHandle. No V8, no JNI on the dispatch path.
A captured script error, surfaced by /te errors and the console. stack is the full chain.
Static entry points that mixins (Java) call into. Kept dependency-light so the mixin classes don't need to know about Kotlin object instances.
Discovers and compiles modules under <gameDir>/tessera/modules/<moduleName>/.
Parsed tessera.json manifest.
A compiled, loaded module. Engine-agnostic surface: its manifest/dir, the names of its exported functions, and a uniform TesseraCallback for any one of them. Two implementations:
Bridge between the entity-render mixin and the engine. Called on the render thread (which is the JS thread), once before and once after each entity model is submitted, with the live PoseStack.
EntityRenderState so Tessera can recover the live Entity behind a render state.