Skip to content

chore: export encoding functions#142

Merged
MicBun merged 1 commit intomainfrom
exportEncoding
Oct 21, 2025
Merged

chore: export encoding functions#142
MicBun merged 1 commit intomainfrom
exportEncoding

Conversation

@MicBun
Copy link
Member

@MicBun MicBun commented Oct 21, 2025

resolves: https://github.com/trufnetwork/truf-network/issues/1274

Summary by CodeRabbit

  • New Features
    • Exposed new public API utilities for encoding operations: EncodedValue type, formatEncodedValue, and encodeEncodedValue functions for developers to handle encoded value formatting and encoding.

@MicBun MicBun self-assigned this Oct 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

Walkthrough

Three internal encoding-related items are exposed to the public API: type EncodedValue and utility functions encodeEncodedValue and formatEncodedValue. The utility functions receive expanded implementations with complete encoding workflows including version, data type, length, and per-element encoding logic.

Changes

Cohort / File(s) Summary
Public API Exposure
src/index.ts
Imports and re-exports EncodedValue type and encodeEncodedValue, formatEncodedValue utilities from internal modules to extend public API surface
Encoding Utilities
src/utils/kwilEncoding.ts, src/utils/parameterEncoding.ts
Converts internal functions to exported public functions with JSDoc documentation; updates encodeEncodedValue with full encoding flow and formatEncodedValue to use EncodedValue[] arrays and encodeValue() instead of bytesToBase64()

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The changes span three files with consistent patterns (API exposure and function exporting), but the encoding logic updates in kwilEncoding.ts and parameterEncoding.ts require careful review to verify the correctness of the expanded encoding workflows and data type conversions.

Poem

🐰 Hop, skip, and encode with flair,
New public paths laid bare,
Type and function, now exposed,
Encoding logic fully composed,
The API grows, spring is in the air!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "chore: export encoding functions" accurately describes the primary change across the three modified files. The PR exports two encoding functions—formatEncodedValue and encodeEncodedValue—making them part of the public API in src/index.ts, while also updating their implementations in their respective utility files. The title is concise, clear, and specific enough that a teammate reviewing the git history would immediately understand the main objective without requiring additional context.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch exportEncoding

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@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: 0

Caution

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

⚠️ Outside diff range comments (3)
src/utils/parameterEncoding.ts (2)

168-179: Bug: switch fallthrough sets non-null objects to NULL

In resolveValueType, falling through from case 'object' to case 'undefined' marks any non-Uint8Array, non-null object as NULL. That silently mis-types inputs (e.g., Date, custom objects) and bypasses the error path.

