Skip to content

Static class refactor#140

Merged
Ryang-21 merged 22 commits into
masterfrom
static-class-refactor
Jun 1, 2026
Merged

Static class refactor#140
Ryang-21 merged 22 commits into
masterfrom
static-class-refactor

Conversation

@Ryang-21

@Ryang-21 Ryang-21 commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR rewrites js-xdr around explicit TypeScript schema builders instead of the old runtime xdr.config(...) registry. The new model keeps XDR wire encoding compatible while replacing generated classes/accessors with typed plain JavaScript values.

Rationale

The old API built schemas dynamically through xdr.config(...), name lookups, typedefs, and generated classes. That made schemas harder to type, harder to tree-shake, and harder to reason about because value shapes were created at runtime.

The new API makes schemas explicit values composed from TypeScript builders. This gives callers typed encode/decode surfaces, removes the runtime registry, makes recursive references explicit with lazy, and aligns decoded values with plain JavaScript data instead of generated accessor classes.

Architecture Shift

v4 Runtime Model

flowchart TD
  A[User schema code] --> B["xdr.config(callback)"]
  B --> C[Runtime type registry]
  C --> D["xdr.lookup(name)"]
  C --> E["xdr.typedef(name, type)"]
  C --> F[Reference resolution]
  F --> G[Generated classes]
  G --> H[Constructors]
  G --> I[Getter/setter methods]
  G --> J[Union helper constructors]
  H --> K["toXDR / fromXDR"]
  I --> K
  J --> K
  K --> L["Buffer / hex / base64"]
Loading

v5 Static Schema Model

flowchart TD
  A[User schema code] --> B[Explicit schema values]
  B --> C["struct(...)"]
  B --> D["union(...)"]
  B --> E["enumType(...)"]
  B --> F["lazy(() => schema)"]
  C --> G[Plain JavaScript values]
  D --> G
  E --> G
  F --> G
  G --> H["encode / decode"]
  H --> I[Uint8Array]
  I --> J["Boundary conversion by caller"]
  J --> K["Buffer / hex / base64"]
Loading

API Changes

XDR concept v4 API v4 value shape v5 API v5 value shape Notes
signed int xdr.int() / XDR.Int number int32() number Range checked on encode.
unsigned int xdr.uint() / XDR.UnsignedInt number uint32() number Range checked on encode.
hyper XDR.Hyper Hyper wrapper int64() bigint No .toBigInt(), .toString(), Hyper.fromString().
unsigned hyper XDR.UnsignedHyper UnsignedHyper wrapper uint64() bigint No wrapper class.
float XDR.Float number float() number Finite numbers only on encode.
double XDR.Double number double() number Finite numbers only on encode.
quadruple XDR.Quadruple unsupported removed removed v4 already threw on use.
bool XDR.Bool boolean bool() boolean Wire values remain 0/1.
string new XDR.String(n) string or bytes string(maxLength) Uint8Array Text encoding moves to caller.
opaque xdr.opaque(n) Buffer/bytes opaque(length) Uint8Array Exact length required.
var opaque xdr.varOpaque(n) Buffer/bytes varOpaque(maxLength) Uint8Array Max length enforced.
fixed array xdr.array(child, n) array fixedArray(element, length) array No length prefix.
variable array xdr.varArray(child, max) array array(element, maxLength) array Has uint32 length prefix.
option xdr.option(child) optional wrapper behavior option(element) T | null null means absent.
void XDR.Void / xdr.void() undefined void() undefined Zero bytes on wire.
enum xdr.enum(...) enum member object enumType(...) member number Member names exposed as numeric constants.
struct xdr.struct(...) generated class instance struct(...) plain object No constructor/getter/setter methods.
union xdr.union(...) generated union instance union(...) tagged object Default discriminator key is type.
forward reference xdr.lookup(name) registry reference lazy(() => schema) inferred Explicit closure instead of registry lookup.
typedef xdr.typedef(name, type) registry alias normal variable alias same schema const Signature = opaque(32).

