Skip to content

Conversation

krodak
Copy link
Contributor

@krodak krodak commented Aug 27, 2025

Introduction

This PR support for enums with associated values of primitive types to the BridgeJS plugin.

This is WIP just to discuss JS / Swift generated code side, I'm working on migrating this to new lifting / lowering approach and align with changes merged over last couple of days and will issue final PR soon.

In the meantime wanted to sync on

  • final d.ts interface
  • JS side shared helper + per enum helpers + use of additional tmpRet = []; parameters - I'd integrate any feedback along migrating to new changes
  • Swift glue code - I'm moving shared _BJSBinaryReader and new extern methods to BridgeJSInstrincics.swift to align with main updates, I'd integrate any feedback on those along the way as well

Overview

I've decided to go with DataView buffer to encode short type information and then payload, to pass single value across the boundaries and unpack it on the other side.

I started with single value primitives using what is currently available, then migrated to serializing parameters into JSON string and with current solution

Other option I've considered but rejected was to generate a separate WASM export function for each enum case - this eliminates the need for case dispatching and parameter packing, but on the other hand it would lead to WASM export explosion given that each case in each enum would end up as separate function and multiple associated values within single case would lead to unreadable long parameters chains.

Examples

Case Enum with Both Styles

@JS enum APIResult {
    case success(String)
    case failure(Int)
    case flag(Bool)
    case rate(Float)
    case precise(Double)
    case info
}
@JS enum ComplexResult {
    case success(String)
    case error(String, Int)
    case status(Bool, Int, String)
    case coordinates(Double, Double, Double)
    case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String)
    case info
}

Generated TypeScript:

export const APIResult: {
    readonly Tag: {
        readonly Success: 0;
        readonly Failure: 1;
        readonly Flag: 2;
        readonly Rate: 3;
        readonly Precise: 4;
        readonly Info: 5;
    };
};

export type APIResult =
  { tag: typeof APIResult.Tag.Success; param0: string } | { tag: typeof APIResult.Tag.Failure; param0: number } | { tag: typeof APIResult.Tag.Flag; param0: boolean } | { tag: typeof APIResult.Tag.Rate; param0: number } | { tag: typeof APIResult.Tag.Precise; param0: number } | { tag: typeof APIResult.Tag.Info }

export const ComplexResult: {
    readonly Tag: {
        readonly Success: 0;
        readonly Error: 1;
        readonly Status: 2;
        readonly Coordinates: 3;
        readonly Comprehensive: 4;
        readonly Info: 5;
    };
};

export type ComplexResult =
  { tag: typeof ComplexResult.Tag.Success; param0: string } | { tag: typeof ComplexResult.Tag.Error; param0: string; param1: number } | { tag: typeof ComplexResult.Tag.Status; param0: boolean; param1: number; param2: string } | { tag: typeof ComplexResult.Tag.Coordinates; param0: number; param1: number; param2: number } | { tag: typeof ComplexResult.Tag.Comprehensive; param0: boolean; param1: boolean; param2: number; param3: number; param4: number; param5: number; param6: string; param7: string; param8: string } | { tag: typeof ComplexResult.Tag.Info }

Testing

All tests are added, after merging fix for nested types nesting and method calls are also working

Docs

Will be added in final PR after updating to accommodate main changes

@krodak krodak requested a review from kateinoigakukun August 27, 2025 07:37
@krodak krodak self-assigned this Aug 27, 2025
@krodak
Copy link
Contributor Author

krodak commented Aug 27, 2025

Closed in favor of #436

@krodak krodak closed this Aug 27, 2025
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