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();
}
Note

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);
}
Warning

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
Previous Statistics
Next Dynamic