Skip to content

Use static builders instead of constructors#945

Merged
tomusdrw merged 9 commits into
mainfrom
td-host-call-regs
Apr 20, 2026
Merged

Use static builders instead of constructors#945
tomusdrw merged 9 commits into
mainfrom
td-host-call-regs

Conversation

@tomusdrw
Copy link
Copy Markdown
Member

  • Use builder methods for HostCallRegisters
  • Refactor classes to use static builder methods.
  • Convert more classes to use static builder

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Switched many components to factory-style construction (static new/empty) and made constructors non-public, standardizing instantiation and tightening encapsulation. Tests and internal call sites updated accordingly. No runtime behavior or public APIs changed.

Walkthrough

This changeset systematically replaces public constructors with controlled factory entry points across many modules. Most classes gain static factory methods (commonly new, fromRaw, assemble, forService) and their original constructors are made private/protected. All call sites were updated to use the new factories. No business logic, control flow, or runtime behavior was changed beyond instantiation and constructor visibility adjustments.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • Networking refactor #436 — Overlaps with the IPC/JAMNP handler and EnvelopeSender/IpcSender factory refactors present in this change.
  • Refactor PartialStateDb #520 — Related to accumulate-externalities / PartiallyUpdatedState factory-style refactors introduced in this PR.
  • Initial refine #859 — Touches RpcServer and related factory/constructor changes similar to those applied in this changeset.

Suggested reviewers

  • skoszuta
  • mateuszsikora
  • DrEverr

"I hopped through files with tidy paws,
Swapping new for factories, following laws.
Private gates now guard each clever art,
Instances summoned from a single start.
A rabbit nods — constructors depart." 🐇

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch td-host-call-regs

@tomusdrw tomusdrw changed the title Use static builder instead of constructors Use static builders instead of constructors Apr 16, 2026
@tomusdrw tomusdrw marked this pull request as ready for review April 16, 2026 20:57
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/core/networking/quic-peer.ts (1)

24-47: 🛠️ Refactor suggestion | 🟠 Major

Move side-effect setup out of the constructor.

The constructor still performs logging and event wiring, so it is not data-initialization-only. Move this setup into QuicPeer.new(...) (or an init method called by it) to fully match the factory pattern.

