Soba Runtime Reference¶
Warning
This document is outdated. We are in the process of rewriting it
Imports¶
In Sobamail platform, all modules use hash values in import statements to guarantee that code is reproducible from the root module down to the last leaf in the import tree. The hash values are simply obtained by encoding Sha224 digest value of module source code using "urlsafe base64" encoding.
Here is a python script that generates the import hash for a given script file.
import sys
import hashlib
for fn in sys.argv[1:]:
digest = hashlib.sha224(io.open(fn, "rb").read()).digest()
digest_b64 = base64.urlsafe_b64encode(digest) \
.replace(b"=", b"") \
.decode("ascii")
print(f"${fn}: ?sha224={digest_b64}")
Special JS Primitives¶
ArrayBuffer (Tagged)
¶
Soba runtime adds a special type of ArrayBuffer
, which is returned by soba.data.*
family of functions. They are used as mutation handles instead of literal binary blobs.
API Reference¶
soba.app.account()
¶
Returns the account associated with the current mailbox.
Returns:
String
: The account name in email address format.
soba.app.instanceId()
¶
Returns the instance id of the current application instance.
Returns:
String
: The instance id.
soba.app.isReplicated()
¶
Returns whether the object key at hand is replicated or not. Replicated objects are the ones that appear in the insertEvent
attributes or the DeleteRow
object.
Returns:
Boolean
:true
if the object at hand is replicated,false
otherwise.
soba.app.mailboxUuid()
¶
Returns the uuid of the current mailbox replica in braced hexadecimal uuid format.
Returns:
String
: The replica uuid, in braced hexadecimal uuid format.
soba.app.objectKey()
¶
Returns the triggering object key.
Returns:
String
: The object key in curly braced namespace format.
soba.app.peers()
¶
Returns the list of users that share this app instance.
Returns:
String[]
: An array of email address strings.
soba.data.delete(table, hash)
¶
Deletes data from the specified table and generates a DeleteRow
mutation with a happens-before relationship with the mutation in the insertEvent
attribute.
Parameters:
table
(String): The name of the table.key
(Any): The hash of the row entry to be deleted, returned by thefind()
orinsert()
function.
soba.data.find(table, object)
¶
Retrieves the mutation hash from the specified table based on the query. It's used to have dynamic happens-before relationships with other mutations. If the mutation can't be found, a fatal exception is thrown.
Parameters:
table
(String): The name of the table.object
(Object): The query object used to search for the data. The object keys must be a subset of column names with LWW constaints.
Returns:
Returns an object with the following attributes:
hash
(ArrayBuffer (Tagged)): The hash of the data that matches the query.deleted
(bool): If the value is not found on the target table but a deletion mutation found in the mutation log, this value is set totrue
, otherwise it'sfalse
.
soba.data.insert(table, data)
¶
Inserts data into the specified table.
Parameters:
table
(String): The name of the table.data
(Object): The data to be inserted. Must be a mapping from column names to values of type (String
,Number
,ArrayBuffer
) or valuenull
.
Return Value:
Returns an object with the following keys:
hash
(ArrayBuffer (Tagged)): The hash value of the inserted mutationinserted: Boolean
:true
means that the mutation was not a duplicate, so it was inserted.false
means that the mutation was a duplicate and was ignored, but the hash for the actual mutation was returned.applied: Boolean
: Same asinserted
.
soba.db.exec(query [, params ...])
¶
Always exposes a read-only SQLite connection.
Throws in replicated context.
Parameters:
query: (String)
: The SQL query to run. Can denote parameters only using the '?' notation.params: (null|true|false|Number|String|ArrayBuffer)
: Zero or more parameters passed to the SQL query.
Return Value:
Returns an object with the following keys:
-
code: Number
: One of SQLite extended return codes. -
data: any[][]
: Array of rows where rows are Array of JS values.
soba.platform.releaseChannel()
¶
Returns the release channel of the current Soba platform implementation.
Return Value:
Returns "Stable"
in the real world.
soba.platform.version()
¶
Returns the version of the current Soba platform implementation.
Throws in replicated context.
Return Value:
Returns an array of integers that represent the version of the current Soba platform implementation.
soba.log.{debug,info,warn,error}(message)
¶
Logs a message with the specified level.
Parameters:
message
(String): The message to be logged.
soba.mail.send(message)
¶
Sends an email.
Throws in replicated context.
Parameters:
message: (Message)
: AMessage
instance.
Return Value:
Nothing.
soba.log.{debug,info,warn,error}(message)
¶
Logs a message with the specified level.
Parameters:
message
(String): The message to be logged.
soba.schema.table(defn)
¶
Creates a table in the local SQLite database with the specified options:
Must be called from the Mutator constructor. Throws otherwise.
Parameters:
defn
(Object): The definition object for the table.name
(String): The name of the table.insertEvent
(Class): Mutation object generated on row insertiondeleteEvent
(Class): Mutation object generated on row deletion. Must beDeleteRow
object from the Base.mjs module.-
columns
(Array): An array of column definitions.name
(String): The name of the column.checks
(Array): An array of single column check objects.-
op
(String): The check operation to be performed. One of:["==", "!=", "typeof", "in", "fk", "lww", "regexp"]
These values mean the following:
-
==
: The equals constraint: The incoming value must be a constant equal to the value stored in thevalue
key. This is enforced by a SQLiteCHECK
constraint, so consult the SQLite docs for exact semantics. -
!=
: The not equals constraint: The incoming value must be a constant not equal to the value stored in thevalue
key. This is enforced by a SQLiteCHECK
constraint, so consult the SQLite docs for exact semantics. -
typeof
: The type-of constraint: The type of the incoming value must equal to the value stored in thevalue
key. Accepted values for this constraint are:["blob", "integer", "null", "real", "text"]
This is enforced by a SQLiteCHECK
constraint, using SQLite'stypeof
operator, so consult the SQLite docs for exact semantics. -
in
: The in constraint: The incoming value must be equal to one of the values stored in the Array inside thevalue
key. This is enforced by a SQLiteCHECK
constraint, using SQLite'sIN
operator, so consult the SQLite docs for exact semantics. -
fk
: The foreign key constraint: The incoming value must be equal to one of the values stored in the given column of the given table. This is enforced by a SQLiteFOREIGN KEY ... ON DELETE CASCADE
constraint. This constraint establishes a happens-before relation between the insert mutation of the target table and the insert mutation at hand. This prevents execution of the mutation at hand by other replicas if its parent mutation is missing. -
lww
: The last-write-wins constraint: The incoming value must be different from one of the values stored in the given column of the current table. This is enforced by a SQLiteUNIQUE
constraint. This constraint establishes a happens-before relation between theDeleteRow
mutation of the insert mutation at hand, if it exists, according to the following rules: -
If the value is missing from the table:
-
If a
DeleteRow
mutation can't be found in the mutation log for the same value, no causal relationship stems from the LWW constraint. -
If a
DeleteRow
mutation is found in the mutation log for the same value, a happens-before relationship is established.
-
-
If the value already exists and the digest value of the new insert mutation matches with the previous insert mutation, the current insert operation is ignored.
-
If the value already exists and the digest value of the new insert mutation does not match with the previous insert mutation, a
DeleteRow
mutation is generated for the column value in previous insert mutation and the new insert mutation is generated to have a happens-before relationship with this newDeleteRow
mutation. -
regexp
: The regular expression constraint: The incoming value must be a string and must match the given regular expression in thevalue
key. This is enforced by a CHECK constraint using SQLite'sREGEXP
operator, which in turn calls into the native regular expression engine of V8, so consult the SQLite, V8 and ECMAScript docs for exact semantics.
-
-
value
(Any): The value to be used in the check. table
(String): The name of the table to be used in foreign key constraintcolumn
(String): The name of the column of the target table to be used in the foreign key constraint.
-
checks
(Array): An array of multi-column check objects.op
(string): The check operation to be performed. One of:["fk", "lww"]
- Check-specific keys specified below:
op === "lww"
: For the Last-Write-Wins check:columns
(string[]): The name of the columns to be used in the LWW checks.value
(true): Must betrue
op === "fk"
: For the Foreign Key check:table
(string): The name of the target table.columns
({col:string}[]): A mapping from column names of the source table to the column names of the target table
The multi-column FK and LWW checks operate the same as their single-column variants. The column names and values are serialized to JSON and treated exactly like the single-column constraints.
soba.task.emit(object)
¶
Used to return a persistent response to the current event. Useful for triggering other apps.
Parameters:
object: null|true|false|String|Number|ArrayBuffer|Array|Object
: A Javascript object that can be serialized as msgpack.
Returns:
Nothing.
soba.task.respond(object)
¶
Used to return an ephemeral response to the current event. Useful for responding to application GUI requests.
Parameters:
object: null|true|false|String|Number|ArrayBuffer|Array|Object
: A Javascript object that can be serialized as msgpack -- ie only consisting of the listed primitives.
Returns:
Nothing.
soba.type.folderName.isValid(s)
¶
Checks whether the given string is a valid folder name.
Parameters:
s
(String): The string to be checked
Returns:
Boolean
:true
if the string is a valid folder name,false
otherwise.
soba.type.userName.isValid(s)
¶
Checks whether the given string is a valid user name.
Parameters:
s
(String): The string to be checked
Returns:
Boolean
:true
if the string is a valid user name,false
otherwise.
soba.type.uuid.v4()
¶
Generates a UUIDv4.
Throws in replicated context.
Returns:
String
: A new uuid, in braced hexadecimal uuid format.