Value Model Examples

  const Color = struct('Color', {
    red: uint32(),
    green: uint32(),
    blue: uint32(),
  });

  Color.encode({ red: 1, green: 2, blue: 3 });

  const Result = union('Result', {
    switchOn: ResultType,
    cases: [
      xdrCase('ok', ResultType.ok, xdrVoid()),
      xdrCase('error', ResultType.error, field('code', int32())),
    ],
  });

  Result.encode({ type: ResultType.error, code: 7 });

Wire Compatibility Proof

This PR includes reproducible v4 compatibility fixtures:

  • test/fixtures/generate-v4-compat.cjs generates fixture bytes using the published v4 package alias:
    js-xdr-v4: npm:@stellar/js-xdr@4.0.0
  • test/fixtures/v4-compat.json commits those bytes and records provenance metadata.
  • test/unit/v4-compat.test.ts decodes the v4 bytes with v5 schemas, asserts the new plain value shape, then re-encodes and compares bytes exactly.

Covered fixture cases:

  • primitive/container struct fixture
  • union void arm
  • union payload arm
  • recursive linked list via lazy

Tooling Changes

  • Migrated source from JavaScript to TypeScript.
  • Replaced Webpack/Babel with Rollup + esbuild + declaration bundling.
  • Replaced Mocha/Karma/Sinon/Chai with Vitest.
  • Migrated ESLint to flat config with typescript-eslint.
  • Updated Husky to v9 and modernized the pre-commit hook.
  • Removed stale assumptions from examples and docs.

Copilot AI review requested due to automatic review settings May 28, 2026 16:19
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@socket-security

socket-security Bot commented May 28, 2026

Copy link
Copy Markdown

@socket-security

socket-security Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
License policy violation: npm rollup-plugin-dts under GPL-3.0

License: GPL-3.0 - The applicable license policy does not permit this license (5) (package/COPYING)

From: package.jsonnpm/rollup-plugin-dts@6.4.1

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/rollup-plugin-dts@6.4.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: npm typescript under MIT-Khronos-old

License: MIT-Khronos-old - The applicable license policy does not permit this license (5) (package/ThirdPartyNoticeText.txt)

License: LicenseRef-W3C-Community-Final-Specification-Agreement - The applicable license policy does not permit this license (5) (package/ThirdPartyNoticeText.txt)

From: package.jsonnpm/typescript@5.9.3

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/typescript@5.9.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@Ryang-21 Ryang-21 requested review from Shaptic and quietbits May 28, 2026 16:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR rewrites js-xdr from the v4 runtime registry (xdr.config(...)) + generated classes into a v5-style, statically composed set of TypeScript schema builders that encode/decode plain JavaScript values while keeping XDR wire compatibility.

Changes:

  • Replaced the dynamic schema DSL and class-based runtime types with explicit TS builders (struct, union, enumType, lazy, etc.) backed by new Reader/Writer streaming primitives.
  • Migrated tooling from Webpack/Karma/Mocha to Rollup + esbuild and Vitest, and rewrote the unit suite in TypeScript.
  • Added reproducible v4 compatibility fixtures and tests that decode+re-encode v4 bytes to prove wire compatibility.

Reviewed changes

