Closed jfilby closed 1 year ago
Just posted on nim forum. Here is a fully working example.
Denim is a hybrid package. Check ~/.nimble/denim
after installation.
Simply denim -h
DENIM 🔥 Native Node/BunJS addons powered by Nim
build <entry> <links> --release
Create a hybrid project via nimble init
, then
import myprogram/submodule
when defined napibuild:
# Running `denim build myprogram.nim` compiles with `-d:napibuild`
import denim # NAPI bindings
import jsony
from strutils import `%`
type
User = object
name: string
enabled: bool
init proc(module: Module) =
# `Env` singleton represent the current `napi_env` context.
module.registerFn(0, "getWelcomeMessage"):
# Create and export a function named `getWelcomeMessage` with no arguments
return %* getWelcomeMessage()
module.registerFn(3, "testWithArgs"):
# a function with 3 arguments.
if not Env.expect(args, "MyProgram", ("name", napi_string), ("city", napi_string), ("?zipcode", napi_number)): return
# retrieve `napi_value` values. ugly too.
# todo macro to `args.has("zipcode")` and `args.get("zipcode")`
let
name = args[0].getStr
city = args[1].getStr
zipcode = if args.len == 3: $(args[2].getInt) else: "n/a"
let output = "Name: $1\nCity: $2\nZipcode: $3" % [name, city, zipcode]
return %* output
module.registerFn(1, "testNapiCall"):
if not Env.expect(args, "ErrorName", ("name", napi_string)): return
var user = User(name: args[0].getStr, enabled: true)
return napiCall("JSON.parse", [%* toJson(user)])
elif isMainModule:
echo(getWelcomeMessage())
Basically, denim build
combines Nim compilation + NodeGYP
denim build src/myprogram.nim
This will generate a dir called denim_build
in root of your project (contains necessary c sources and binding.gyp - this directory gets flushed everytime you run denim build
).
For myprogram.node
check in myprogram/bin
directory
JavaScript
const nim = require('./myprogram.node')
console.log(nim) // {}
console.log(nim.getWelcomeMessage()) // Hello, World!
// nim.testWithArgs()
// Error: Type mismatch parameter: `name`. Got `undefined`, expected `string`
// nim.testWithArgs("J. Doe")
// Error: Type mismatch parameter: `city`. Got `undefined`, expected `string`
let x = nim.testWithArgs("J. Doe", "London") // works because `zipcode` is optional
console.log(x)
// nim.testWithArgs("Doe Again", "London", true) // ...error Got `bool`, expected `number``
let user = nim.testNapiCall("John Do the Do")
console.log(user) // {...}
console.log(user.name) // John Do the Do
What will the High-level API be like? Is it worth waiting for before I start?
Anything that can make code more readable (no ideas yet). A good start would be type definition
(when calling registerFn
. Anyway, the low-level API is pretty stable, you can give a try.
On my todo list for cli:
package.json
publish
to NPM. Here I need some inspiration. Maybe rust-to-npm.nimble
, where will store generated c sources and node-gyp files.The current README is pretty dumb, I will add useful examples soon. Also, I should highlight that Denim is both a library and a CLI toolkit (maybe using a carbon.now.sh screen)
Closing this, I understand how to build the add-on now. Thanks.
It would be very useful if Denim included a utility to build a binding.gyp file given a package name.
I would also like to know: must I list every .c file in the project's cache? Or only the main .c file? Thanks.