How would you all create `external` declarations f...
# javascript
m
How would you all create
external
declarations for the following signatures?
Copy code
flatbuffers.Builder = function(opt_initial_size) { ... }
flatbuffers.Builder.prototype.clear = function() { ... }
What I have tried is:
Copy code
@file:JsModule("flatbuffers")
@file:JsNonModule
package flatbuffers

external class Builder(initialSize: Int) {
    fun clear()
}
But I get an error:
TypeError: Builder is not a constructor
t
Copy code
@JsModule("flatbuffers")
@JsNonModule
external object flatbuffers {

    external class Builder(initialSize: Int) {
        fun clear()
    }

}
Like this?
m
Already have it in
package flatbuffers
. Wrapper object hasn't helped
Thank you for the suggestion though
t
Copy code
@JsModule("flatbuffers")
@JsNonModule
external object flatbuffers {

    class Builder(initialSize: Int) {
        fun clear()
    }

}
Works for me 🙂
@bod Fine example where
@JsModule
isn’t fine 😞
m
Hmm... I tried that and it isn't. Maybe it is an issue with my the dependency I'm pulling in...
t
Do you use this library?
m
Yeah version 1.11.0 is a requirement
b
Copy code
@JsModule("flatbuffers")
 @JsNonModule
 external object flatbuffers {
 
     external object Builder {
         fun clear()
         operator fun invoke(initialSize: Int)
     }
 
 }
😟 1
m
Ohhh clever let me try that
TypeError: Cannot read properties of undefined (reading 'invoke')
I'll play with it more today, need to make sure that I've got the build configured right at this point because I'm not sure.
b
Ok, I figured it out! When wrapping js in kotlin, I always find it quite helpful to just console.log entire module from kotlin to inspect its structure. In this case the log output is this:
Copy code
{
  flatbuffers: {
    SIZEOF_SHORT: 2,
    SIZEOF_INT: 4,
    FILE_IDENTIFIER_LENGTH: 4,
    Encoding: { UTF8_BYTES: 1, UTF16_STRING: 2 },
    int32: Int32Array(2) [ 0, 0 ],
    float32: Float32Array(2) [ 0, 0 ],
    float64: Float64Array(1) [ 0 ],
    isLittleEndian: true,
    Long: [Function (anonymous)] {
      create: [Function (anonymous)],
      ZERO: [Object]
    },
    Builder: [Function (anonymous)] { growByteBuffer: [Function (anonymous)] },
    ByteBuffer: [Function (anonymous)] { allocate: [Function (anonymous)] }
  }
}
Notice how
flatbuffer
module exports an object with a single field also called
flatbuffer
. The value of the field is another object which contains your
Builder
class. With all that in mind, here's the working wrapper to reflect it:
Copy code
@JsModule("flatbuffers")
@JsNonModule
external object flatbuffers {
  object flatbuffers {
    class Builder(opt_initial_size:Int = definedExternally) {
      fun clear()
    }
  }
}
🎉 1
🙏 1
Or to avoid unnecessary nesting, place your wrapper into a separate file as
Copy code
@file:JsModule("flatbuffers")
@file:JsNonModule

@JsName("flatbuffers")
external object FlatBuffers {
  class Builder(opt_initial_size:Int = definedExternally) {
    fun clear()
  }
}
Good luck with the rest!
m
Trying this now. Thank you! And now I have a good debugging tool.
❤️ 1
Wow, yeah, it worked.
b
Yeah,
console.log
is a godsend for these kind of things. Just be sure not to use
println
instead as that calls
Any::toString
before printing, which in most cases will just return
[object Object]
m
Hah, I was just about to use
println
b
You'd be surprised how many people still think that
println == console.log
in Kotlin/JS 😄
m
people-- now
😅 1
😁
t
Copy code
@file:JsModule("flatbuffers")
@file:JsNonModule
@file:JsQualifier("flatbuffers")

package flatbuffers

external class Builder(
    opt_initial_size:Int = definedExternally,
) {
    fun clear()
}
Without redundand
object
?