> For the complete documentation index, see [llms.txt](https://docs.menanak47.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.menanak47.com/plugins/ak47_lib/imports/callback.md).

# Callback

The `ak47_lib` features a powerful, two-way callback system built on promises. This allows you to easily request data from the Server to the Client, or from the Client to the Server, yielding the thread until a response is received or a timeout occurs.

You can access these functions via the `Lib47.Callback` namespace.

### Client to Server Callbacks

These functions are used when a Client script needs to request data from the Server.

#### `Lib47.Callback.Register` (Server-Side)

Registers a server-side callback that can be triggered by clients. Duplicate registrations will output an error to the console to prevent overlapping event handlers.

```lua
--- @param name string The unique name of the callback
--- @param cb function The function to execute when called. The first parameter is ALWAYS the player's source.
Lib47.Callback.Register('ak47_lib:server:getPlayerData', function(source, arg1, arg2)
    -- The first argument is automatically the invoking player's server ID
    local player = Lib47.GetPlayer(source)
    local money = Lib47.GetMoney(source, 'cash')
    
    -- You can return a single value, multiple values, or nil
    return money, player.job.name
end)
```

#### `Lib47.Callback.Await` (Client-Side)

Triggers a registered server callback and waits for the response. If the server takes longer than the configured timeout (defaulting to 15 seconds), it will automatically resolve as `nil` and print a timeout warning.

```lua
--- @param name string The name of the callback to trigger
--- @param _ nil The second argument is ignored on the client (used for target parity)
--- @param ... any Any additional arguments you want to pass to the server
--- @return ... any Returns the unpacked values sent back by the server
local cashBalance, jobName = Lib47.Callback.Await('ak47_lib:server:getPlayerData', nil, "extra_arg1", "extra_arg2")

if cashBalance then
    print(("I have $%s and I work as a %s"):format(cashBalance, jobName))
else
    print("Server failed to respond in time.")
end
```

### Server to Client Callbacks

These functions are used when the Server needs to request data from a specific Client (e.g., checking their UI state, getting a waypoint coordinate, or verifying a client-side entity).

#### `Lib47.Callback.Register` (Client-Side)

Registers a client-side callback that can be triggered by the server.

```lua
--- @param name string The unique name of the callback
--- @param cb function The function to execute when called by the server.
Lib47.Callback.Register('ak47_lib:client:getWaypointCoordinates', function(arg1)
    -- Execute client-side logic
    local waypoint = GetFirstBlipInfoId(8)
    
    if DoesBlipExist(waypoint) then
        local coords = GetBlipInfoIdCoord(waypoint)
        return coords -- Return data to the server
    end
    
    return nil
end)
```

#### `Lib47.Callback.Await` (Server-Side)

Triggers a registered client callback on a specific player and waits for the response. If the target player doesn't exist or fails to respond within the timeout, it resolves to `nil`.

```lua
--- @param name string The name of the callback to trigger
--- @param target number The server ID of the player you are requesting data from
--- @param ... any Any additional arguments you want to pass to the client
--- @return ... any Returns the unpacked values sent back by the client
local targetPlayerId = 1
local waypointCoords = Lib47.Callback.Await('ak47_lib:client:getWaypointCoordinates', targetPlayerId, "optional_arg")

if waypointCoords then
    print("Player's waypoint is at: " .. json.encode(waypointCoords))
else
    print("Player does not have a waypoint or failed to respond.")
end
```