Apply this guard and prevent fallthrough:

   switch (typeof value) {
@@
-    case 'object':
-      if (value instanceof Uint8Array) {
-        varType = VarType.BYTEA;
-        break;
-      }
-      if (value === null) {
-        varType = VarType.NULL;
-        break;
-      }
-    case 'undefined':
+    case 'object':
+      if (value instanceof Uint8Array) {
+        varType = VarType.BYTEA;
+        break;
+      }
+      if (value === null) {
+        varType = VarType.NULL;
+        break;
+      }
+      throw new Error(
+        `Unsupported object type: ${Object.prototype.toString.call(value)}. If using a uuid, blob, or uint256, convert to a string or Uint8Array.`
+      );
+    case 'undefined':
       varType = VarType.NULL;
       break;

92-104: Cannot infer type from empty arrays—throw error for ambiguous empty array parameters

Empty arrays passed to formatDataType without an override are mis-typed as VarType.NULL instead of their intended element type, breaking API calls expecting e.g. INT8[] with zero elements.

Root cause: When an empty array [] is processed, resolveValueType(value[0]) receives undefined at line 144, which triggers the case 'undefined': handler at line 162 and defaults to VarType.NULL.

Fix required: Add a guard in formatDataType after the override check to fail fast:

 function formatDataType(val: ValueType | ValueType[], o?: DataInfo): {
   type: DataInfo;
   data: ValueType;
 } {
   // handle override case
   if (o) {
     return {
       type: o,
       data: val,
     };
   }
+  // Prevent ambiguous typing for empty arrays without an override
+  if (Array.isArray(val) && val.length === 0) {
+    throw new Error(
+      'Cannot infer element type from an empty array. Provide a DataInfo override with the desired VarType.'
+    );
+  }

Also add a test case covering empty arrays with and without overrides to prevent regression.

src/utils/kwilEncoding.ts (1)

121-137: Guard optional parameters in encodeRawStatement

statement.parameters is used in a for..of without a null/undefined guard. This will throw if the field is absent.

-  let encodedParameters: Uint8Array;
-  encodedParameters = numberToUint16LittleEndian(
-    statement.parameters ? statement.parameters.length : 0
-  );
-  // then, for each parameter..
-  for (const param of statement.parameters) {
+  const params = statement.parameters ?? [];
+  let encodedParameters: Uint8Array = numberToUint16LittleEndian(params.length);
+  // then, for each parameter..
+  for (const param of params) {
🧹 Nitpick comments (3)
src/utils/parameterEncoding.ts (1)

115-126: Numeric metadata derivation is fragile for e-notation

analyzeNumber uses Number.toString(); large/small magnitudes may render in scientific notation, skewing precision/scale. It also counts leading zeros toward “precision.”

Consider a safer approach (no e-notation), e.g., normalize via toLocaleString with numberingSystem 'latn' and then strip separators, or use a decimal library to compute digits and scale precisely.

src/utils/kwilEncoding.ts (2)

185-187: Typo

“Concact” → “Concat”.


189-203: Endian inconsistencies are intentional — add explicit note

encodeDataType uses big-endian for version and lengths while other areas use little-endian. You added a brief note; consider linking to the kwil-db struct definition or adding a reference comment for future maintainers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 941ae0c and 7234553.

📒 Files selected for processing (3)
  • src/index.ts (3 hunks)
  • src/utils/kwilEncoding.ts (1 hunks)
  • src/utils/parameterEncoding.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/index.ts (3)
src/core/payload.ts (1)
  • EncodedValue (34-37)
src/utils/parameterEncoding.ts (1)
  • formatEncodedValue (62-81)
src/utils/kwilEncoding.ts (1)
  • encodeEncodedValue (164-187)
src/utils/kwilEncoding.ts (2)
src/index.ts (2)
  • encodeEncodedValue (116-116)
  • EncodedValue (71-71)
src/core/payload.ts (1)
  • EncodedValue (34-37)
src/utils/parameterEncoding.ts (4)
src/index.ts (3)
  • formatEncodedValue (110-110)
  • ValueType (70-70)
  • EncodedValue (71-71)
src/utils/types.ts (1)
  • ValueType (66-74)
src/core/database.ts (1)
  • DataInfo (32-36)
src/core/payload.ts (1)
  • EncodedValue (34-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (5)
src/utils/parameterEncoding.ts (2)

54-62: Good call exposing formatEncodedValue

Public export + JSDoc make the encoding path usable externally. No functional concerns here.


62-80: Minor: consistent override usage

In formatEncodedValue (array branch), you pass o?.name to encodeValue for each element, which is correct. For non-array, you pass base.data with o?.name — also fine. Add a quick unit test to cover both override and inference paths, including UUID, BYTEA, NUMERIC with scale, and NULL.

src/utils/kwilEncoding.ts (2)

175-183: Spec mismatch: data length field width (comment says uint32, code uses uint16)

encodeEncodedValue builds the data array with numberToUint16LittleEndian(ev.data.length), but the comment says “prepend 4 bytes (uint32)”. Clarify and align with kwil-db’s MarshalBinary spec to avoid interop breaks.

Two options:

  • If spec is uint16 (count of elements), fix the comment.
  • If spec is uint32, change the code:
-  const dataLength = numberToUint16LittleEndian(ev.data.length);
+  const dataLength = numberToUint32BigEndian(ev.data.length);
   let encodedData = concatBytes(dataLength);

205-246: encodeValue: behavior surfaces look good

Covers override, UUID, null, BYTEA, decimal-as-string, and scalars. Recommend a few tests for edge cases: -0, large integers, 1e21, 1e-7, empty Uint8Array, and override with NULL when v is non-null (should still encode null per current logic).

src/index.ts (1)

42-45: Public API surface looks consistent

Re-exporting Types.EncodedValue and Utils.{formatEncodedValue, encodeEncodedValue} aligns with internal implementations.

Please update CHANGELOG and public docs with:

  • New exports in Utils.
  • Guidance on empty-array typing (require DataInfo override).
  • Example showing formatEncodedValue + encodeEncodedValue usage.

Also applies to: 106-117, 71-71

@holdex
Copy link

holdex bot commented Oct 21, 2025

Time Submission Status

Member Status Time Action Last Update
MicBun ✅ Submitted 6h Update time Oct 21, 2025, 1:55 PM
@outerlook ❌ Missing - ⚠️ Submit time -

@MicBun MicBun merged commit 0659b0b into main Oct 21, 2025
3 of 4 checks passed
@MicBun MicBun deleted the exportEncoding branch October 21, 2025 14:00
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.

2 participants