Difficulty adding register Before Authenticate Email handler function in typescript

I am a noob to nakama so please be patient.

I just completed the getting started tutorial for typescript and the nakama server. With some amendments I was able to get it to print the “Hello World” message to the console on startup with docker compose.

I am having difficulty when I try to add event handlers.

Here is the init code I’ve created:

let InitModule: nkruntime.InitModule =
        function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, initializer: nkruntime.Initializer) {
    logger.info("Hello World!");
    const registerBeforeAuthenticateEmail: nkruntime.BeforeHookFunction<nkruntime.AuthenticateEmailRequest> = (ctx, logger, nk, req) => {
        logger.info(`login received ${req.username}`)

I see the following error on startup

nakama_1    | {"level":"info","ts":"2022-01-01T12:44:35.106Z","caller":"server/runtime.go:697","msg":"Registered JavaScript runtime Before function invocation","id":"authenticateemail"}

And then the following error on login:

nakama_1    | {"level":"error","ts":"2022-01-01T12:49:56.427Z","caller":"server/runtime_javascript.go:348","msg":"JavaScript runtime function invalid.","key":"registerBeforeAuthenticateEmail"}

I wonder could someone help me with understanding how to proceed from here.

I found the answer. The handler function needed to be defined in the global scope.

@punkle I’m glad you solved it. For some additional context on why this requirement exists I can explain what we do within the JavaScript VM instances.

When the server starts up we parse the JS bundle and check it for errors. We then “deep clone” the abstract syntax tree representation (AST) for the code so we can create VM instances in the pool to be used to serve requests really fast. To do that we need to capture references in a few places to where function handles might be passed into function executions. We’ve got to walk part of the AST and look for patterns that should be cloned.

We do have plans to make this cleverer over time to recognise more “patterns of code” in the AST so that developers can use code patterns they’re comfortable with. This tradeoff is worthwhile to make though because it means code executed in RPCs, match handlers, before/after hooks and other places in the server can eliminate the “start time” of the VM where it would need to parse the code all over again.

Hope this helps.