Copilot reviewed 128 out of 131 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
webpack.config.js Removed legacy Webpack build configuration.
vitest.config.ts Added Vitest configuration for unit tests.
tsconfig.json Added TypeScript compiler configuration for the new TS codebase.
test/unit/writer.test.ts New Vitest coverage for low-level Writer behavior.
test/unit/void.test.ts New Vitest coverage for void schema behavior.
test/unit/void_test.js Removed legacy Mocha/Chai void tests.
test/unit/var-opaque.test.ts New Vitest coverage for varOpaque encoding/decoding.
test/unit/var-opaque_test.js Removed legacy Mocha/Chai var-opaque tests.
test/unit/v4-compat.test.ts Added v4 wire-compat decode/re-encode fixture tests.
test/unit/unsigned-int_test.js Removed legacy Mocha/Chai unsigned-int tests.
test/unit/unsigned-hyper_test.js Removed legacy Mocha/Chai unsigned-hyper tests.
test/unit/union.test.ts New Vitest coverage for union encoding/decoding behavior.
test/unit/uint64.test.ts New Vitest coverage for uint64 schema behavior.
test/unit/uint32.test.ts New Vitest coverage for uint32 schema behavior.
test/unit/struct.test.ts New Vitest coverage for struct schema behavior.
test/unit/struct_union_test.js Removed legacy Mocha/Chai struct+union integration test.
test/unit/string.test.ts New Vitest coverage for string-as-bytes schema behavior.
test/unit/string_test.js Removed legacy Mocha/Chai string tests.
test/unit/reader.test.ts New Vitest coverage for low-level Reader behavior and maxDepth.
test/unit/quadruple_test.js Removed legacy Mocha/Chai quadruple tests (unsupported type removed).
test/unit/option.test.ts New Vitest coverage for option schema behavior.
test/unit/option_test.js Removed legacy Mocha/Chai option tests.
test/unit/opaque.test.ts New Vitest coverage for opaque schema behavior.
test/unit/opaque_test.js Removed legacy Mocha/Chai opaque tests.
test/unit/lazy.test.ts New Vitest coverage for lazy schema behavior and recursion.
test/unit/large-int-128_test.js Removed legacy LargeInt (>64-bit) tests (LargeInt API removed).
test/unit/int64.test.ts New Vitest coverage for int64 schema behavior.
test/unit/int32.test.ts New Vitest coverage for int32 schema behavior.
test/unit/int_test.js Removed legacy Mocha/Chai int tests.
test/unit/hyper_test.js Removed legacy Mocha/Chai hyper tests.
test/unit/float.test.ts New Vitest coverage for float schema behavior.
test/unit/float_test.js Removed legacy Mocha/Chai float tests.
test/unit/fixed-array.test.ts New Vitest coverage for fixedArray schema behavior.
test/unit/enum.test.ts New Vitest coverage for enumType schema behavior.
test/unit/enum_test.js Removed legacy Mocha/Chai enum tests.
test/unit/dynamic-buffer-resize_test.js Removed legacy writer-resize test (new Writer implementation + tests added).
test/unit/double.test.ts New Vitest coverage for double schema behavior.
test/unit/double_test.js Removed legacy Mocha/Chai double tests.
test/unit/define_test.js Removed legacy xdr.config DSL tests (DSL removed).
test/unit/bool.test.ts New Vitest coverage for bool schema behavior.
test/unit/bool_test.js Removed legacy Mocha/Chai bool tests.
test/unit/array.test.ts New Vitest coverage for variable-length array schema behavior.
test/unit/array_test.js Removed legacy Mocha/Chai array tests.
test/unit/_helpers.ts Added shared Vitest helper utilities for bytes/roundtrips/negative cases.
test/setup.js Removed Mocha/Karma test bootstrap.
test/fixtures/v4-compat.json Added committed v4-generated fixture bytes + metadata.
test/fixtures/generate-v4-compat.cjs Added script to generate v4 fixture bytes via npm alias.
test/.eslintrc.js Removed legacy ESLint config for Mocha tests.
src/xdr-type.js Removed legacy XdrType base + encoding format helpers.
src/void.js Removed legacy Void type implementation.
src/var-opaque.js Removed legacy VarOpaque implementation.
src/var-array.js Removed legacy VarArray implementation.
src/unsigned-int.js Removed legacy UnsignedInt implementation.
src/unsigned-hyper.js Removed legacy UnsignedHyper implementation.
src/union.js Removed legacy generated-class Union implementation.
src/types/void.ts Added new void schema builder/type.
src/types/var-opaque.ts Added new varOpaque schema builder/type.
src/types/uint64.ts Added new uint64 schema builder/type.
src/types/uint32.ts Added new uint32 schema builder/type.
src/types/struct.ts Added new struct schema builder/type.
src/types/string.ts Added new string schema builder/type (bytes-based).
src/types/option.ts Added new option schema builder/type (null-absent).
src/types/opaque.ts Added new opaque schema builder/type.
src/types/lazy.ts Added new lazy schema builder/type for recursion/forward refs.
src/types/int64.ts Added new int64 schema builder/type (bigint).
src/types/int32.ts Added new int32 schema builder/type.
src/types/float.ts Added new float schema builder/type.
src/types/fixed-array.ts Added new fixedArray schema builder/type.
src/types/enum.ts Added new enumType schema builder/type.
src/types/double.ts Added new double schema builder/type.
src/types/bool.ts Added new bool schema builder/type.
src/types/array.ts Added new array schema builder/type and array helpers.
src/types.js Removed legacy barrel export for v4 JS types.
src/struct.js Removed legacy generated-class Struct implementation.
src/string.js Removed legacy String type implementation.
src/serialization/xdr-writer.js Removed legacy Buffer-based XdrWriter.
src/serialization/xdr-reader.js Removed legacy Buffer-based XdrReader.
src/reference.js Removed legacy Reference type (registry-based).
src/quadruple.js Removed legacy Quadruple type (unsupported).
src/option.js Removed legacy Option implementation.
src/opaque.js Removed legacy Opaque implementation.
src/large-int.js Removed legacy LargeInt implementation (wrapper-based bigints).
src/int.js Removed legacy Int implementation.
src/index.ts Added new TS public entrypoint exporting builders + core primitives.
src/index.js Removed legacy JS entrypoint (v4 exports/config/reader/writer).
src/hyper.js Removed legacy Hyper implementation.
src/float.js Removed legacy Float implementation.
src/errors.js Removed legacy error classes (replaced by XdrError).
src/enum.js Removed legacy Enum implementation (member objects).
src/double.js Removed legacy Double implementation.
src/core/xdr-type.ts Added new BaseType/XdrType abstractions + encode/decode/validate APIs.
src/core/writer.ts Added new Uint8Array-based Writer implementation.
src/core/reader.ts Added new Uint8Array-based Reader with padding and maxDepth enforcement.
src/core/helpers.ts Added shared helpers/assertions used across schema implementations.
src/core/error.ts Added unified XdrError error type.
src/config.js Removed v4 runtime schema DSL / registry.
src/browser.js Removed legacy browser entry wrapper.
src/bool.js Removed legacy Bool implementation.
src/bigint-encoder.js Removed legacy bigint slicing/assembly utilities tied to LargeInt API.
src/array.js Removed legacy fixed-length Array implementation.
src/.eslintrc.js Removed legacy ESLint config for src JS.
rollup.config.mjs Added Rollup build for ESM/CJS bundles + bundled .d.ts output.
README.md Updated docs to the new v5-style static schema API and migration link.
package.json Updated package exports/build/test/lint scripts and Node engine requirement.
karma.conf.js Removed legacy Karma browser test runner config.
Gemfile.lock Removed Ruby toolchain lockfile (xdrgen tooling).
Gemfile Removed Ruby xdrgen dev dependencies.
examples/union.ts Updated union example to new builders + Uint8Array boundary conversions.
examples/union.js Removed legacy v4 DSL-based union example.
examples/typedef.ts Added v5-style typedef example (but currently imports from dist).
examples/typedef.js Removed legacy v4 typedef example.
examples/struct.ts Updated struct example to new builders + plain object values.
examples/struct.js Removed legacy v4 DSL-based struct example.
examples/linked_list.ts Updated recursive struct example to use lazy().
examples/linked_list.js Removed legacy v4 DSL-based linked list example.
examples/enum.ts Updated enum example to numeric enum members and nameByValue metadata.
examples/enum.js Removed legacy v4 DSL-based enum example.
eslint.config.mjs Added ESLint v9 flat config with typescript-eslint + prettier integration.
CHANGELOG.md Added v5 breaking-change notes and migration guidance.
bower.json Removed Bower packaging metadata.
babel.config.json Removed Babel configuration (no longer using Webpack/Babel).
.travis.yml Removed legacy Travis CI configuration.
.husky/pre-commit Updated Husky hook (currently missing required shell header).
.eslintrc.js Removed legacy ESLint config (replaced by flat config).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/helpers.ts
Comment thread src/types/enum.ts
Comment thread .husky/pre-commit
Comment thread CHANGELOG.md Outdated
Comment thread examples/typedef.ts Outdated
Comment thread package.json

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 131 out of 134 changed files in this pull request and generated 2 comments.

Comment thread pnpm-workspace.yaml
@@ -0,0 +1 @@
minimumReleaseAge: 4320
Comment thread .husky/pre-commit
@Ryang-21 Ryang-21 merged commit 3f1c7e7 into master Jun 1, 2026
8 checks passed
@Ryang-21 Ryang-21 deleted the static-class-refactor branch June 1, 2026 22:25
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.

3 participants