spyweb injects several global helper functions into the Lua environment for networking,
logging, and storage.
Storage & Persistence
SpyWeb supports state management through both Runtime Memory (transient)
and an Embedded Database (persistent). Memory is fast but resets on
reload; the database survives restarts.
💡 Race Condition Note: Both Runtime Memory and
Job-Local Storage are safe by default. Hooks for a single job are
execution-locked (sequential), so race conditions are impossible within a single job.
Use global_store_incr strictly when you need to mutate state shared across
multiple concurrent jobs.
| Function |
Description |
store_set(key, value) |
Save a string (prefixed with job name) |
store_get(key) |
Retrieve a string or nil |
store_delete(key) |
Remove a key |
Example: Job-Scoped Counter
local c = tonumber(store_get("count") or "0")
store_set("count", tostring(c + 1))
| Function |
Description |
global_store_set(key, value) |
Save a string (shared across all jobs) |
global_store_get(key) |
Retrieve a shared string or nil |
global_store_delete(key) |
Remove a shared key |
global_store_incr(k, def, delta) |
Atomic shared increment across all jobs |
Example: Atomic Shared Logic
-- WRONG APPROACH (race condition prone)
local v = tonumber(global_store_get("visits") or "0")
global_store_set("visits", tostring(v + 1))
-- CORRECT APPROACH (race condition safe)
global_store_incr("visits", 0, 1)
⚠️ Resets on hot-reload or restart. Use for transient state
only.
Standard Lua variables persist in memory as long as the job is
active. Because each job runs in its own Isolated VM, these
variables are naturally job-scoped and cannot be accessed by other jobs.
Example: Simple Memory Counter
-- This resets to 1 if you edit hooks.lua or restart SpyWeb
visit_count = (visit_count or 0) + 1
log("Session visit: " .. visit_count)
http_get(url, [headers])
Performs a synchronous HTTP GET request. The headers argument is an optional
Lua table containing key-value pairs for request headers.
local html = http_get("https://api.example.com", {
["Authorization"] = "Bearer token123",
["X-Custom-Header"] = "my-value"
})
http_post(url, body, [headers])
Performs a synchronous HTTP POST request. By default, it sets the
Content-Type to application/x-www-form-urlencoded unless
overridden in the headers argument.
local response = http_post("https://api.example.com", '{"foo":"bar"}', {
["Content-Type"] = "application/json",
["Accept"] = "application/json"
})
log(message)
Appends a message to hook.log inside the job's directory. This is the
recommended way to debug hooks without using external libraries.
function after_extract(items)
log("Extracted " .. #items .. " items from " .. request.url)
return items
end