Using a class constructor from within an object

I’m trying to use new on an object value, but the JS output treats it as any regular function. Here’s the example:

type module = {
    "Property": ...someProp
    "Connection": @new (~rpcUrl: string, ~commitment: commitment = ?) => connection
}

@module external solanaModule: module = "@solana/web3.js"

let establishConnection = (~rpcUrl: string) => {
  let connection = solanaModule["Connection"](~rpcUrl, ~commitment=#confirmed)
}

In this case, the module exposes different classes as named exports, so I’m trying to construct them properly, but can’t seem to figure out how to use new on object values. The JS output is

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Curry = require("rescript/lib/js/curry.js");
var Web3Js = require("@solana/web3.js");

function establishConnection(rpcUrl) {
  Curry._2(Web3Js.Connection, rpcUrl, "confirmed");
}

exports.establishConnection = establishConnection;

But should actually be

new Web3Js.Connection(rpcUrl, "confirmed");

Have I just gone down the wrong path here on exposing multiple named class exports from a JS module?

It looks like

@module("@solana/web3.js") @new external makeConnection: (~rpcUrl: string, ~commitment: commitment=?) => connection = "Connection" 

works fine, but I was hoping to be able to group all exports under a single object, record, or module and have only one @module line. I’ll use multiple lines for now and will re-write later if there’s a better way.

Don’t do that, you’ll run into this context issues whenever a function requires this. Generally, whenever you end up with code like solanaModule["Connection"](~rpcUrl, ~commitment=#confirmed), there’s something wrong.

Usually you’d organize classes as a module + type t to represent the instance, and then design @send externals around that to define methods that act on that instance.

// Solana.res

module Connection = {
  type t
  @module("@solana/web3.js") @new makeConnection: (~rpcUrl: string, ~commitment: commitment=?) => t = "Connection" 

  @send external getBlocks: (t, float) => Js.Promise.t<array<float>>
}

Ah, great thanks! That makes sense.