Suggested refactor
 export class QuicPeer implements Peer {
@@
   static new(conn: QUICConnection, peerInfo: PeerInfo) {
-    return new QuicPeer(conn, peerInfo);
+    const peer = new QuicPeer(conn, peerInfo);
+    logger.log`👥 [${peerInfo.id}] peer connected ${conn.remoteHost}:${conn.remotePort}`;
+    peer.bindConnectionEvents();
+    return peer;
   }

   private constructor(
     public readonly conn: QUICConnection,
     peerInfo: PeerInfo,
   ) {
-    logger.log`👥 [${peerInfo.id}] peer connected ${conn.remoteHost}:${conn.remotePort}`;
-
     this.connectionId = conn.connectionIdShared.toString();
@@
     this.id = peerInfo.id;
     this.key = peerInfo.key;
+  }
 
-    addEventListener(conn, events.EventQUICConnectionStream, (ev) => {
+  private bindConnectionEvents(): void {
+    addEventListener(this.conn, events.EventQUICConnectionStream, (ev) => {
       const stream = ev.detail;
       logger.log`🚰  [${this.id}] new stream: [${stream.streamId}]`;
       this.streamEvents.emit("stream", QuicStream.new(stream));
     });
 
-    addEventListener(conn, events.EventQUICConnectionError, (err) => {
+    addEventListener(this.conn, events.EventQUICConnectionError, (err) => {
       logger.error`❌ [${this.id}] connection failed: ${err.detail}`;
     });
   }

As per coding guidelines, constructors should be “data initialization only” with no instantiation control flow; move any creation/validation logic into the builder/factory.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/networking/quic-peer.ts` around lines 24 - 47, The constructor
currently performs side effects (logging and event wiring using
logger.log/logger.error and addEventListener for
events.EventQUICConnectionStream and events.EventQUICConnectionError, and
emitting to this.streamEvents), so refactor by moving all non-field
initialization into a new init method (e.g., QuicPeer.init or performSetup) and
call that from the factory QuicPeer.new(...); keep the constructor as
data-initialization-only (assigning this.conn, this.connectionId, this.address,
this.id, this.key), then implement the init method to attach the
addEventListener handlers (wrapping stream -> this.streamEvents.emit("stream",
QuicStream.new(stream))) and the logging, and ensure QuicPeer.new invokes the
init method before returning the instance so behavior is unchanged.
packages/jam/state/in-memory-state.ts (1)

141-148: ⚠️ Potential issue | 🟡 Minor

clone() is still shallow despite the no-shared-references contract.

Lines 143-147 duplicate the containers, but the contained PreimageItem, StorageItem, and LookupHistoryItem objects are still reused. Either deep-copy those nested items too, or relax the docstring.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/state/in-memory-state.ts` around lines 141 - 148, The current
clone path in InMemoryService.new uses HashDictionary.fromEntries and new Map to
copy containers but leaves nested objects (values in this.data.preimages,
this.data.storage and the entries inside this.data.lookupHistory) as shared
references; update the clone to deep-copy those nested PreimageItem, StorageItem
and LookupHistoryItem values (e.g., map over this.data.preimages.entries() and
this.data.storage.entries() and produce new value objects, and for lookupHistory
map and clone each HistoryItem inside each array) instead of reusing them — you
can use structuredClone or each domain type’s own copy/constructor/`create`
helper where available; keep ServiceAccountInfo.create and the outer container
copies (HashDictionary.fromEntries / new Map) but ensure the contained items are
newly created.
🧹 Nitpick comments (8)
packages/jam/jamnp-s/stream-manager.ts (1)

139-163: Use the raw stream id string when composing StreamId.

At Line 140–141, converting stream.streamId through tryAsU32 is unnecessary for this identifier path and can make opaque StreamId handling brittle. Prefer composing with the original string value directly.

Suggested change
-    const quicStreamId = tryAsU32(stream.streamId);
-    const streamId = tryAsStreamId(`${peer.id}:${quicStreamId}`);
+    const streamId = tryAsStreamId(`${peer.id}:${stream.streamId}`);

Based on learnings: in packages/jam/jamnp-s/stream-manager.ts, composite StreamId values should use stream.streamId directly as a string, without U32 conversion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/jamnp-s/stream-manager.ts` around lines 139 - 163, The code
currently converts stream.streamId via tryAsU32 before composing the StreamId
which is brittle; in registerStream replace the two-line creation of
quicStreamId and streamId (which uses tryAsU32) with a single use of the raw
stream.streamId string when creating the StreamId (e.g., call tryAsStreamId with
`${peer.id}:${stream.streamId}`), remove the tryAsU32 usage and any dependent
quicStreamId variable, and ensure QuicStreamSender.new and any map keys
(this.streams / this.backgroundTasks) continue to use the new streamId value.
packages/jam/transition/hasher.ts (1)

10-15: Consider delegating create() to new(...) to keep a single construction path.

This avoids duplicate constructor wiring and keeps factory maintenance tighter.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/transition/hasher.ts` around lines 10 - 15, Change
TransitionHasher.create to call TransitionHasher.new so there is a single
construction path: obtain the two async hashers (keccak.KeccakHasher.create()
and Blake2b.createHasher()) then pass them into
TransitionHasher.new(keccakHasher, blake2b) instead of calling the constructor
directly. Update the static create method to await both factories, call
TransitionHasher.new with the resulting keccakHasher and blake2b, and return
that result, keeping the existing static new(keccakHasher, blake2b) and
constructor intact.
packages/core/hash/hash.ts (1)

42-45: Constructor visibility is still broader than the factory-only contract.

Using protected still permits subclass-based construction paths that bypass centralized builders. If strict instantiation control is intended, move to private constructors (or adjust inheritance structure accordingly).

As per coding guidelines: "Prefer static new(...)/*.new style factory methods and keep the actual constructor private."

Also applies to: 58-63

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/hash/hash.ts` around lines 42 - 45, The constructor(s) in this
file (the Hash class constructors declared as "protected constructor" around the
current Hash/THash/TData declarations and the second constructor at the later
block) must be made private to enforce factory-only instantiation; change both
protected constructors to private and ensure any existing factory functions
(e.g., static new / .new methods or factory functions that create instances of
the Hash class) are used/updated to construct instances instead of relying on
subclassing; if any subclass currently calls super(...), refactor that subclass
to use a provided static factory on Hash or adjust the inheritance to avoid
direct construction.
packages/jam/config/chain-spec.ts (1)

85-91: Prefer a dedicated ChainSpecArgs type over Omit<ChainSpec, ...>.

Omit<ChainSpec, ...> couples constructor input to the full instance type. Defining an explicit args type will keep the factory contract stable and easier to reason about.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/config/chain-spec.ts` around lines 85 - 91, Introduce a
dedicated type alias (e.g. ChainSpecArgs) defined as the current Omit<ChainSpec,
"validatorsSuperMajority" | "thirdOfValidators" | "erasureCodedPieceSize"> and
replace the inline Omit usage in both the static new method signature and the
private constructor signature with ChainSpecArgs; update any references to the
constructor/new to use the new alias so the factory contract no longer depends
directly on the full ChainSpec shape.
packages/jam/transition/chain-stf.ts (1)

137-157: Move collaborator wiring from constructor into assemble(...).

assemble(...) currently just forwards arguments, while instantiation control flow still lives in the constructor. Consider making the constructor assignment-only and doing object wiring in the static factory.

As per coding guidelines, constructors should be “data initialization only” (assign fields) and instantiation logic should be moved into static builders/factories.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/transition/chain-stf.ts` around lines 137 - 157, The constructor
of OnChain should be reduced to plain data initialization (assigning chainSpec,
state, hasher, options, headerChain) and any collaborator wiring currently
inside the constructor must be moved into the static assemble(...) factory;
change assemble(...) to instantiate the object (new OnChain(...)) and then
perform all setup/wiring (registering listeners, hooking headerChain,
initializing dependent services, etc.) on that instance before returning it, and
remove those wiring steps from the OnChain constructor so it only assigns fields
(referencing assemble, OnChain constructor, and fields chainSpec, state, hasher,
options, headerChain).
packages/jam/transition/reports/test.utils.ts (1)

329-350: Reuse the existing id variable for service construction.

Tiny readability cleanup: avoid recomputing tryAsServiceId(129) when id already exists in scope.

Proposed diff
-    InMemoryService.new(tryAsServiceId(129), {
+    InMemoryService.new(id, {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/transition/reports/test.utils.ts` around lines 329 - 350,
Replace the duplicated tryAsServiceId(129) call with the existing id variable so
the InMemoryService.new invocation uses id (the pre-existing service identifier)
instead of recomputing tryAsServiceId(129); update the constructor call where
InMemoryService.new(...) is invoked and ensure any surrounding references
(preimages, storage, info) remain unchanged and still match the id usage.
packages/jam/transition/externalities/accumulate-externalities.test.ts (1)

71-78: Extract a test helper for AccumulateExternalities.forService setup.

The same object literal is duplicated many times; a local helper would cut boilerplate and keep defaults consistent.

♻️ Suggested refactor pattern
+function forServiceExt(state: PartiallyUpdatedState, currentServiceId = tryAsServiceId(0), currentTimeslot = tryAsTimeSlot(16)) {
+  return AccumulateExternalities.forService({
+    chainSpec: tinyChainSpec,
+    blake2b,
+    updatedState: state,
+    currentServiceId,
+    nextNewServiceIdCandidate: tryAsServiceId(10),
+    currentTimeslot,
+  });
+}
...
-const partialState = AccumulateExternalities.forService({
-  chainSpec: tinyChainSpec,
-  blake2b: blake2b,
-  updatedState: state,
-  currentServiceId: tryAsServiceId(0),
-  nextNewServiceIdCandidate: tryAsServiceId(10),
-  currentTimeslot: tryAsTimeSlot(16),
-});
+const partialState = forServiceExt(state);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/transition/externalities/accumulate-externalities.test.ts`
around lines 71 - 78, Extract a test helper function (e.g.,
makeAccumulateExternalitiesArgs or buildForServiceOpts) that returns the common
argument object used for AccumulateExternalities.forService so tests reuse
defaults (tinyChainSpec, blake2b, state, tryAsServiceId(0), tryAsServiceId(10),
tryAsTimeSlot(16)); update each test to call
AccumulateExternalities.forService(helper()) and override only fields that
differ per test (e.g., currentServiceId or updatedState) to remove duplicated
object literals and keep defaults consistent across tests.
packages/jam/transition/externalities/accumulate-externalities.ts (1)

96-102: Prefer returning Result from forService validation instead of throwing.

Line 99 introduces exception-based control flow for an expected validation failure. Consider making forService return Result so callers can handle this path explicitly.

♻️ Proposed refactor
-  static forService(args: AccumulateExternalitiesArgs) {
+  static forService(args: AccumulateExternalitiesArgs): Result<AccumulateExternalities, "missing_service_info"> {
     const service = args.updatedState.getServiceInfo(args.currentServiceId);
     if (service === null) {
-      throw new Error(`Invalid state initialization. Service info missing for ${args.currentServiceId}.`);
+      return Result.error(
+        "missing_service_info",
+        () => `Invalid state initialization. Service info missing for ${args.currentServiceId}.`,
+      );
     }
-    return new AccumulateExternalities(args);
+    return Result.ok(new AccumulateExternalities(args));
   }

As per coding guidelines: "Prefer Result over throwing; avoid relying on catching specific exceptions."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/transition/externalities/accumulate-externalities.ts` around
lines 96 - 102, forService currently throws when getServiceInfo returns null;
change its signature to return a Result<AccumulateExternalities,
ValidationError> (or your project's Result type) instead of throwing: call
args.updatedState.getServiceInfo(args.currentServiceId), and if null return Err
with a descriptive validation error referencing args.currentServiceId, otherwise
return Ok(new AccumulateExternalities(args)); update the function signature and
any callers of forService to handle the Result rather than relying on
exceptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/collections/multi-map.ts`:
- Around line 31-37: Move the instantiation validation out of the private
constructor and into the static factory new<TKeys extends readonly unknown[],
TValue>(keysLength: TKeys["length"], keyMappers?: KeyMappers<TKeys>) method:
remove the check`${keysLength > 0} Keys cannot be empty.` and check`${keyMappers
=== undefined || keyMappers.length === keysLength} Incorrect number of key
mappers given!` calls from the MultiMap constructor and add those checks at the
start of MultiMap.new before calling new MultiMap(...), keeping the constructor
strictly data-initialization only (assign fields).

In `@packages/core/pvm-interpreter/program-decoder/jump-table.ts`:
- Line 15: Update the validation error message in jump-table.ts to fix the typo
"item lenght" to "item length" so diagnostics read "Length of jump table
(${bytes.length}) should be a multiple of item length (${itemByteLength})!";
locate the string in the code that constructs this message (around the jump
table length validation that references bytes.length and itemByteLength) and
replace the misspelled word only.
- Around line 12-21: The fromRaw validation currently allows itemByteLength ===
0 with non-empty bytes and then the JumpTable constructor forces length to 0,
silently dropping data; update fromRaw in class JumpTable to reject non-empty
bytes when itemByteLength is 0 by asserting bytes.length === 0 in that branch
(i.e. require either itemByteLength > 0 and bytes.length % itemByteLength === 0,
or itemByteLength === 0 and bytes.length === 0) and keep a clear error message
referencing bytes.length and itemByteLength so malformed input is surfaced
instead of being discarded; adjust the check surrounding fromRaw and leave the
private constructor (JumpTable) behavior unchanged.

In `@packages/core/pvm-interpreter/registers.ts`:
- Around line 23-30: The fromBytes(bytes: Uint8Array) method must validate
8-byte alignment before creating BigInt64Array/BigUint64Array views to avoid a
RangeError; add a check that bytes.byteOffset % 8 === 0 (in addition to the
existing size check) and throw a clear error (e.g., via the same check`...`
helper) if misaligned, so that Registers constructor and the creation of
this.asSigned / this.asUnsigned only run on properly aligned buffers.

In `@packages/core/trie/nodesDb.ts`:
- Around line 62-65: WriteableNodesDb must declare an explicit private
constructor to call the protected parent constructor and enforce factory-only
creation; add a private constructor in class WriteableNodesDb that accepts
(hasher: TrieHasher) and calls super(hasher), then keep the existing static
new(hasher: TrieHasher) factory as the only public creation point to satisfy
TypeScript and the project's guideline of private constructors with static
builders.

In `@packages/jam/jamnp-s/protocol/ce-133-work-package-submission.ts`:
- Around line 77-79: ClientHandler currently exposes an implicit public
constructor so calling new ClientHandler() bypasses the static factory; make the
constructor explicit and private (add a private constructor method to the
ClientHandler class) so instances can only be created via the existing static
new() factory method — locate the ClientHandler class and add a private
constructor definition to enforce the factory-only pattern used by
ServerHandler.

In `@packages/jam/jamnp-s/protocol/ce-134-work-package-sharing.ts`:
- Around line 127-129: ClientHandler currently exposes public construction via
the implicit constructor even though it provides a static new() factory; add an
explicit private constructor to ClientHandler (matching the pattern used by
ServerHandler) so external code cannot call new ClientHandler() directly,
leaving the static new() method as the only public instantiation path.

In `@packages/jam/state/in-memory-state.ts`:
- Around line 91-100: The constructor of InMemoryService is currently protected
which allows subclass instantiation; change the constructor visibility to
private so instances can only be created via the static new(serviceId:
ServiceId, data: InMemoryServiceData) factory; update the constructor
declaration in the InMemoryService class (the constructor handling readonly
serviceId and data) to be private and ensure no internal subclasses rely on
protected access (adjust or remove subclassing/tests if present).

---

Outside diff comments:
In `@packages/core/networking/quic-peer.ts`:
- Around line 24-47: The constructor currently performs side effects (logging
and event wiring using logger.log/logger.error and addEventListener for
events.EventQUICConnectionStream and events.EventQUICConnectionError, and
emitting to this.streamEvents), so refactor by moving all non-field
initialization into a new init method (e.g., QuicPeer.init or performSetup) and
call that from the factory QuicPeer.new(...); keep the constructor as
data-initialization-only (assigning this.conn, this.connectionId, this.address,
this.id, this.key), then implement the init method to attach the
addEventListener handlers (wrapping stream -> this.streamEvents.emit("stream",
QuicStream.new(stream))) and the logging, and ensure QuicPeer.new invokes the
init method before returning the instance so behavior is unchanged.

In `@packages/jam/state/in-memory-state.ts`:
- Around line 141-148: The current clone path in InMemoryService.new uses
HashDictionary.fromEntries and new Map to copy containers but leaves nested
objects (values in this.data.preimages, this.data.storage and the entries inside
this.data.lookupHistory) as shared references; update the clone to deep-copy
those nested PreimageItem, StorageItem and LookupHistoryItem values (e.g., map
over this.data.preimages.entries() and this.data.storage.entries() and produce
new value objects, and for lookupHistory map and clone each HistoryItem inside
each array) instead of reusing them — you can use structuredClone or each domain
type’s own copy/constructor/`create` helper where available; keep
ServiceAccountInfo.create and the outer container copies
(HashDictionary.fromEntries / new Map) but ensure the contained items are newly
created.

---

Nitpick comments:
In `@packages/core/hash/hash.ts`:
- Around line 42-45: The constructor(s) in this file (the Hash class
constructors declared as "protected constructor" around the current
Hash/THash/TData declarations and the second constructor at the later block)
must be made private to enforce factory-only instantiation; change both
protected constructors to private and ensure any existing factory functions
(e.g., static new / .new methods or factory functions that create instances of
the Hash class) are used/updated to construct instances instead of relying on
subclassing; if any subclass currently calls super(...), refactor that subclass
to use a provided static factory on Hash or adjust the inheritance to avoid
direct construction.

In `@packages/jam/config/chain-spec.ts`:
- Around line 85-91: Introduce a dedicated type alias (e.g. ChainSpecArgs)
defined as the current Omit<ChainSpec, "validatorsSuperMajority" |
"thirdOfValidators" | "erasureCodedPieceSize"> and replace the inline Omit usage
in both the static new method signature and the private constructor signature
with ChainSpecArgs; update any references to the constructor/new to use the new
alias so the factory contract no longer depends directly on the full ChainSpec
shape.

In `@packages/jam/jamnp-s/stream-manager.ts`:
- Around line 139-163: The code currently converts stream.streamId via tryAsU32
before composing the StreamId which is brittle; in registerStream replace the
two-line creation of quicStreamId and streamId (which uses tryAsU32) with a
single use of the raw stream.streamId string when creating the StreamId (e.g.,
call tryAsStreamId with `${peer.id}:${stream.streamId}`), remove the tryAsU32
usage and any dependent quicStreamId variable, and ensure QuicStreamSender.new
and any map keys (this.streams / this.backgroundTasks) continue to use the new
streamId value.

In `@packages/jam/transition/chain-stf.ts`:
- Around line 137-157: The constructor of OnChain should be reduced to plain
data initialization (assigning chainSpec, state, hasher, options, headerChain)
and any collaborator wiring currently inside the constructor must be moved into
the static assemble(...) factory; change assemble(...) to instantiate the object
(new OnChain(...)) and then perform all setup/wiring (registering listeners,
hooking headerChain, initializing dependent services, etc.) on that instance
before returning it, and remove those wiring steps from the OnChain constructor
so it only assigns fields (referencing assemble, OnChain constructor, and fields
chainSpec, state, hasher, options, headerChain).

In `@packages/jam/transition/externalities/accumulate-externalities.test.ts`:
- Around line 71-78: Extract a test helper function (e.g.,
makeAccumulateExternalitiesArgs or buildForServiceOpts) that returns the common
argument object used for AccumulateExternalities.forService so tests reuse
defaults (tinyChainSpec, blake2b, state, tryAsServiceId(0), tryAsServiceId(10),
tryAsTimeSlot(16)); update each test to call
AccumulateExternalities.forService(helper()) and override only fields that
differ per test (e.g., currentServiceId or updatedState) to remove duplicated
object literals and keep defaults consistent across tests.

In `@packages/jam/transition/externalities/accumulate-externalities.ts`:
- Around line 96-102: forService currently throws when getServiceInfo returns
null; change its signature to return a Result<AccumulateExternalities,
ValidationError> (or your project's Result type) instead of throwing: call
args.updatedState.getServiceInfo(args.currentServiceId), and if null return Err
with a descriptive validation error referencing args.currentServiceId, otherwise
return Ok(new AccumulateExternalities(args)); update the function signature and
any callers of forService to handle the Result rather than relying on
exceptions.

In `@packages/jam/transition/hasher.ts`:
- Around line 10-15: Change TransitionHasher.create to call TransitionHasher.new
so there is a single construction path: obtain the two async hashers
(keccak.KeccakHasher.create() and Blake2b.createHasher()) then pass them into
TransitionHasher.new(keccakHasher, blake2b) instead of calling the constructor
directly. Update the static create method to await both factories, call
TransitionHasher.new with the resulting keccakHasher and blake2b, and return
that result, keeping the existing static new(keccakHasher, blake2b) and
constructor intact.

In `@packages/jam/transition/reports/test.utils.ts`:
- Around line 329-350: Replace the duplicated tryAsServiceId(129) call with the
existing id variable so the InMemoryService.new invocation uses id (the
pre-existing service identifier) instead of recomputing tryAsServiceId(129);
update the constructor call where InMemoryService.new(...) is invoked and ensure
any surrounding references (preimages, storage, info) remain unchanged and still
match the id usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 95fad167-92fc-462c-8961-6defcc577f33

📥 Commits

Reviewing files that changed from the base of the PR and between ec38e0b and 8ef7915.

📒 Files selected for processing (248)
  • bin/ipc2rpc/client.ts
  • bin/jam/index.ts
  • bin/lib/examples/pvm-usage.test.ts
  • bin/pvm/index.ts
  • bin/rpc/main.ts
  • bin/rpc/src/handlers/typeberry/refine-work-package.ts
  • bin/rpc/src/server.ts
  • bin/rpc/src/subscription-manager.ts
  • bin/rpc/test/e2e.ts
  • bin/test-runner/common.ts
  • bin/test-runner/index.ts
  • bin/test-runner/reporter.ts
  • bin/test-runner/state-transition/state-transition.ts
  • bin/test-runner/w3f/preimages.ts
  • bin/test-runner/w3f/pvm-gas-cost.ts
  • bin/test-runner/w3f/pvm.ts
  • packages/core/codec/descriptor.ts
  • packages/core/codec/descriptors.ts
  • packages/core/codec/index.test.ts
  • packages/core/codec/skip.ts
  • packages/core/codec/view.ts
  • packages/core/collections/multi-map.test.ts
  • packages/core/collections/multi-map.ts
  • packages/core/concurrent/parent.ts
  • packages/core/crypto/ed25519.ts
  • packages/core/hash/hash.ts
  • packages/core/networking/quic-network.ts
  • packages/core/networking/quic-peer.ts
  • packages/core/networking/quic-stream.ts
  • packages/core/networking/setup.ts
  • packages/core/pvm-host-calls/bin.ts
  • packages/core/pvm-host-calls/ecalli-trace-logger.test.ts
  • packages/core/pvm-host-calls/host-call-memory.test.ts
  • packages/core/pvm-host-calls/host-call-memory.ts
  • packages/core/pvm-host-calls/host-call-registers.test.ts
  • packages/core/pvm-host-calls/host-call-registers.ts
  • packages/core/pvm-host-calls/host-calls-executor.ts
  • packages/core/pvm-host-calls/host-calls.ts
  • packages/core/pvm-host-calls/pvm-instance-manager.ts
  • packages/core/pvm-interpreter-ananas/index.ts
  • packages/core/pvm-interpreter/args-decoder/args-decoder.test.ts
  • packages/core/pvm-interpreter/args-decoder/args-decoder.ts
  • packages/core/pvm-interpreter/args-decoder/args-decoding-results.ts
  • packages/core/pvm-interpreter/args-decoder/decoders/extended-with-immediate-decoder.test.ts
  • packages/core/pvm-interpreter/args-decoder/decoders/extended-with-immediate-decoder.ts
  • packages/core/pvm-interpreter/args-decoder/decoders/immediate-decoder.test.ts
  • packages/core/pvm-interpreter/args-decoder/decoders/immediate-decoder.ts
  • packages/core/pvm-interpreter/basic-blocks/basic-blocks.test.ts
  • packages/core/pvm-interpreter/bin.ts
  • packages/core/pvm-interpreter/debugger-adapter.ts
  • packages/core/pvm-interpreter/gas.ts
  • packages/core/pvm-interpreter/interpreter.ts
  • packages/core/pvm-interpreter/memory/memory-builder.test.ts
  • packages/core/pvm-interpreter/memory/memory-builder.ts
  • packages/core/pvm-interpreter/memory/memory.test.ts
  • packages/core/pvm-interpreter/memory/memory.ts
  • packages/core/pvm-interpreter/memory/pages/readable-page.test.ts
  • packages/core/pvm-interpreter/memory/pages/readable-page.ts
  • packages/core/pvm-interpreter/memory/pages/writeable-page.test.ts
  • packages/core/pvm-interpreter/memory/pages/writeable-page.ts
  • packages/core/pvm-interpreter/ops-dispatchers/no-args-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/one-imm-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/one-offset-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/one-reg-one-ext-imm-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/one-reg-one-imm-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/one-reg-one-imm-one-offset-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/one-reg-two-imms-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/three-regs-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/two-imms-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/two-regs-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/two-regs-one-imm-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/two-regs-one-offset-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops-dispatchers/two-regs-two-imms-dispatcher.test.ts
  • packages/core/pvm-interpreter/ops/bit-ops.test.ts
  • packages/core/pvm-interpreter/ops/bit-ops.ts
  • packages/core/pvm-interpreter/ops/bit-rotation-ops.test.ts
  • packages/core/pvm-interpreter/ops/bit-rotation-ops.ts
  • packages/core/pvm-interpreter/ops/boolean-ops.test.ts
  • packages/core/pvm-interpreter/ops/boolean-ops.ts
  • packages/core/pvm-interpreter/ops/branch-ops.test.ts
  • packages/core/pvm-interpreter/ops/branch-ops.ts
  • packages/core/pvm-interpreter/ops/dynamic-jump-ops.test.ts
  • packages/core/pvm-interpreter/ops/dynamic-jump-ops.ts
  • packages/core/pvm-interpreter/ops/host-call-ops.test.ts
  • packages/core/pvm-interpreter/ops/host-call-ops.ts
  • packages/core/pvm-interpreter/ops/load-ops.test.ts
  • packages/core/pvm-interpreter/ops/load-ops.ts
  • packages/core/pvm-interpreter/ops/math-ops.test.ts
  • packages/core/pvm-interpreter/ops/math-ops.ts
  • packages/core/pvm-interpreter/ops/memory-ops.test.ts
  • packages/core/pvm-interpreter/ops/memory-ops.ts
  • packages/core/pvm-interpreter/ops/move-ops.test.ts
  • packages/core/pvm-interpreter/ops/move-ops.ts
  • packages/core/pvm-interpreter/ops/no-args-ops.test.ts
  • packages/core/pvm-interpreter/ops/no-args-ops.ts
  • packages/core/pvm-interpreter/ops/shift-ops.test.ts
  • packages/core/pvm-interpreter/ops/shift-ops.ts
  • packages/core/pvm-interpreter/ops/store-ops.test.ts
  • packages/core/pvm-interpreter/ops/store-ops.ts
  • packages/core/pvm-interpreter/program-decoder/jump-table.test.ts
  • packages/core/pvm-interpreter/program-decoder/jump-table.ts
  • packages/core/pvm-interpreter/program-decoder/mask.test.ts
  • packages/core/pvm-interpreter/program-decoder/mask.ts
  • packages/core/pvm-interpreter/program-decoder/program-decoder.test.ts
  • packages/core/pvm-interpreter/program-decoder/program-decoder.ts
  • packages/core/pvm-interpreter/program.ts
  • packages/core/pvm-interpreter/registers.test.ts
  • packages/core/pvm-interpreter/registers.ts
  • packages/core/pvm-interpreter/spi-decoder/decode-standard-program.ts
  • packages/core/trie/nodes.ts
  • packages/core/trie/nodesDb.ts
  • packages/core/trie/trie.ts
  • packages/extensions/ipc/index.ts
  • packages/extensions/ipc/jamnp/handler.ts
  • packages/extensions/ipc/jamnp/server.ts
  • packages/extensions/ipc/server.ts
  • packages/jam/block/header.ts
  • packages/jam/config-node/jip-chain-spec.ts
  • packages/jam/config/chain-spec.ts
  • packages/jam/config/network.ts
  • packages/jam/database-lmdb/blocks.ts
  • packages/jam/database-lmdb/root.ts
  • packages/jam/database-lmdb/states.test.ts
  • packages/jam/database-lmdb/states.ts
  • packages/jam/database/blocks.test.ts
  • packages/jam/database/states.test.ts
  • packages/jam/database/states.ts
  • packages/jam/executor/pvm-executor.ts
  • packages/jam/fuzz-proto/v1/handler.test.ts
  • packages/jam/fuzz-proto/v1/handler.ts
  • packages/jam/in-core/externalities/refine.test.ts
  • packages/jam/in-core/in-core.test.ts
  • packages/jam/in-core/in-core.ts
  • packages/jam/in-core/is-authorized.test.ts
  • packages/jam/in-core/refine.ts
  • packages/jam/jam-host-calls/accumulate/assign.test.ts
  • packages/jam/jam-host-calls/accumulate/assign.ts
  • packages/jam/jam-host-calls/accumulate/bless.test.ts
  • packages/jam/jam-host-calls/accumulate/bless.ts
  • packages/jam/jam-host-calls/accumulate/checkpoint.test.ts
  • packages/jam/jam-host-calls/accumulate/checkpoint.ts
  • packages/jam/jam-host-calls/accumulate/designate.test.ts
  • packages/jam/jam-host-calls/accumulate/designate.ts
  • packages/jam/jam-host-calls/accumulate/eject.test.ts
  • packages/jam/jam-host-calls/accumulate/eject.ts
  • packages/jam/jam-host-calls/accumulate/forget.test.ts
  • packages/jam/jam-host-calls/accumulate/forget.ts
  • packages/jam/jam-host-calls/accumulate/new.test.ts
  • packages/jam/jam-host-calls/accumulate/new.ts
  • packages/jam/jam-host-calls/accumulate/provide.test.ts
  • packages/jam/jam-host-calls/accumulate/provide.ts
  • packages/jam/jam-host-calls/accumulate/query.test.ts
  • packages/jam/jam-host-calls/accumulate/query.ts
  • packages/jam/jam-host-calls/accumulate/solicit.test.ts
  • packages/jam/jam-host-calls/accumulate/solicit.ts
  • packages/jam/jam-host-calls/accumulate/transfer.test.ts
  • packages/jam/jam-host-calls/accumulate/transfer.ts
  • packages/jam/jam-host-calls/accumulate/upgrade.test.ts
  • packages/jam/jam-host-calls/accumulate/upgrade.ts
  • packages/jam/jam-host-calls/accumulate/yield.test.ts
  • packages/jam/jam-host-calls/accumulate/yield.ts
  • packages/jam/jam-host-calls/externalities/refine-externalities.test.ts
  • packages/jam/jam-host-calls/externalities/state-update.ts
  • packages/jam/jam-host-calls/externalities/test-accounts.ts
  • packages/jam/jam-host-calls/general/fetch.test.ts
  • packages/jam/jam-host-calls/general/fetch.ts
  • packages/jam/jam-host-calls/general/gas.test.ts
  • packages/jam/jam-host-calls/general/gas.ts
  • packages/jam/jam-host-calls/general/info.test.ts
  • packages/jam/jam-host-calls/general/info.ts
  • packages/jam/jam-host-calls/general/log.ts
  • packages/jam/jam-host-calls/general/lookup.test.ts
  • packages/jam/jam-host-calls/general/lookup.ts
  • packages/jam/jam-host-calls/general/read.test.ts
  • packages/jam/jam-host-calls/general/read.ts
  • packages/jam/jam-host-calls/general/write.test.ts
  • packages/jam/jam-host-calls/general/write.ts
  • packages/jam/jam-host-calls/refine/export.test.ts
  • packages/jam/jam-host-calls/refine/export.ts
  • packages/jam/jam-host-calls/refine/expunge.test.ts
  • packages/jam/jam-host-calls/refine/expunge.ts
  • packages/jam/jam-host-calls/refine/historical-lookup.test.ts
  • packages/jam/jam-host-calls/refine/historical-lookup.ts
  • packages/jam/jam-host-calls/refine/invoke.test.ts
  • packages/jam/jam-host-calls/refine/invoke.ts
  • packages/jam/jam-host-calls/refine/machine.test.ts
  • packages/jam/jam-host-calls/refine/machine.ts
  • packages/jam/jam-host-calls/refine/pages.test.ts
  • packages/jam/jam-host-calls/refine/pages.ts
  • packages/jam/jam-host-calls/refine/peek.test.ts
  • packages/jam/jam-host-calls/refine/peek.ts
  • packages/jam/jam-host-calls/refine/poke.test.ts
  • packages/jam/jam-host-calls/refine/poke.ts
  • packages/jam/jamnp-s/network.ts
  • packages/jam/jamnp-s/peers.ts
  • packages/jam/jamnp-s/protocol/ce-128-block-request.test.ts
  • packages/jam/jamnp-s/protocol/ce-128-block-request.ts
  • packages/jam/jamnp-s/protocol/ce-129-state-request.test.ts
  • packages/jam/jamnp-s/protocol/ce-129-state-request.ts
  • packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.test.ts
  • packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.ts
  • packages/jam/jamnp-s/protocol/ce-133-work-package-submission.test.ts
  • packages/jam/jamnp-s/protocol/ce-133-work-package-submission.ts
  • packages/jam/jamnp-s/protocol/ce-134-work-package-sharing.test.ts
  • packages/jam/jamnp-s/protocol/ce-134-work-package-sharing.ts
  • packages/jam/jamnp-s/protocol/ce-135-work-report-distribution.test.ts
  • packages/jam/jamnp-s/protocol/ce-135-work-report-distribution.ts
  • packages/jam/jamnp-s/protocol/up-0-block-announcement.ts
  • packages/jam/jamnp-s/stream-manager.ts
  • packages/jam/jamnp-s/tasks/sync.test.ts
  • packages/jam/jamnp-s/tasks/sync.ts
  • packages/jam/jamnp-s/tasks/ticket-distribution.test.ts
  • packages/jam/jamnp-s/tasks/ticket-distribution.ts
  • packages/jam/node/common.ts
  • packages/jam/rpc-client/index.ts
  • packages/jam/state-json/accounts.ts
  • packages/jam/state-merkleization/in-memory-state-codec.ts
  • packages/jam/state-merkleization/serialized-state-view.ts
  • packages/jam/state-merkleization/serialized-state.test.ts
  • packages/jam/state-merkleization/serialized-state.ts
  • packages/jam/state/in-memory-state-view.ts
  • packages/jam/state/in-memory-state.test.ts
  • packages/jam/state/in-memory-state.ts
  • packages/jam/state/service.ts
  • packages/jam/state/test.utils.ts
  • packages/jam/transition/accumulate/accumulate.test.ts
  • packages/jam/transition/accumulate/accumulate.ts
  • packages/jam/transition/block-verifier.test.ts
  • packages/jam/transition/block-verifier.ts
  • packages/jam/transition/chain-stf.ts
  • packages/jam/transition/externalities/accumulate-externalities.test.ts
  • packages/jam/transition/externalities/accumulate-externalities.ts
  • packages/jam/transition/externalities/refine-fetch-externalities.test.ts
  • packages/jam/transition/externalities/refine-fetch-externalities.ts
  • packages/jam/transition/hasher.test.ts
  • packages/jam/transition/hasher.ts
  • packages/jam/transition/preimages.test.ts
  • packages/jam/transition/reports/test.utils.ts
  • packages/workers/api-node/config.ts
  • packages/workers/api-node/port.test.ts
  • packages/workers/api-node/port.ts
  • packages/workers/api-node/protocol.ts
  • packages/workers/block-authorship/generator.test.ts
  • packages/workers/block-authorship/generator.ts
  • packages/workers/block-authorship/main.ts
  • packages/workers/importer/finality.test.ts
  • packages/workers/importer/importer.ts
  • packages/workers/importer/main.ts

Comment thread packages/core/collections/multi-map.ts
Comment thread packages/core/pvm-interpreter/program-decoder/jump-table.ts
Comment thread packages/core/pvm-interpreter/program-decoder/jump-table.ts
Comment thread packages/core/pvm-interpreter/registers.ts
Comment thread packages/core/trie/nodesDb.ts
Comment thread packages/jam/jamnp-s/protocol/ce-133-work-package-submission.ts
Comment thread packages/jam/jamnp-s/protocol/ce-134-work-package-sharing.ts
Comment thread packages/jam/state/in-memory-state.ts
tomusdrw and others added 4 commits April 19, 2026 22:16
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bin/lib/README.md (1)

295-297: ⚠️ Potential issue | 🟠 Major

Update remaining PVM example to static builder for consistency.

Line 296 still uses new Interpreter() while nearby examples use Interpreter.new(). This leaves the docs inconsistent and may break if constructor access is restricted.

Suggested README fix
 const initialGas = tryAsGas(1000);
-const pvm = new Interpreter();
+const pvm = Interpreter.new();
 pvm.resetGeneric(program.raw, 0, initialGas);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/README.md` around lines 295 - 297, The README example uses the
constructor directly (new Interpreter()) which is inconsistent with other
examples and may fail if the constructor is restricted; update the snippet to
use the static builder Interpreter.new() instead, i.e., create the PVM via
Interpreter.new(...) and then call resetGeneric(program.raw, 0, initialGas)
(keeping tryAsGas(1000) and resetGeneric usage intact) so the example matches
other docs and uses the static factory method consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@bin/lib/README.md`:
- Around line 295-297: The README example uses the constructor directly (new
Interpreter()) which is inconsistent with other examples and may fail if the
constructor is restricted; update the snippet to use the static builder
Interpreter.new() instead, i.e., create the PVM via Interpreter.new(...) and
then call resetGeneric(program.raw, 0, initialGas) (keeping tryAsGas(1000) and
resetGeneric usage intact) so the example matches other docs and uses the static
factory method consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b6d98533-a7d7-4773-8cda-77ea476bdd47

📥 Commits

Reviewing files that changed from the base of the PR and between e5d3acb and 25b6e15.

📒 Files selected for processing (3)
  • bin/lib/README.md
  • packages/jam/in-core/externalities/refine.test.ts
  • packages/jam/in-core/externalities/refine.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/jam/in-core/externalities/refine.test.ts

@github-actions
Copy link
Copy Markdown

View all
File Benchmark Ops
bytes/hex-from.ts[0] parse hex using Number with NaN checking 69293.33 ±0.81% 85.25% slower
bytes/hex-from.ts[1] parse hex from char codes 469712.81 ±0.24% fastest ✅
bytes/hex-from.ts[2] parse hex from string nibbles 267609.81 ±0.36% 43.03% slower
bytes/hex-to.ts[0] number toString + padding 89383.07 ±1.36% fastest ✅
bytes/hex-to.ts[1] manual 7385.47 ±1.28% 91.74% slower
codec/bigint.compare.ts[0] compare custom 92034542.71 ±5.44% 4.88% slower
codec/bigint.compare.ts[1] compare bigint 96759013.76 ±4.98% fastest ✅
codec/bigint.decode.ts[0] decode custom 71270840.49 ±3.57% 23.62% slower
codec/bigint.decode.ts[1] decode bigint 93316802.15 ±4.83% fastest ✅
codec/decoding.ts[0] manual decode 9761949.54 ±1.51% 85.8% slower
codec/decoding.ts[1] int32array decode 66008700.1 ±3.38% 3.96% slower
codec/decoding.ts[2] dataview decode 68730055.39 ±3.55% fastest ✅
codec/encoding.ts[0] manual encode 1098158.36 ±0.38% 13.21% slower
codec/encoding.ts[1] int32array encode 1265335.26 ±0.28% fastest ✅
codec/encoding.ts[2] dataview encode 1211077.15 ±0.89% 4.29% slower
collections/map-set.ts[0] 2 gets + conditional set 71771.28 ±0.19% fastest ✅
collections/map-set.ts[1] 1 get 1 set 47538.72 ±0.33% 33.76% slower
logger/index.ts[0] console.log with string concat 4956895.75 ±42.01% fastest ✅
logger/index.ts[1] console.log with args 1287279.44 ±54.57% 74.03% slower
math/add_one_overflow.ts[0] add and take modulus 97886143.88 ±4.7% 4.19% slower
math/add_one_overflow.ts[1] condition before calculation 102161632.61 ±3.63% fastest ✅
math/count-bits-u32.ts[0] standard method 45305996.1 ±2.14% 50.29% slower
math/count-bits-u32.ts[1] magic 91132543.78 ±3.84% fastest ✅
math/count-bits-u64.ts[0] standard method 5693014.83 ±0.44% 78.93% slower
math/count-bits-u64.ts[1] magic 27019598.9 ±1.58% fastest ✅
math/mul_overflow.ts[0] multiply and bring back to u32 90139089.24 ±6.95% 8.35% slower
math/mul_overflow.ts[1] multiply and take modulus 98355503.49 ±5.54% fastest ✅
math/switch.ts[0] switch 97914143.05 ±4.79% fastest ✅
math/switch.ts[1] if 94707354.36 ±5.98% 3.28% slower
hash/index.ts[0] hash with numeric representation 68.51 ±0.08% 30.18% slower
hash/index.ts[1] hash with string representation 42.95 ±0.82% 56.23% slower
hash/index.ts[2] hash with symbol representation 67.17 ±0.2% 31.54% slower
hash/index.ts[3] hash with uint8 representation 76.38 ±0.14% 22.16% slower
hash/index.ts[4] hash with packed representation 98.12 ±0.65% fastest ✅
hash/index.ts[5] hash with bigint representation 73.66 ±0.12% 24.93% slower
hash/index.ts[6] hash with uint32 representation 94.31 ±0.09% 3.88% slower
bytes/bytes-to-number.ts[0] Conversion with bitops 3207.07 ±5.13% fastest ✅
bytes/bytes-to-number.ts[1] Conversion without bitops 2567.93 ±2.79% 19.93% slower
bytes/compare.ts[0] Comparing Uint32 bytes 11932.41 ±0.26% fastest ✅
bytes/compare.ts[1] Comparing raw bytes 11768.34 ±0.08% 1.37% slower
codec/view_vs_collection.ts[0] Get first element from Decoded 14541.09 ±0.55% 52.16% slower
codec/view_vs_collection.ts[1] Get first element from View 30394.79 ±2.69% fastest ✅
codec/view_vs_collection.ts[2] Get 50th element from Decoded 14622.06 ±0.71% 51.89% slower
codec/view_vs_collection.ts[3] Get 50th element from View 17293.34 ±0.37% 43.1% slower
codec/view_vs_collection.ts[4] Get last element from Decoded 14830.55 ±0.13% 51.21% slower
codec/view_vs_collection.ts[5] Get last element from View 12096.99 ±0.52% 60.2% slower
codec/view_vs_object.ts[0] Get the first field from Decoded 200710.64 ±0.62% 1.1% slower
codec/view_vs_object.ts[1] Get the first field from View 51341 ±0.34% 74.7% slower
codec/view_vs_object.ts[2] Get the first field as view from View 50127.09 ±0.36% 75.3% slower
codec/view_vs_object.ts[3] Get two fields from Decoded 102874.79 ±94.81% 49.31% slower
codec/view_vs_object.ts[4] Get two fields from View 39622.17 ±0.58% 80.48% slower
codec/view_vs_object.ts[5] Get two fields from materialized from View 78310.26 ±0.33% 61.41% slower
codec/view_vs_object.ts[6] Get two fields as views from View 37750.62 ±2.27% 81.4% slower
codec/view_vs_object.ts[7] Get only third field from Decoded 202950.1 ±0.52% fastest ✅
codec/view_vs_object.ts[8] Get only third field from View 48857.04 ±0.52% 75.93% slower
codec/view_vs_object.ts[9] Get only third field as view from View 49306.54 ±0.29% 75.71% slower
collections/map_vs_sorted.ts[0] Map 123075.12 ±0.1% fastest ✅
collections/map_vs_sorted.ts[1] Map-array 45122.11 ±0.41% 63.34% slower
collections/map_vs_sorted.ts[2] Array 54782.33 ±0.56% 55.49% slower
collections/map_vs_sorted.ts[3] SortedArray 83633.83 ±0.32% 32.05% slower
collections/hash-dict-vs-blob-dict_delete.ts[0] StringHashDictionary 2381.8 ±0.3% 0.35% slower
collections/hash-dict-vs-blob-dict_delete.ts[1] BlobDictionary(1) 2329.8 ±1.91% 2.52% slower
collections/hash-dict-vs-blob-dict_delete.ts[2] BlobDictionary(2) 2390.07 ±0.33% fastest ✅
collections/hash-dict-vs-blob-dict_delete.ts[3] BlobDictionary(3) 2375.31 ±0.41% 0.62% slower
collections/hash-dict-vs-blob-dict_delete.ts[4] BlobDictionary(4) 2375.7 ±0.76% 0.6% slower
collections/hash-dict-vs-blob-dict_delete.ts[5] BlobDictionary(5) 2388.21 ±0.28% 0.08% slower
collections/hash-dict-vs-blob-dict_get.ts[0] StringHashDictionary 2979.72 ±1.42% 0.83% slower
collections/hash-dict-vs-blob-dict_get.ts[1] BlobDictionary(1) 2926.72 ±1.25% 2.59% slower
collections/hash-dict-vs-blob-dict_get.ts[2] BlobDictionary(2) 2981.76 ±0.49% 0.76% slower
collections/hash-dict-vs-blob-dict_get.ts[3] BlobDictionary(3) 3004.69 ±0.32% fastest ✅
collections/hash-dict-vs-blob-dict_get.ts[4] BlobDictionary(4) 2976.61 ±0.45% 0.93% slower
collections/hash-dict-vs-blob-dict_get.ts[5] BlobDictionary(5) 2993.69 ±0.38% 0.37% slower
collections/hash-dict-vs-blob-dict_set.ts[0] StringHashDictionary 2036.01 ±1.83% 10.41% slower
collections/hash-dict-vs-blob-dict_set.ts[1] BlobDictionary(1) 2272.51 ±0.39% fastest ✅
collections/hash-dict-vs-blob-dict_set.ts[2] BlobDictionary(2) 2246.39 ±0.63% 1.15% slower
collections/hash-dict-vs-blob-dict_set.ts[3] BlobDictionary(3) 2256.95 ±0.39% 0.68% slower
collections/hash-dict-vs-blob-dict_set.ts[4] BlobDictionary(4) 1494.42 ±60.29% 34.24% slower
collections/hash-dict-vs-blob-dict_set.ts[5] BlobDictionary(5) 2240.89 ±0.42% 1.39% slower
hash/blake2b.ts[0] our hasher 1.07 ±1.69% fastest ✅
hash/blake2b.ts[1] blake2b js 0.03 ±0.45% 97.2% slower
crypto/ed25519.ts[0] native crypto 5.741 ±1.05% fastest ✅
crypto/ed25519.ts[1] wasm lib 2.282 ±0.24% 60.25% slower
crypto/ed25519.ts[2] wasm lib batch 2.276 ±0.24% 60.36% slower

Benchmarks summary: 83/83 OK ✅

@tomusdrw tomusdrw enabled auto-merge April 20, 2026 21:35
@tomusdrw tomusdrw disabled auto-merge April 20, 2026 21:36
@tomusdrw tomusdrw merged commit 9ffd7ac into main Apr 20, 2026
14 checks passed
@tomusdrw tomusdrw deleted the td-host-call-regs branch April 20, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant