Yep, I need a cool logo (and full examples)
> Does Denim provide anyway to automatically build a binding.gyp file
Yes, 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
Run
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())
Run
Basically, `denim build` combines Nim compilation + NodeGYP
denim build src/myprogram.nim
Run
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
Run
> 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:
1. Allow passing any flags to Nim/C compiler
2. Generate a JS index loader to detect the platform/load the corresponding
binary module
3. Command to generate a `package.json`
4. Command `publish` to NPM. Here I need some inspiration. Maybe
[rust-to-npm](https://github.com/a11ywatch/rust-to-npm)
5. Denim should have its own directory, next to `.nimble`, where will store
generated c sources and node-gyp files.
6. Allow linking external C headers (binding.gyp)
[ref](https://nodejs.org/api/addons.html#linking-to-libraries-included-with-nodejs)