Global Objects
Adama has several built-in global objects that give documents access to platform services, time, randomness, messaging, and identity operations. They're always available -- no imports needed.
Time
The Time global handles temporal values and timezone management. Every document has its own timezone (defaults to "UTC") that affects how dates and times get computed.
Getting Current Values
| Function | Description | Returns |
|---|---|---|
Time.now() |
Current UNIX timestamp in milliseconds | long |
Time.today() |
Current date in document timezone | date |
Time.datetime() |
Current datetime (cached ~60s) | datetime |
Time.datetimeLive() |
Current datetime (updates every ms) | datetime |
Time.time() |
Current time of day in document tz | time |
public long timestamp;
public date today;
public datetime now;
public time current_time;
@construct {
timestamp = Time.now();
today = Time.today();
now = Time.datetime();
current_time = Time.time();
}
Time.datetime() is cached for about 60 seconds, which is fine for most things. Only reach for Time.datetimeLive() when you genuinely need millisecond-level precision -- it creates a dependency that updates more frequently, which has a cost.
Timezone Management
Every document starts in "UTC". Changing the timezone affects how Time.today(), Time.datetime(), and Time.time() compute their values.
| Function | Description | Returns |
|---|---|---|
Time.zone() |
Get the document's timezone | string |
Time.setZone(zone) |
Set the document's timezone | bool |
public string tz;
public bool zone_set;
@construct {
tz = Time.zone(); // "UTC"
zone_set = Time.setZone("America/New_York"); // true
tz = Time.zone(); // "America/New_York"
}
Time.setZone() validates the timezone string against Java's IANA time zone database. Returns true on success, false if the timezone is garbage.
Valid timezone formats:
- IANA identifiers:
"America/New_York","Europe/London","Asia/Tokyo","Australia/Sydney" - UTC offsets:
"UTC","UTC+5:30","UTC-8"
public bool ok1;
public bool ok2;
public bool bad;
@construct {
ok1 = Time.setZone("Europe/London"); // true
ok2 = Time.setZone("Asia/Tokyo"); // true
bad = Time.setZone("Not/A/Zone"); // false - timezone unchanged
}
Timezone Effects on DateTime
When you change the timezone, all subsequent calls to Time.today(), Time.datetime(), and Time.time() reflect the new timezone:
public datetime dt_utc;
public datetime dt_eastern;
#capture_utc {
dt_utc = Time.datetime(); // e.g. 2025-01-15T20:00:00Z[UTC]
Time.setZone("America/New_York");
}
#capture_eastern {
dt_eastern = Time.datetime(); // e.g. 2025-01-15T15:00:00-05:00[America/New_York]
}
Time Utility Functions
These operate on time values and are inherited from the LibTime parent:
| Function | Description | Returns |
|---|---|---|
Time.make(hr, min) |
Create a validated time value | maybe<time> |
Time.toInt(t) |
Convert time to minutes since midnight | int |
Time.extendWithinDay(t, span) |
Add timespan, clamping at midnight | time |
Time.cyclicAdd(t, span) |
Add timespan, wrapping around midnight | time |
Time.overlaps(a, b, c, d) |
Check if time ranges [a,b] and [c,d] overlap | bool |
maybe<time> t = Time.make(14, 30); // 2:30 PM
time evening = @time 23:00;
time extended = Time.extendWithinDay(evening, @timespan 2 hr); // clamped
time wrapped = Time.cyclicAdd(evening, @timespan 2 hr); // wraps to 01:00
bool conflict = Time.overlaps(@time 9:00, @time 10:30, @time 10:00, @time 11:00); // true
Document
The Document global gives you access to the document's identity and lifecycle operations.
Document Identity
| Function | Description | Returns |
|---|---|---|
Document.key() |
Get the document's unique key | string |
Document.space() |
Get the space name | string |
Document.seq() |
Get the current sequence number | int |
public string doc_key;
public string doc_space;
public int doc_seq;
@construct {
doc_key = Document.key();
doc_space = Document.space();
doc_seq = Document.seq();
}
Document Lifecycle
| Function | Description | Returns |
|---|---|---|
Document.destroy() |
Permanently delete this document | void |
Document.rewind(seq) |
Rewind document to a previous sequence | void |
Document.disconnect(who) |
Force disconnect a principal | void |
Document.patch(data) |
Apply a JSON patch to the document | void |
// Force a principal to disconnect
procedure kick_user(principal who) {
Document.disconnect(who);
}
// Apply a dynamic patch
message PatchRequest {
dynamic data;
}
channel apply_patch(PatchRequest req) {
Document.patch(req.data);
}
Document.destroy() permanently deletes the document. There's no undo. Be careful with this one.
Random
The Random global gives you deterministic pseudo-random number generation. The random state is part of the document state, which means it's reproducible during replay -- important for maintaining consistency.
| Function | Description | Returns |
|---|---|---|
Random.genBoundInt(max) |
Random integer in [0, max) | int |
Random.genInt() |
Random 32-bit integer | int |
Random.genDouble() |
Random double in [0.0, 1.0) | double |
Random.getDoubleGaussian() |
Gaussian-distributed random double | double |
Random.genLong() |
Random 64-bit integer | long |
Random.genVec2() |
Random 2D unit vector | vec2 |
Random.genVec3() |
Random 3D unit vector | vec3 |
// Dice roll (1-6)
int roll = Random.genBoundInt(6) + 1;
// Coin flip
bool heads = Random.genDouble() < 0.5;
// Shuffle a table
record Card {
public int id;
public int ordering;
}
table<Card> deck;
procedure shuffle() {
(iterate deck).ordering = Random.genInt();
}
Principal
The Principal global handles identity creation and inspection.
Creating Principals
| Function | Description | Returns |
|---|---|---|
Principal.principalOf(agent) |
Create a principal from an agent ID | principal |
principal p = Principal.principalOf("user123");
// Equivalent extension method:
principal p2 = "user123".principalOf();
Inspecting Principals
| Function | Description | Returns |
|---|---|---|
Principal.agent(p) |
Get the agent string | string |
Principal.authority(p) |
Get the authority string | string |
Principal.isAnonymous(p) |
Check if authority is "anonymous" | bool |
Principal.isAdamaDeveloper(p) |
Check if authority is "adama" | bool |
Principal.isOverlord(p) |
Check if authority is "overlord" | bool |
Principal.isAdamaHost(p) |
Check if authority is "adama-host" | bool |
Principal.fromAuthority(p, auth) |
Check if principal has given authority | bool |
Principal.isFromDocument(p) |
Check if principal is from this document | bool |
Principal.isFromSpace(p) |
Check if principal is from this space | bool |
principal p = Principal.principalOf("admin");
string agent = Principal.agent(p); // "admin"
string auth = Principal.authority(p); // "doc/space/key"
bool is_doc = Principal.isFromDocument(p); // true
bool is_space = Principal.isFromSpace(p); // true
bool is_anon = Principal.isAnonymous(p); // false
// Extension method style
bool from_adama = p.fromAuthority("adama");
ViewState
The ViewState global lets you manipulate client view state from the server side during message handling. These functions only do something meaningful inside channel handlers where there's an active client connection.
| Function | Description | Returns |
|---|---|---|
ViewState.merge(data) |
Merge dynamic data into client view state | bool |
ViewState.goto(view) |
Navigate client to a named view | bool |
ViewState.send(channel, data) |
Send data to client on a named channel | bool |
ViewState.log(message) |
Log a message to the client's view state | bool |
channel submit(SubmitMsg msg) {
// Update the client's view state
ViewState.merge(@dynamic {"status": "processing"});
// Navigate client to results page
ViewState.goto("results");
// Send notification to client
ViewState.send("notification", @dynamic {"message": "Done!"});
// Log for debugging
ViewState.log("submission processed");
}
Messaging
The Messaging global lets you send messages programmatically within a document.
| Function | Description | Returns |
|---|---|---|
Messaging.send(channel, data) |
Send a message to a specific channel | bool |
Messaging.broadcast(channel, data) |
Broadcast a message to all connections | void |
public int event_count;
message Event {
int value;
}
channel on_event(Event e) {
event_count += e.value;
}
procedure trigger_event() {
Messaging.send("on_event", @dynamic {"value": 1});
}
procedure notify_all() {
Messaging.broadcast("on_event", @dynamic {"value": 0});
}
Method Summary
Time
| Function / Method | Returns | Description |
|---|---|---|
Time.now() |
long |
UNIX timestamp (ms) |
Time.today() |
date |
Current date in document timezone |
Time.datetime() |
datetime |
Current datetime (cached ~60s) |
Time.datetimeLive() |
datetime |
Current datetime (live) |
Time.time() |
time |
Current time of day |
Time.zone() |
string |
Document timezone |
Time.setZone(tz) |
bool |
Set document timezone |
Time.make(hr, min) |
maybe<time> |
Create time value |
Time.toInt(t) |
int |
Time to minutes since midnight |
Time.extendWithinDay(t, s) |
time |
Add span, clamp at midnight |
Time.cyclicAdd(t, s) |
time |
Add span, wrap at midnight |
Time.overlaps(a, b, c, d) |
bool |
Check time range overlap |
Document
| Function | Returns | Description |
|---|---|---|
Document.key() |
string |
Document key |
Document.space() |
string |
Space name |
Document.seq() |
int |
Current sequence number |
Document.destroy() |
void | Delete document |
Document.rewind(n) |
void | Rewind to sequence |
Document.disconnect(p) |
void | Force disconnect |
Document.patch(d) |
void | Apply JSON patch |
Random
| Function | Returns | Description |
|---|---|---|
Random.genBoundInt(max) |
int |
Random int in [0, max) |
Random.genInt() |
int |
Random 32-bit int |
Random.genDouble() |
double |
Random double [0, 1) |
Random.getDoubleGaussian() |
double |
Gaussian random |
Random.genLong() |
long |
Random 64-bit int |
Random.genVec2() |
vec2 |
Random 2D unit vector |
Random.genVec3() |
vec3 |
Random 3D unit vector |
Principal
| Function | Returns | Description |
|---|---|---|
Principal.principalOf(agent) |
principal |
Create principal |
Principal.agent(p) |
string |
Get agent string |
Principal.authority(p) |
string |
Get authority string |
Principal.isAnonymous(p) |
bool |
Check anonymous |
Principal.isAdamaDeveloper(p) |
bool |
Check Adama developer |
Principal.isOverlord(p) |
bool |
Check overlord |
Principal.isAdamaHost(p) |
bool |
Check host |
Principal.fromAuthority(p, a) |
bool |
Check authority match |
Principal.isFromDocument(p) |
bool |
Check document scope |
Principal.isFromSpace(p) |
bool |
Check space scope |