JavaScript Callbacks to the Host Application

Question: Can Chilkat.Js make callbacks into the host application?

Quick Answer: A Chilkat.Js script cannot directly call host functions. Instead, the script could return a description of the next requested action, the application performs that action, and then re-enters the script (or calls another script) with the result. This allows complex scripted workflows without requiring direct callbacks from JavaScript into the host.

An Alternative Conversational Model

A good alternative is to make the JavaScript describe requested host actions, instead of directly calling back into the host.

The general pattern is:

  1. The host calls a JS function and passes input/state.
  2. The JS function returns a structured result saying one of:
    • “I’m finished, here is the final result.”
    • “Please do this host action next.”
  3. The host performs that action.
  4. The host calls JS again, passing the action result back in.
  5. Repeat until the script says it is done.

So instead of true callbacks, you get a request/response conversation between host and script.

A simple mental model is that the script acts like a workflow engine or state machine.

Example shape of what JS might return:

{
  "status": "need_host_action",
  "action": "http_get",
  "params": {
    "url": "https://example.com/data"
  },
  "nextState": {
    "step": 2
  }
}

Then the host does the HTTP GET and calls JS again with:

{
  "state": {
    "step": 2
  },
  "hostResult": {
    "statusCode": 200,
    "body": "..."
  }
}

Then JS can decide the next thing to do.

A practical design is to define one JS entry point such as:

function runStep(inputJson) {
    // inputJson contains:
    // - script state
    // - initial user data or prior host action result
    // return JSON describing:
    // - done/final result
    // - or next host action to perform
}

The host keeps calling runStep(...) until JS returns something like:

{
  "status": "done",
  "result": {
    "message": "Workflow completed successfully"
  }
}

This works well for things such as:

  • file operations
  • database queries
  • HTTP requests
  • UI prompts
  • sending email
  • business-rule workflows

It is often better than direct callbacks because:

  • the boundary between JS and host stays simple
  • you can validate every requested action before doing it
  • you can log each step
  • you can restrict which host actions are allowed
  • it is easier to debug and safer to sandbox

A clean architecture is to treat the JS as producing commands. For example:

  • read_file
  • write_file
  • show_dialog
  • query_database
  • send_http_request

The host receives a command object, executes it, and sends back a result object.

You can even support multi-step scripting with something like this:

function next(input) {
    var ctx = JSON.parse(input);

    if (!ctx.state) {
        return JSON.stringify({
            status: "need_host_action",
            command: "read_file",
            args: { path: "config.json" },
            state: { step: "waiting_for_config" }
        });
    }

    if (ctx.state.step == "waiting_for_config") {
        var configText = ctx.hostResult.content;
        return JSON.stringify({
            status: "need_host_action",
            command: "show_message",
            args: { text: "Config loaded: " + configText },
            state: { step: "done" }
        });
    }

    if (ctx.state.step == "done") {
        return JSON.stringify({
            status: "done",
            result: { success: true }
        });
    }
}

So the answer is: yes, absolutely. Even without host callbacks, you can implement scripting by using a host-driven execution loop where JavaScript returns declarative instructions, and the host calls back into JavaScript with the results.

The best names for this pattern would be something like:

  • command/request loop
  • coroutine-style stepping
  • workflow/state-machine scripting
  • continuation-based host mediation