I know {.importcpp.} is used for c++ backend and {.importjs.} should be used for js backend, but both pragmas are used in the js/dom.nim lib.
The manual says:
"ImportJs pragma Similar to the importcpp pragma for C++, the importjs pragma can be used to import Javascript methods or symbols in general. The generated code then uses the Javascript method calling syntax: obj.method(arg)."
So, for a constructor in js api, I would have to use {.importcpp.}?
Example:
new CustomEvent(type, options)
Some docs and examples https://github.com/nim-lang/Nim/wiki/Nim-for-TypeScript-Programmers#interoperability-template
Also as example check the code at https://github.com/juancarlospaco/nodejs#documentation
My naive expectation was that importjs and importcpp are exactly the same and the only difference is that importjs came later (to feel more natural when wrapping js) so in some places there is still importccp used but it could be safely changed to importjs. And that their use case is to support method call syntax in contrast to importc (where c stands for compatible with backend and not C as in the language) that supports the standard function call syntax:
proc method(obj: var MyJsObject, arg: string) {. importjs .}
# translates to obj.method(arg) in js
proc foo(a: string, b: int) {. importc .}
# translates to foo(a, b) in js
Next thing I now is that for more complex use case you can emit js code.
After seeing some of the links provided by @juancarlospaco I see there is nice syntax supported by imports that I though previously would require an emit. And I am not very sure my naive expectation is true. Also I am surprised to see very little use of importc in nodejs package, so I guess it is not that much needed.
I have done very little js wrapping but I have not found a lot of documentation around, the best resources are usually looking at code and trying things out (and the advice is to compile to js with -d:danger to see reduced noise). Would very much welcome more explanations on this or pointers to resources. :)
Yes, that is I wanted to try:
newEvent*(name: cstring): Event {.importcpp: "new Event(@)", constructor.}
in dom.nim compiles to JS:
event_1124073573 = new Event(eventType_1124073566);
and
newEvent*(name: cstring): Event {.importjs: "new Event(@)", constructor.}
in dom.nim produces identical JS:
event_1124073573 = new Event(eventType_1124073566);
So if the .importcpp.== .importjs. are identical and both pragmas are used in the latest dom.nim, this seems not to be consistent. I guess there is a difference between both pragmas in detail or the use has simply historical reasons.
The proc newEvent*(name: cstring): ... is using name as the parameter, but the standard API from https://developer.mozilla.org/en-US/docs/Web/API/Event/Event?retiredLocale=de is using type and the option parameter is missing.
To be consistent with the actual implementation I would use the no standard name parameter. Maybe this will change in the future. My prototype for the new CustomEvent is:
import std/tables
type
CustomEventOptions* = object
detail: Table[cstring, cstring]
EventOptions* = object
bubbles, cancelable, composed: bool
proc newCustomEvent*(name: cstring, options: CustomEventOptions): Event {.importcpp: "new CustomEvent(@)", constructor.}
Would it be Ok to create this PR?