ScrewtopDB API Reference

144 methods, 32 factory functions, 1 concepts, 45 REST endpoints. Generated from the screwtopdb-docs database.

Screwtop

ScrewtopDB method

db().ScrewtopDB(initial)

Concepts

Topic Instancing (concept) method

addTopics({ text, instance: 'new', ...tags }) -> topicId

A name is not a key. Several distinct topic nodes may carry the same name, and
`topicByName` returns every one of them the caller can see -- each with its own
`topicId`. That is what instancing means in v2: identity is the node id, not an
ordinal.

Mint a distinct node by passing a spec with `instance: 'new'`. Both arities work,
and every key in the spec other than `text` and `instance` becomes a tag on the
new node:

db().addTopics({ text: 'blog-article', instance: 'new', status: 'draft' }).end();
db().addTopics({ text: 'blog-article', instance: 'new' }, 'status', 'draft').end();

Capture the returned `topicId` -- it is the only durable handle to that node:

db().addTopics({ text: 'blog-article', instance: 'new' }, 'status', 'draft')
.fn(function(ts) { articleId = ts[0].topicId; })
.end();

Read one node with `topicById(articleId)`, or narrow the by-name set with the
`hasTag` option -- `topicByName('blog-article', { hasTag: 'items' })` keeps only
the nodes carrying that tag, which is the usual way to pick the container out of a
set of same-named nodes. Delete one node with `deleteTopics(articleId)`.

Writes by an ambiguous name are refused rather than guessed: once a name has more
than one node, `addTopics('blog-article', tag, value)` is rejected. Pin the write
with the id instead -- `addTopics(articleId, tag, value)`.

There are no instance NUMBERS. The v1 model -- instance 0 as a shared public copy,
1 and higher as per-user copies, numbered monotonically and never reused -- went
away with the v1 engine, and with it the `instance` option, topicByNameAndInstance,
deleteInstance, and GET/DELETE /:app/instances.json/:text/:instance. The
`apiVersion` option is accepted and ignored, because the behaviour it used to
select is now unconditional.

via (option) method

db().topicByName(name, { via: ... })

The **via** option turns a reader step (topicByName, topicById, findTopics) into a multi-level graph traversal. Each hop follows tag values to the referenced topics, optionally filtering along the way. The result set is replaced by the topics reached at the final hop.

**Shapes:**
- **String**: `via: "friends"` — a single outbound hop on the tag named "friends" (the whole string is one tag name; it is NOT split on dots).
- **Object**: `via: { tag: "friends", with: { age: { $gt: 18 } } }` — single hop with a filter.
- **Array**: `via: [{ tag: "friends" }, { tag: "employer", with: { region: "US" } }]` — explicit multi-hop list.
- **Inbound**: add `inbound: true` to a hop to traverse the reverse edge ("who references this topic?"): `via: { tag: "friends", inbound: true }`.

**Filtering with `with`:** a hop may carry a `with` object that keeps only destinations matching the given outbound tag:value pairs. Keys AND together. The filter key is `with` (NOT `filter`). Per-value operators:
- plain string — exact match
- `$not: X` — negation
- `$contains: "X"` — substring match
- `$gt` / `$gte` / `$lt` / `$lte: "X"` — comparison (numeric or lexicographic)
- `$none: X` — passes only when NO value on the tag matches X
- `$or: [ { tag: val }, ... ]` — OR across AND-clauses

**Returning edge values (`as: "values"`):** add `as: "values"` to the FINAL hop to return the traversed edge’s values instead of the destination topics.

**Shaping the result (`include`):** the `include` option applies only to the TERMINAL topics; intermediate hops always carry a full include so `with` filters can see every edge. `include` accepts CSV ("inbound,outbound") or an array (["inbound","outbound"]).

See also the related option **recursevia** for unbounded recursive traversal of a single tag name.

Examples

example-via (option)-real pass (runnableIn: node)
Setup:
db().addTopics('AcmeViaOpt','members','alice').end()
Code:
db().topicByName('AcmeViaOpt', { via: 'members' })
    .end(function(ts){ console.log(ts.map(function(t){return t.text;})); })
Output:
["alice"]

viaOption concept

The via option (accepted by topicByName, topicById, findTopics, topics) declares a multi-hop graph traversal from the starting topic. Each hop follows an outbound tag and treats each value's text as a destination topic name.

Forms:

  • String: {via: "departments"} — single hop, no filter.
  • Object: {via: {tag: "departments", with: {region: "US"}}} — single hop with filter.
  • Array: {via: [{tag: "departments", with: {region: "US"}}, {tag: "members", with: {status: "active"}}]} — multi-hop.

The optional with filters destinations by requiring matching outbound tag:value pairs. AND across keys. Operators inside with values: $not, $contains, $gt/$gte/$lt/$lte, $or, $none. Implemented at screwtopdbapi.js:2958-3032.

See also

topicByName · findTopics · topics · topicById

Initialization

appId method

db().appId(arg)
module: ttv-core

Set or get the application ID to be used in subsequent query sequence steps.

ScrewtopDB applications have both a name and an ID. The application's creator specifies the application name
when the app is created with the ScrewtopDB Application Dashboard.
The app ID is assigned by the ScrewtopDB software. Retrieval by ID is slightly more efficient than
retrieval by name.

Parameters

NameTypeRequiredDescription
arg string | number | function(id) ✓ If this argument is a string or number then it is interpreted as
the appID to set. If this argument is a function, it is invoked and passed as its single argument the currently
set app ID. The return value of the function is ignored.

See also

appName

Examples

example-appId-ex1 skipped (runnableIn: browser)
Code:
db()
.appId(123)
.appId(function(id) {
 alert("App ID is " + id + ".");
})
.end()
example-appId-cover pass (runnableIn: node)
Code:
console.log(typeof db().appId);
Output:
function
example-appId-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().appId);
Output:
function

appName method

db().appName(arg)
module: ttv-core

Set or get the application name to be used in subsequent query sequence steps.

ScrewtopDB applications have both a name and an ID. The application's creator specifies the application name
when the app is created with the ScrewtopDB Application Dashboard.
The app ID is assigned by the ScrewtopDB software. Retrieval by ID is slightly more efficient than
retrieval by name.

Parameters

NameTypeRequiredDescription
arg string | number | function(name) ✓ If this argument is a string or number then it is interpreted as
the app name to set. If this argument is a function, it is invoked and passed as its single argument the currently
set app name. The return value of the function is ignored.

See also

appId

Examples

example-appName-ex1 skipped (runnableIn: browser)
Code:
db()
.appName('myappname')
.appName(function(name) {
    alert("App name is " + name + ".");
})
.end()
example-appName-cover pass (runnableIn: node)
Code:
console.log(typeof db().appName);
Output:
function
example-appName-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().appName);
Output:
function

authentication method

db().authentication(app, user, pswd)
module: ttv-core

Set authentication information for use in later server interactions

Users must always log in to add or make changes to application database contents. Depending on
options set for the application, logging in may also be necessary to read database contents.

Authentication information is sent in plaintext and the session identifier assigned to the session
is afterward included in all requests. Thus, only secure connections (those starting with https://)
should be used for authenticated sessions. (This is the default for both authenticated and unauthenticated
requests, so generally you needn't be concerned unless you have specified an alternate URL for interaction
with ScrewtopDb.)

Note that when authentication information is set using this method, session timeouts are disabled.

This is an alternative to the login method. No server communication is performed by this method.
Use authentication when you know the user's credentials are valid to avoid an unnecessary server
interaction. Use login when it is necessary to confirm the validity of the user's credentials immediately,
or a session timeout must be set, or an app login is desired.

Parameters

NameTypeRequiredDescription
appIdOrName string ✓ The application with which to open the session.
user string ✓ The username
pswd string ✓ The password associated with the username

See also

login · logout · appName · appId · session · offline

Examples

example-authentication-ex1 pass (runnableIn: node)
Code:
db()
.authentication('<appname>', '<username>', '<password>')
.end();
example-authentication-cover pass (runnableIn: node)
Code:
console.log(typeof db().authentication);
Output:
function
example-authentication-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().authentication);
Output:
function

login method

db().login(appIdOrName, user, pswd, sessionTimeout, appLogin)
module: ttv-core

Authenticate a user and create a session for further interaction.

Users must be authenticated to add or make changes to application database contents. Depending on
options set for the application, logging in may also be necessary to read database contents.

Authentication information is sent in plaintext and the session identifier assigned to the session
is afterward included in all requests. Thus, only secure connections (those starting with https://)
should be used for authenticated sessions. (This is the default for both authenticated and unauthenticated
requests, so generally you needn't be concerned unless you have specified an alternate URL for interaction
with ScrewtopDb.)

Parameters

NameTypeRequiredDescription
appIdOrName string ✓ The application with which to open the session.
user string ✓ The username
pswd string ✓ The password associated with the username
sessionTimeout number Optional. The idle timeout in seconds desired for the session. The default is 10 minutes.
The maximum allowed session timeout is 1 hour (3600 seconds.)
appLogin boolean Optional. If true and the user is the responsible user, the session is created
as the application itself, rather than the user logging in. This allows the responsible user to create, modify,
and delete topics owned by the application and access and change application attributes.

See also

logout · authentication · appName · appId · session · offline

Examples

example-login-cover pass (runnableIn: node)
Code:
console.log(typeof db().login);
Output:
function
example-login-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().login);
Output:
function

logout method

db().logout()
module: ttv-core

End a ScrewtopDb session

See also

login · appId · appName · session

Examples

example-logout-cover pass (runnableIn: node)
Code:
console.log(typeof db().logout);
Output:
function
example-logout-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().logout);
Output:
function

setSession method

db().setSession(session)
module: ttv-core

Manually set the current session state from a previously obtained session object, bypassing the
normal login flow.

Sets the sessionId, appId, appName, username, userTopicId, and version from the provided session object.
Clears the password.

Parameters

NameTypeRequiredDescription
session object ✓ An object with properties: sessionId, appId,
appName, username, userTopicId, version.

See also

login · session · saveSession · restoreSession

Examples

example-setSession-ex1 pass (runnableIn: node)
Code:
// Save a session from one chain and restore it in another
var savedSession;
db()
.login('myApp', 'user', 'pass')
.session(function(sess) { savedSession = sess; })
.end();

// Later, in a different chain:
db()
.setSession(savedSession)
.topicByName('myTopic')
.end();
example-setSession-cover pass (runnableIn: node)
Code:
console.log(typeof db().setSession);
Output:
function
example-setSession-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().setSession);
Output:
function

setVersion method

db().setVersion(ver)
module: ttv-core

Set the API version number used for subsequent requests.

Updates the version at both the chain-local and global level. The version affects version-dependent
behavior such as tag text matching (e.g. how `./` and `../` prefixes are expanded).

Parameters

NameTypeRequiredDescription
ver number ✓ The API version number (e.g. 0 or 1).

See also

db.matchTagText

Examples

example-setVersion-ex1 skipped (runnableIn: reference)
Code:
db.setVersion(1);
example-setVersion-cover pass (runnableIn: node)
Code:
db().setVersion(2).end(function(){ console.log('ok'); })
Output:
ok
example-setVersion-cover2 pass (runnableIn: node)
Code:
db().setVersion(2).end(function(){ console.log('ok'); })
Output:
ok

Database

addTags method

db().addTags(newTagText, newValueText, optionsObj)
module: ttv-core

Add tag and value to each of the topics in the current result set.

Parameters

NameTypeRequiredDescription
newTagText string ✓ The new tag text
newValueText string ✓ The new value text
optionsObj object Options passed to the server that determine how the request is to be
processed. Options are:

- echoTopic - True to have the server include the value topic in its response. Note that the value topic
returned includes only inbound tags. The default is true.
If this option is false, the result set is replaced with an empty array.

- private - True to have tags and values created by this operation be marked as private. Private tags and
values are not accessible to users other than the owner. The default is false.

- appUpdated - If false, causes the lastModified application attribute not to be updated as it would normally be.

See also

addTopics · addValues · updateValue · deleteTopics · deleteTags · deleteValues

Examples

example-addTags-ex1 pass (runnableIn: node)
Code:
db()
 .addTopics('persons', 'friends', 'Raquel')
 .addTags('coworkers', 'Billy', {echoTopic: false})
 .topicByName('persons')
 .tag('coworkers')
 .addValues('Zenaida', {echoTopic: false})
 .topicByName('persons')
 .push()
 .tag('friends')
 .log('friends:')
 .values().text().log()
 .pop()
 .tag('coworkers')
 .log('coworkers:')
 .values().text().log()
 .end();
Output:
friends:
[
  "Raquel"
]
coworkers:
[
  "Billy",
  "Zenaida"
]
example-addTags-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').addTags('age').end(function(){
  db().topicByName('Alice').tags().end(function(ts){
    console.log(ts.map(function(t){return t.text;}).sort());
  });
})
Output:
["age","city"]
example-addTags-cover2 pass (runnableIn: node)
Setup:
db().addTopics('addTags_t','seed','x').end()
Code:
db().topicByName('addTags_t').addTags('newtag').end(function(){ console.log('ok'); })
Output:
ok
example-addTags-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().addTags);
Output:
function

addTopics method

db().addTopics(newData, newTagText, newValueText, optionsObj)
module: ttv-core availableIn: v1, v2 returns: this (chain)

Add a new topic to the screwtopDb database.

If the topic already exists, the tags and values are merged into the existing topic.

Parameters

NameTypeRequiredDescription
newData array|object|string ✓ This argument can be any of the following

- An array of topics (objects containing tags members that contain values members,
all of which contain text members). See example 1.

- a single topic. See example 2.

- an object (possibly with nested sub-objects) to be translated into a topic hierarchy array. See example 3.

- a string that is the topic text. In this case, the second and third arguments must contain the
tag text and value text, respectively. See example 4.
newTagText string The tag text. Required when the first parameter is a string.
newValueText string The value text. Required when the first parameter is a string.
optionsObj object Options passed to the server that determine how the request is to be
processed. Options are:

- echoTopic - True to have the server include the new topic in its response. The default is true.
If this option is false, the result set is replaced with an empty array.

- private - True to have the topics, tags and values created by this operation be marked as private. Private topics, tags, and
values are not accessible to users other than the owner. The default is false.

- appUpdated - If false, causes the lastModified application attribute not to be updated as it would normally be.

- addTagOwner - NOT IMPLEMENTED in v2, and will not be. It controlled a v1 convention in which tag ownership was
expressed as a prefix on the tag NAME (alice:notes), the server prefixing the creating user's name automatically;
passing false let a privileged caller create a tag owned by someone else. v2 replaced name-prefix ownership with
real access control -- owner and acl are carried on the edge itself and enforced by allowTag/allowValue -- so
there is no prefix to suppress. Passing this option has no effect.
newData array|object|string ✓ Topic data: an array of topic objects, a single topic object, a JS object to translate to topic hierarchy, or a topic-name string (in which case newTagText and newValueText are required).
newTagText string Tag text. Required when newData is a string.
newValueText string Value text. Required when newData is a string.
optionsObj object Options bag. See option-echoTopic, option-allowDuplicateValues, option-private.

Options

NameTypeDefaultDescription
echoTopic boolean true If false the result set is replaced with an empty array; the new topic is not echoed back.
allowDuplicateValues boolean false If true tags created by this operation allow duplicate values.
private boolean false If true topics, tags and values created by this operation are private to the owner.

See also

addTags · addValue · updateValue · deleteTopic · deleteTag · deleteValue · updateTopic · addValues

Examples

example-addTopics-ex1 pass (runnableIn: node)
Code:
//
// Insert an array of topics. Same-named topics merge.
//
var dbobjs = [];
dbobjs.push({ text: 'persons', tags: [{ text: 'friends', values: [{ text: 'Bill' }] }] });
dbobjs.push({ text: 'persons', tags: [{ text: 'friends', values: [{ text: 'Connie' }] }] });

db()
 .addTopics(dbobjs, {echoTopic: true})
 .topicByName('persons')
 .values()
 .text()
 .log()
 .end()
Output:
["Bill","Connie"]
example-addTopics-ex2 pass (runnableIn: node)
Code:
//
// Insert a single topic.
//
var dbobj = {
    text: 'persons',
    tags: [{
       text: 'friends',
       values: [{ text: 'Bill' }, { text: 'Jeremy' }, { text: 'Shanika' }]
    }]
};

db()
 .addTopics(dbobj)
 .topicByName('persons')
 .values()
 .text()
 .log()
 .end()
Output:
["Bill","Jeremy","Shanika"]
example-addTopics-ex3 pass (runnableIn: node)
Code:
//
// Insert topics auto-generated from a plain Javascript object. Note that
// there are no tags/values members; the structure is translated. The inner
// 'personal data' object has no text field, so it gets an auto-generated
// unique topic name.
//
db()
.addTopics({
    text: 'persons',
    friends: [
        'Dave',
        { text: 'Carrie', 'personal data': { city: 'New Orleans', spouse: 'Mitchell' } }
    ]
 })
 .topicByName('persons')
 .tag('friends')
 .values()
 .each(function(friend) { alert(friend.text); })
 .topicByName('Carrie')
 .tagValues('personal data')
 .topics()
 .values()
 .text()
 .log()
 .end();
Output:
Dave
Carrie
[
  "New Orleans",
  "Mitchell"
]
example-addTopics-ex4 pass (runnableIn: node)
Code:
//
// The simplest way to add topics.
//
db()
 .addTopics('persons', 'friends', 'Bill')
 .addTopics('persons', 'friends', 'Carl')
 .topicByName('persons')
 .log('The values in the topic:')
 .values()
 .text()
 .log()
 .end();
Output:
The values in the topic:
[
  "Bill",
  "Carl"
]
example-addTopics-cover2 pass (runnableIn: node)
Code:
db().addTopics('addTopics_t','tag1','val1').end(function(t){ console.log(t.length); })
Output:
1
example-addTopics-3string stale (runnableIn: node)
Code:
db().addTopics('Alice', 'city', 'San Francisco')
    .topicByName('Alice').values().text()
    .end(function(t) { console.log(t); })
Output:
["San Francisco"]
example-addTopics-array stale (runnableIn: node)
Code:
db().addTopics([{ text: 'persons', tags: [
    { text: 'friends', values: [{text:'Bill'},{text:'Connie'}] }
]}]).topicByName('persons').values().text()
  .end(function(t) { console.log(t); })
Output:
["Bill","Connie"]

addToValue method

db().addToValue(topicText, tagText, val, notifyId, sourceId)
module: ttv-core

Atomically increase a numeric value.

The single value (or the first value if the tag contains multiple values) in the specified tag within
the specified topic is increased by a specified amount in a single operation, eliminating the possibility of a buried update.

The updated value is returned.

If the tag does not exist, it and the value (set to one) are created and the increase amount is returned.

The returned object replaces the current result set.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic text of the topic containing the value to be increased
tagText string ✓ The text of the tag within the topic that contains the value to be increased.
val integer ✓ The amount by which to increase the value
notifyId string ✓ An identifier that designates the asynchronous notification subscribers to which a copy of the
updated value should be transmitted.
sourceId string ✓ An identifier to be included in asynchronous notifications intended to identify the client from which
the update originated.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · decrementValue · incrementValue · subtractFromValue · setValue · vote · unvote · userVotes

Examples

example-addToValue-cover pass (runnableIn: node)
Setup:
db().addTopics('cnt','n','5').end()
Code:
db().addToValue('cnt','n',3).end(function(){
  db().topicByName('cnt').tagValues('n').end(function(vs){ console.log(vs[0].text); });
})
Output:
8
example-addToValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().addToValue);
Output:
function

addValues method

db().addValues(newValueText, optionsObj)
module: ttv-core

Add a value to each of the tags in the current result set.

Parameters

NameTypeRequiredDescription
newValueText string ✓ The new value text
optionsObj object Optional options bag (e.g. allowDuplicateValues, private).

See also

addTopics · addTags · updateValue · deleteTopics · deleteTags · deleteValues

Examples

example-addValues-ex1 pass (runnableIn: node)
Code:
db()
 .addTopics('persons', 'friends', 'Raquel')
 .addTags('coworkers', 'Billy', {echoTopic: false})
 .topicByName('persons')
 .tag('coworkers')
 .addValues('Zenaida', {echoTopic: false})
 .topicByName('persons')
 .push()
 .tag('friends')
 .log('friends:')
 .values().text().log()
 .pop()
 .tag('coworkers')
 .log('coworkers:')
 .values().text().log()
 .end();
Output:
friends:
[
  "Raquel"
]
coworkers:
[
  "Billy",
  "Zenaida"
]
example-addValues-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'skill', 'js').end()
Code:
db().topicByName('Alice').tag('skill').addValues('py').end(function(){
  db().topicByName('Alice').tagValues('skill').end(function(vs){
    console.log(vs.map(function(v){return v.text;}).sort());
  });
})
Output:
["js","py"]
example-addValues-cover2 pass (runnableIn: node)
Setup:
db().addTopics('addValues_t','vtag','v1').end()
Code:
db().topicByName('addValues_t').tag('vtag').addValues('v2').end(function(){ console.log('ok'); })
Output:
ok

createValue method

db().createValue(topicText, tagText, newValueText, options)
module: ttv-core

Create or update a value.

Update the text of a value if it exists. Create the value (and topic and tag if necessary) if it does not exist.
This method cane be used to maintain a single value in a topic's tag, creating the topic and/or tag if necessary
the first time it is invoked, eliminating the need to first check if a value exists before attempting to update
it.

This method does not update the local cache. Thus, invalidation of the cache is necessary if the new value is
to be retrieved after an update using this method. The updateValue method might be a
better choice in this case.

This method does not alter the result set.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic in which to replace or create the value.
tagText string ✓ The tag in wbhich to replace or create the value.
newValueText string ✓ The new text to replace the existing value text, if any.
options object Optional. The only valid options for this method are appupdated and private. If appupdated is false, this
causes the lastModified application attribute not to be updated as it would normally be. If private is true, the value created or
updated will be private. If private is false, the value will be public, even if it was previously private.

See also

addTopics · addTags · addValues · updateValue · deleteTopics · deleteTags · deleteValues

Examples

example-createValue-ex1 pass (runnableIn: node)
Code:
db()
 .createValue('Jane', 'friend', 'Raquel')
 .topicByName('Jane')
 .tagValues('friend')
 .text()
 .log()
 .invalidateCache()
 .createValue('Jane', 'friend', 'Raquella')
 .topicByName('Jane')
 .tagValues('friend')
 .text()
 .log()
 .end();
Output:
[
  "Raquel"
]
[
  "Raquella"
]
example-createValue-cover pass (runnableIn: node)
Setup:
db().addTopics('cnt','color','red').end()
Code:
db().createValue('cnt','size','large').end(function(){
  db().topicByName('cnt').tagValues('size').end(function(vs){
    console.log(vs.map(function(v){return v.text;}));
  });
})
Output:
["large"]
example-createValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().createValue);
Output:
function

decrementValue method

db().decrementValue(topicText, tagText, notifyId, sourceId)
module: ttv-core

Atomically decrement a numeric value.

The single value (or the first value if the tag contains multiple values) in the specified tag within
the specified topic is decremented in a single operation, eliminating the possibility of a buried update.

The value is not allowed to fall below zero.

The updated value is returned. If the value was zero before the attempt to decrement it, the value is unchanged,
but -1 is returned to indicate that no actual decrement of the value occurred.

If the tag does not exist, it and the value (set to zero) are created and -1 is returned.

The returned object replaces the current result set.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic text of the topic containing the value to be decremented
tagText string ✓ The tag text of the value to be decremented.
notifyId string ✓ An identifier that designates the asynchronous notification subscribers to which a copy of the
updated value should be transmitted.
sourceId string ✓ An identifier to be included in asynchronous notifications intended to identify the client from which
the update originated.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · incrementValue · vote · unvote · userVotes

Examples

example-decrementValue-ex1 pass (runnableIn: node)
Code:
function show(r) { console.log(r.data.value); }
db()
.incrementValue('counter', 'n').fn(show)
.incrementValue('counter', 'n').fn(show)
.decrementValue('counter', 'n').fn(show)
.decrementValue('counter', 'n').fn(show)
.end();
Output:
1
2
1
0
example-decrementValue-cover pass (runnableIn: node)
Setup:
db().addTopics('cnt','n','5').end()
Code:
db().decrementValue('cnt','n').end(function(){
  db().topicByName('cnt').tagValues('n').end(function(vs){ console.log(vs[0].text); });
})
Output:
4
example-decrementValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().decrementValue);
Output:
function

deleteInstance method

db().deleteInstance(topicText, instance)
module: ttv-core

REMOVED in v2, along with the instance numbers it took. The method is still on the
chain, and its result-set form still looks for `topic.instance`, but v2 frames carry
no such field and the server answers DELETE /:app/instances.json/:text/:instance
with HTTP 409 -- so the call silently does nothing.

Delete one node with `deleteTopics(topicId)`. `topicByName(name)`, optionally with
`hasTag`, enumerates the ids. See Topic Instancing (concept).

See also

deleteTopics · topicByNameAndInstance · topicInstancing

Examples

example-deleteInstance-cover pass (runnableIn: node)
Code:
console.log(typeof db().deleteInstance);
Output:
function

deleteTags method

db().deleteTags(tagIds, options)
module: ttv-core

Delete tags in the result set from the ScrewtopDB database

Tags are deleted using a cascade delete operation. This means that the tag and all the
values contained in the tags are deleted. Then any topics
named by the deleted values are deleted if they contain no inbound tags (i.e. they are not referenced
by any remaining topic.) This process continues until there are no unreferenced topics left that were
reachable via outbound tags from the starting topics.

If you want to retain topics referenced only by topics you intend to delete, add a tag to a topic that
will not be deleted with a value referring to the topic you wish to retain. Often, the user topic is a
convenient topic in which to place such a tag.

Topics will not be deleted if they contain a tag owned by a user other than the deleting user. Instead,
all tags owned by the deleting user will be deleted from the topic. An exception to this rule is made for
unique topics. Unique topics owned by the deleting user are deleted regardless of whether they contain
tags owned by another user.

Note that if you delete all the tags of a topic, the topic will automatically be deleted as well.

The argument may also be a FUNCTION returning an id or an array of ids. Chain
arguments are evaluated when the chain is BUILT, so an id captured by an earlier
`.fn()` in the same chain is still undefined by the time a plain argument is read;
a function is called when the step RUNS, which is when the id exists. A function
that returns nothing deletes nothing.

Parameters

NameTypeRequiredDescription
tagIds string|array Optional. If this parameter is present, it is assumed to contain a
tag ID or an array of tag IDs to be deleted and is used instead of the current result set as the source
of tag IDs to delete.
options object Optional. The only valid option for this method is appupdated. If false, this
causes the lastModified application attribute not to be updated as it would normally be.

See also

deleteTopics · deleteValues

Examples

example-deleteTags-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.push()
.tags()
.text()
.log()
.pop()
.tag('friends')
.deleteTags()
.topicByName('persons')
.tags()
.text()
.log()
.end();
Output:
[
  "friends",
  "coworkers"
]
[
  "coworkers"
]
example-deleteTags-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice','city','SF').end()
Code:
db().topicByName('Alice').tag('city').deleteTags().end(function(){
  db().topicByName('Alice').tags().end(function(ts){ console.log(ts.length); });
})
Output:
0
example-deleteTags-cover2 pass (runnableIn: node)
Setup:
db().addTopics('deleteTags_t','x','1').end()
Code:
db().topicByName('deleteTags_t').tag('x').deleteTags().end(function(){
  db().topicByName('deleteTags_t').tags().end(function(ts){
    console.log(ts.filter(function(t){return t && t.tagType !== 'inbound';}).length);
  });
})
Output:
0

deleteTopics method

db().deleteTopics(topicIds, options)
module: ttv-core

Delete topics in the result set from the ScrewtopDB database

Topics are deleted using a cascade delete operation. This means that the topics, all the
tags contained in the topics, and all the values contained in the tags are deleted. Then any topics
named by the deleted values are deleted if they contain no inbound tags (i.e. they are not referenced
by any remaining topic.) This process continues until there are no unreferenced topics left that were
reachable via outbound tags from the starting topics.

If you want to retain topics referenced only by topics you intend to delete, add a tag to a topic that
will not be deleted with a value referring to the topic you wish to retain. Often, the user topic is a
convenient topic in which to place such a tag.

Topics will not be deleted if they contain a tag owned by a user other than the deleting user. Instead,
all tags owned by the deleting user will be deleted from the topic. An exception to this rule is made for
unique topics. Unique topics owned by the deleting user are deleted regardless of whether they contain
tags owned by another user.

With no `topicIds` argument the ids come from the result set: each element
contributes its `topicId`, and an element that IS a bare topic id (a ULID, as
left by `.fn(function(ts) { return ts[0].topicId; })`) is taken as that id --
the same address form the `topicIds` argument accepts. Elements carrying no
topic id contribute nothing, so a result set holding tags, values or plain
strings deletes nothing rather than issuing a delete for a missing id.

The argument may also be a FUNCTION returning an id or an array of ids. Chain
arguments are evaluated when the chain is BUILT, so an id captured by an earlier
`.fn()` in the same chain is still undefined by the time a plain argument is read;
a function is called when the step RUNS, which is when the id exists. A function
that returns nothing deletes nothing.

Parameters

NameTypeRequiredDescription
topicIds string|array Optional. If this parameter is present, it is assumed to contain a
topic ID or an array of topic IDs to be deleted and is used instead of the current result set as the source
of topic IDs to delete.
options object Optional. The only valid option for this method is appupdated. If false, his
causes the lastModified application attribute not to be updated as it would normally be.

See also

deleteTags · deleteValues

Examples

example-deleteTopics-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.text()
.log()
.topicByName('persons')
.deleteTopics()
.topicByName('persons')
.fn(function(ts) { console.log('after delete: ' + ts.length); })
.end();
Output:
[
  "friends",
  "coworkers"
]
after delete: 0
example-deleteTopics-cover pass (runnableIn: node)
Setup:
db().addTopics('Junk','x','1').end()
Code:
db().topicByName('Junk').deleteTopics().end(function(){
  db().topicByName('Junk').end(function(ts){ console.log(ts.length); });
})
Output:
0
example-deleteTopics-cover2 pass (runnableIn: node)
Setup:
db().addTopics('deleteTopics_t','x','1').end()
Code:
db().topicByName('deleteTopics_t').deleteTopics().end(function(){
  db().topicByName('deleteTopics_t').end(function(ts){ console.log(ts.length); });
})
Output:
0

deleteValues method

db().deleteValues(valueIds, options)
module: ttv-core

Delete values in the result set from the ScrewtopDB database

Values are deleted using a cascade delete operation. This means that the
values are deleted and then any topics
named by the deleted values are deleted if they contain no inbound tags (i.e. they are not referenced
by any remaining topic.) This process continues until there are no unreferenced topics left that were
reachable via outbound tags from the starting topics.

If you want to retain topics referenced only by topics you intend to delete, add a tag to a topic that
will not be deleted with a value referring to the topic you wish to retain. Often, the user topic is a
convenient topic in which to place such a tag.

Topics will not be deleted if they contain a tag owned by a user other than the deleting user. Instead,
all tags owned by the deleting user will be deleted from the topic. An exception to this rule is made for
unique topics. Unique topics owned by the deleting user are deleted regardless of whether they contain
tags owned by another user.

Note that if you delete all the values of a tag, the tag will automatically be deleted as well.

The current result set is unaffected by this method.

Parameters

NameTypeRequiredDescription
valueIds string|array Optional. If this parameter is present, it is assumed to contain a
value ID or an array of value IDs to be deleted and is used instead of the current result set as the source
of value IDs to delete.
options object Optional. The only valid option for this method is appupdated. If false, this
causes the application attribute not to be updated as it would normally be.

See also

deleteTopics · deleteTags

Examples

example-deleteValues-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.push()
.values()
.text()
.log()
.pop()
.tag('friends')
.values()
.deleteValues()
.topicByName('persons')
.values()
.text()
.log()
.end();
Output:
[
  "Andy",
  "Mary",
  "Bill",
  "Frank",
  "Wendy"
]
[
  "Frank",
  "Wendy"
]
example-deleteValues-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice','city','SF').end()
Code:
db().topicByName('Alice').tagValues('city').deleteValues().end(function(){
  db().topicByName('Alice').tagValues('city').end(function(vs){ console.log(vs.length); });
})
Output:
0
example-deleteValues-cover2 pass (runnableIn: node)
Setup:
db().addTopics('deleteValues_t','x','v').end()
Code:
db().topicByName('deleteValues_t').tagValues('x').deleteValues().end(function(){
  db().topicByName('deleteValues_t').tagValues('x').end(function(vs){ console.log(vs.length); });
})
Output:
0

findTopics method

db().findTopics(topicText, options)
module: ttv-core

Fetch topics whose name matches a regular expression -- not a shell glob. The pattern matches anywhere in the name, so 'milk' finds 'shopping milk list'; anchor it with ^ and/or $ to pin the match to the start or end of the name. Note that 'user:*' is NOT a glob: read as a regex it means "user" followed by zero or more colons, so it matches every name containing "user" -- write '^user:' instead.

The topics fetched are passed to the following query sequence step as an array. If no topics were
found, an empty array is passed.

This function will initiate a request to the ScrewtopDB server regardless of whether the topics are already in cache.

Parameters

NameTypeRequiredDescription
topicText string ✓ The name (i.e. the topicText) of the topic to fetch
options object Optional. An object containing option names and values to be passed with the request.

Any combination of the following options may be included:

- include - Specify any combination of: "outbound" to include outbound tags, "inbound" to include inbound tags, "allTopics"
to include all topics containing the topicText parameter as a tag, and "allValues" to include all values in tags named with
the topicText parameter. The default is "outbound".

- via - Multi-level graph traversal. Either a string (e.g. "friends.name") for simple hops, or an
object/array describing one or more hops with per-hop filters. Each hop may specify a tag name, filter expression, and
direction ({ inbound: true } for reverse-direction traversal). Filter expressions support the operators
$eq, $contains, $not, $none, $gt, $lt,
$or, $and, and $regex. The result set is replaced by the topics reached at the
final hop. See via option for full syntax.

- recursevia - Recursively adds topics to the result array (which would otherwise contain a single topic) that
are encountered by retrieving the topics of values found in tags matching the value of the recursevia option. Applies
only to outbound tags. (The legacy name recurseVia is also accepted.)

- instance - NOT IMPLEMENTED in v2, and will not be. It selected an instance by ORDINAL, a v1 model where
instance 0 was the shared public copy and 1+ were per-user copies. v2 instancing is identity-based rather than
ordinal: a distinct same-named node is minted with instance:'new' and addressed thereafter by its ULID. There is
no ordinal to select by; to read one specific instance, address it by id.

- apiVersion - Accepted and ignored by the v2 server, because the behaviour it selected is now unconditional: a
name resolves to EVERY node carrying it (topicByName hydrates each and returns them as a list), so a response
already describes all visible instances. There is no single-instance mode to fall back to. Expect data to be a
list; do not assume it holds exactly one topic, though for names never explicitly instanced it always will.

- excludeValueText True to exclude the text member of value objects. This is used to reduce the amount of data
returned when the value text is not needed.

- elide True to omit tag-value text from the response for tags whose values are themselves topic references
(i.e. pure linking tags), reducing payload size. Value objects still include topicId and valueId.

- fromcache True to return a cached copy of the topic if available, skipping the server request entirely.
Useful for patterns that want to consult the cache without triggering network I/O.

- valueFilter A comma-separated list of strings. If any of the strings matches a value in the topic, that value
will be returned. Values whose text does not match one of the valueFilter strings provided are not returned.

- tagFilter A comma-separated list of tag names; only the matching tags are returned (the topic itself is returned even when none match). A name may be owner-qualified, IW style: owner/name keeps only that owner's tag, ./name the caller's own, <appName>/name any owner's. A value written as a regular expression (e.g. ^(question|answer)$) is matched as a regex instead.

- page The zero-based number of the data page to return or a comma-separated two-element list where the
first element is the zero-based page number to return and the second element is the number of elements per page.
Note that totalCount, pageSize, and pageNumber members are returned in the returned topic.

See also

topicById · topicByName · topics

Examples

example-findTopics-ex1 pass (runnableIn: node)
Setup:
db().addTopics('member:alice','login count','5').addTopics('member:bob','login count','3').end()
Code:
db()
.findTopics('member:')
.fn(function(topics) {
    console.log(topics.map(function(t){return t.text;}).sort());
})
.end();
Output:
["member:alice","member:bob"]
example-findTopics-cover pass (runnableIn: node)
Setup:
db().addTopics('alpha-1','x','1').addTopics('alpha-2','x','2').end()
Code:
db().findTopics('alpha').end(function(ts){ console.log(ts.map(function(t){return t.text;}).filter(function(t){return /^alpha-/.test(t);}).sort()); })
Output:
["alpha-1","alpha-2"]
example-findTopics-cover2 pass (runnableIn: node)
Setup:
db().addTopics('findTopics_t_zebra','x','1').addTopics('findTopics_t_zelda','x','2').end()
Code:
db().findTopics('findTopics_t_z').end(function(ts){
  console.log(ts.filter(function(t){return /^findTopics_t_z/.test(t.text);}).length);
})
Output:
2

findTopicsByTag method

findTopicsByTag(tagName, valueText)
module: ttv-core availableIn: v1, v2 returns: Array of stub objects {text, topicInstance, topicId}

List topics that carry a specific tag:value combination. Returns an array of stub
objects {text, topicInstance, topicId} -- one per source topic node that has
tagName=valueText. Follow up with topicById(topicId) for the full topic. The
`topicInstance` field is a v1 vestige and is always 0 in v2; `topicId` is the handle
that actually addresses the node.

Use this instead of findTopics(regex) when you want "topics where tag = value" (the
schema-correct enumeration). findTopics(regex) is a substring/regex search of topic
names with a default page size of 100 -- a different operation. Implemented by
walking the inbound tagName slot on the topic named valueText, so it is correct even
when several distinct nodes share the source name.

Parameters

NameTypeRequiredDescription
tagName string ✓ Tag name to match.
valueText string ✓ Tag value to match.

See also

findTopics · topicByName · topicByNameAndInstance · topics

Examples

example-findTopicsByTag-basic pass (runnableIn: node)
Setup:
db().addTopics('Alice','role','admin')
    .addTopics('Bob','role','admin')
    .addTopics('Carol','role','user').end()
Code:
db().findTopicsByTag('role','admin')
    .end(function(stubs){
        console.log(stubs.map(function(s){return s.text;}).sort());
    })
Output:
["Alice","Bob"]

ftsBuildIndex method

db().ftsBuildIndex()

Trigger a full (re)build of the native FTS index for the current app. Issues POST `/:app/fts.json`.
Result set becomes `[{ count, durationMs }]`. Usually only needed the first time FTS is used against an
app, or after a mass import that bypassed the normal topic-creation path.

See also

ftsSearch · ftsStatus

Examples

example-ftsBuildIndex-cover pass (runnableIn: node)
Setup:
db().addTopics('Alpha','x','1').end()
Code:
db().ftsBuildIndex().end(function(){ console.log('ok'); })
Output:
ok

ftsSearch method

db().ftsSearch(query, options)
module: ttv-fts availableIn: v1, v2 returns: this (chain)

Run a native full-text search over the current app's topics. The result set is replaced with an array of hit
objects of the form `{ topic_id, topicId, text, rank }`, which composes directly with
topics or topicById to fetch the full topic records.

Uses the server's LevelDB-backed FTS5 index. The index is maintained incrementally as topics/tags/values are
added or modified. If the index is missing or stale for an app, call ftsBuildIndex
first. Check availability with ftsStatus.

Parameters

NameTypeRequiredDescription
query string ✓ FTS5-style query. Tokens are AND-ed together by default. Use the mode option to switch to OR. A trailing * enables prefix matching on the final token.
options object Optional. Members:

- limit - maximum hits to return (server default applies if omitted).

- mode - "AND" (default) or "OR" combining of tokens.

- impl - "native" (default) to use the LevelDB-backed index, or "sqlite" to route through the legacy SQLite add-on.
query string ✓ FTS5-style query. Tokens are AND-ed together by default. Use the mode option to switch to OR. A trailing * enables prefix matching on the final token.
opts object Optional: { limit, mode } where mode is "AND" or "OR".

See also

ftsStatus · ftsBuildIndex · topics · findTopics

Examples

example-ftsSearch-ex1 pass (runnableIn: node)
Code:
db()
.appName('<appname>')
.ftsSearch('hello world', { limit: 20 })
.topics()
.each(function(t) { console.log(t.topicText(), t.rank); })
.end();
example-ftsSearch-cover2 pass (runnableIn: node)
Setup:
db().addTopics('ftsSearch_t_apple','x','1').addTopics('ftsSearch_t_apricot','x','2').end()
Code:
db().ftsSearch('ftsSearch_t').end(function(rs){
  console.log(rs.filter(function(t){return /^ftsSearch_t/.test(t.text);}).length >= 2);
})
Output:
true
example-ftsSearch-basic stale (runnableIn: node)
Setup:
db().addTopics('Apollo Mission', 'year', '1969')
    .addTopics('Apollo Theater', 'city', 'Harlem').end()
Code:
db().ftsSearch('apollo')
    .end(function(rs) {
        console.log(rs.map(function(t) { return t.text; }).sort());
    })
Output:
["Apollo Mission","Apollo Theater"]

ftsStatus method

db().ftsStatus()

Report whether the native FTS index is available for the current app, and summarize corpus statistics. The result
set is replaced with a single-element array `[{ available, N, dlSum, loaded, impl }]` where
`N` is the document count and `dlSum` is the total token count.

See also

ftsSearch · ftsBuildIndex

Examples

example-ftsStatus-ex1 pass (runnableIn: node)
Code:
db().ftsStatus().each(function(s) {
    if (!s.available) db().ftsBuildIndex().end();
}).end();
example-ftsStatus-cover pass (runnableIn: node)
Code:
db().ftsStatus().end(function(s){ console.log(typeof s); })
Output:
object

incrementValue method

db().incrementValue(topicText, tagText, notifyId, sourceId)
module: ttv-core

Atomically increment a numeric value.

The single value (or the first value if the tag contains multiple values) in the specified tag within
the specified topic is incremented in a single operation, eliminating the possibility of a buried update.

The updated value is returned.

If the tag does not exist, it and the value (set to one) are created and 1 is returned.

The returned object replaces the current result set.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic text of the topic containing the value to be decremented
tagText string ✓ The tag text of the value to be incremented.
notifyId string ✓ An identifier that designates the asynchronous notification subscribers to which a copy of the
updated value should be transmitted.
sourceId string ✓ An identifier to be included in asynchronous notifications intended to identify the client from which
the update originated.

See also

addTopics · addTags · addValues · addToValue · subtractFromValue · setValue · deleteTopics · deleteTags · deleteValues · decrementValue · vote · unvote · userVotes

Examples

example-incrementValue-ex1 pass (runnableIn: node)
Code:
function show(r) { console.log(r.data.value); }
db()
.incrementValue('counter', 'n').fn(show)
.incrementValue('counter', 'n').fn(show)
.decrementValue('counter', 'n').fn(show)
.decrementValue('counter', 'n').fn(show)
.end();
Output:
1
2
1
0
example-incrementValue-cover pass (runnableIn: node)
Setup:
db().addTopics('cnt','n','1').end()
Code:
db().incrementValue('cnt','n').end(function(){
  db().topicByName('cnt').tagValues('n').end(function(vs){ console.log(vs[0].text); });
})
Output:
2
example-incrementValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().incrementValue);
Output:
function

moveTag method

db().moveTag(insertBeforeTagId, valueId)
module: ttv-core

Relocate a tag within its topic's tag list.

Moving is a modification: the caller must be allowed to modify the topic (its owner, an ACL grant, the app's responsible user, or the super-admin) or must own the tag being moved. Otherwise the server refuses with 403.

This method replaces the current result set with the updated topic.

Note that this method is ineffective in deferredWrite mode.

Parameters

NameTypeRequiredDescription
insertBeforeTagId string ✓ The tag ID before which to insert the tag being moved.
tagId string ✓ The tag ID of the value to be moved.

See also

addTags · deleteTags · moveValue

Examples

example-moveTag-cover pass (runnableIn: node)
Code:
console.log(typeof db().moveTag);
Output:
function
example-moveTag-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().moveTag);
Output:
function

moveValue method

db().moveValue(insertBeforeValueId, valueId, optionsObj)
module: ttv-core

Relocate a value within its tag's value list.

Moving is a modification: the caller must be allowed to modify the value (its owner, an ACL grant, the app's responsible user, or the super-admin) or must own the tag it is in. Otherwise the server refuses with 403.

This method replaces the current result set with the updated topic.

Note that this method is ineffective in deferredWrite mode.

Parameters

NameTypeRequiredDescription
insertBeforeValueId string ✓ The value ID before which to insert the value being moved.
valueId string ✓ The value ID of the value to be moved.

See also

addTags · deleteTags · moveValue

Examples

example-moveValue-cover pass (runnableIn: node)
Code:
console.log(typeof db().moveValue);
Output:
function
example-moveValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().moveValue);
Output:
function

notify method

db().notify(notificationId, obj)

Publish an arbitrary payload to all SSE subscribers of a given notificationId within the current app. Use this to
fan out application-level events (not bound to topic changes) to connected clients.

Parameters

NameTypeRequiredDescription
notificationId string ✓ The SSE channel identifier. Subscribers opened an EventSource at /:app/events/<notificationId>.
obj any ✓ JSON-serializable payload.

See also

subscribe · autoRenderer

Examples

example-notify-cover pass (runnableIn: node)
Code:
console.log(typeof db().notify);
Output:
function

setValue method

db().setValue(topicText, tagText, val, notifyId, sourceId)
module: ttv-core

Atomically set a numeric value.

The single value (or the first value if the tag contains multiple values) in the specified tag within
the specified topic is set to the value specified in a single operation, eliminating the possibility of a buried update.

The updated value is returned.

If the tag does not exist, it and the value (set to one) are created and the specified value is returned.

The returned object replaces the current result set.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic text of the topic containing the value to be decreased
tagText string ✓ The tag text of the value to set.
val integer ✓ The amount by which to increase the value
notifyId string ✓ An identifier that designates the asynchronous notification subscribers to which a copy of the
updated value should be transmitted.
sourceId string ✓ An identifier to be included in asynchronous notifications intended to identify the client from which
the update originated.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · decrementValue · incrementValue · addToValue · subtractFromValue · vote · unvote · userVotes

Examples

example-setValue-cover pass (runnableIn: node)
Setup:
db().addTopics('cnt','n','1').end()
Code:
db().setValue('cnt','n','9').end(function(){
  db().topicByName('cnt').tagValues('n').end(function(vs){ console.log(vs[0].text); });
})
Output:
9
example-setValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().setValue);
Output:
function

subtractFromValue method

db().subtractFromValue(topicText, tagText, val, notifyId, sourceId)
module: ttv-core

Atomically decrease a numeric value.

The single value (or the first value if the tag contains multiple values) in the specified tag within
the specified topic is decreased by a specified amount in a single operation, eliminating the possibility of a buried update.

The updated value is returned.

If the tag does not exist, it and the value (set to one) are created and the negative amount is returned.

The returned object replaces the current result set.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic text of the topic containing the value to be decreased
tagText string ✓ The tag text of the value to subtract from.
val integer ✓ The amount by which to increase the value
notifyId string ✓ An identifier that designates the asynchronous notification subscribers to which a copy of the
updated value should be transmitted.
sourceId string ✓ An identifier to be included in asynchronous notifications intended to identify the client from which
the update originated.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · decrementValue · incrementValue · addToValue · setValue · vote · unvote · userVotes

Examples

example-subtractFromValue-cover pass (runnableIn: node)
Setup:
db().addTopics('cnt','n','10').end()
Code:
db().subtractFromValue('cnt','n',4).end(function(){
  db().topicByName('cnt').tagValues('n').end(function(vs){ console.log(vs[0].text); });
})
Output:
6
example-subtractFromValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().subtractFromValue);
Output:
function

topicById method

db().topicById(topicId, options)
module: ttv-core

Fetch a topic given its ID.

This step passes its result set (an array of topic objects) to the next step.
Typically, there will be zero or one element in the array.

An options object may be included that specifies any combination of the following options:

- **include** - Specify any combination of: "outbound" to include outbound tags, "inbound" to include inbound tags, "allTopics"
to include all topics containing the topicText parameter as a tag, and "allValues" to include all values in tags named with
the topicText parameter. The default is "outbound".

- **via** - Multi-level graph traversal. Either a string (e.g. `"friends.name"`) for simple hops, or an
object/array describing one or more hops with per-hop filters. Each hop may specify a tag name, filter expression, and
direction (`{ inbound: true }` for reverse-direction traversal). Filter expressions support the operators
`$eq`, `$contains`, `$not`, `$none`, `$gt`, `$lt`,
`$or`, `$and`, and `$regex`. The result set is replaced by the topics reached at the
final hop. See via option for full syntax.

- **recursevia** - Recursively adds topics to the result array (which would otherwise contain a single topic) that
are encountered by retrieving the topics of values found in tags matching the value of the recursevia option. Applies
only to outbound tags. (The legacy name `recurseVia` is also accepted.)

- **instance** - NOT IMPLEMENTED in v2, and will not be. It selected an instance by ORDINAL, a v1 model where
instance 0 was the shared public copy and 1+ were per-user copies. v2 instancing is identity-based rather than
ordinal: a distinct same-named node is minted with `instance:'new'` and addressed thereafter by its ULID. There is
no ordinal to select by; to read one specific instance, address it by id.

- **apiVersion** - Accepted and ignored by the v2 server, because the behaviour it selected is now unconditional: a
name resolves to EVERY node carrying it (topicByName hydrates each and returns them as a list), so a response
already describes all visible instances. There is no single-instance mode to fall back to. Expect `data` to be a
list; do not assume it holds exactly one topic, though for names never explicitly instanced it always will.

Ths function will initiate a request to the ScrewtopDB server if the topic requested is not in cache with the options
specified.

Parameters

NameTypeRequiredDescription
topicId string ✓ The topicId of the topic to fetch
options object Optional. An object containing option names and values to be passed with the request.

See also

topicByName · findTopics · topics

Examples

example-topicById-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').end(function(ts){
  db().topicById(ts[0].topicId).end(function(ts2){ console.log(ts2[0].text); });
})
Output:
Alice
example-topicById-cover2 pass (runnableIn: node)
Setup:
db().addTopics('topicById_t','x','v').end()
Code:
db().topicByName('topicById_t').end(function(ts){
  db().topicById(ts[0].topicId).end(function(ts2){ console.log(ts2[0].text); });
})
Output:
topicById_t

topicByName method

db().topicByName(topicText, options)
module: ttv-core availableIn: v1, v2 returns: this (chain)

Fetch a topic given its name (i.e. its topicText).

The topic fetched is passed to the following query sequence step as a single element array. If the topic was not
found, an empty array is passed.

This function will initiate a request to the ScrewtopDB server if the topic requested is not in cache with the options
specified.

Parameters

NameTypeRequiredDescription
topicText string|function ✓ The name (topicText) of the topic to fetch. May also be a function returning the name, or an array of names.
options object Optional. Options bag passed with the request (via, with, hasTag, include, recursevia, apiVersion, valueFilter, tagFilter, page).
topicText string ✓ The name (topicText) of the topic to fetch.
options object Optional bag with via, hasTag, recurseVia, include, fromcache, apiVersion, valueFilter, tagFilter, page.

Options

NameTypeDefaultDescription
via String|Object|Array undefined Multi-hop graph traversal. Follows outbound tag values from the starting topic. Accepts a string (single tag), an object {tag, with}, or an array of objects for multi-hop. The optional "with" property filters destinations by matching outbound tag:value pairs (AND across keys; supports $not, $contains, $gt/$lt, $or, $none).
include string outbound Comma-separated combination of: outbound, inbound, allTopics, allValues.
recursevia string undefined Recursively follow outbound tags matching the given name; returns the full set.
fromcache boolean false If true, only consult the local cache; do not contact the server.
apiVersion number ignored Accepted and ignored by the v2 server. The behaviour it used to select is now
unconditional: a name resolves to EVERY node carrying it, so a response already
describes all visible instances. Expect a list; do not assume it holds exactly one
topic, though for names never explicitly instanced it always will.
hasTag String undefined A tag name. Keeps only topics carrying an outbound tag with exactly this name. topicByName returns the full set of same-named topics, so hasTag selects the ones playing a given role — e.g. the container instance among same-named topics, or whether a shared value topic also acts as a container. Combines with via (filters the traversal's starting topics). v2 server only; the v1 engine ignores it.

See also

topicById · findTopics · topics · topicByNameAndInstance

Examples

example-topicByName-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.fn(function(topics) {
    console.log(topics[0].text + ' has ' + topics[0].tags.length + ' tags');
})
.end();
Output:
persons has 2 tags
example-topicByName-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').end(function(ts){ console.log(ts[0].text); })
Output:
Alice
example-topicByName-basic stale (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'Berkeley').end()
Code:
db().topicByName('Alice').end(function(ts) { console.log(ts[0].text); })
Output:
Alice
example-topicByName-via pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'employer', 'Acme')
    .addTopics('Acme', 'city', 'Oakland').end()
Code:
db().topicByName('Alice', { via: 'employer' })
    .tag('city').values().text()
    .end(function(v) { console.log(v); })
Output:
["Oakland"]
example-topicByName-hasTag pass (runnableIn: node)
Setup:
db().addTopics('release-1.0', 'tickets', 'fix login timeout')
    .addTopics('fix login timeout', 'owner', 'Ann').end()
Code:
// 'fix login timeout' is both a ticket VALUE under release-1.0 and a topic
// in its own right. hasTag asks: does this topic carry the 'owner' role?
db().topicByName('fix login timeout', { hasTag: 'owner' })
    .fn(function(ts) { console.log('with owner: ' + ts.length); })
    .topicByName('release-1.0', { hasTag: 'owner' })
    .fn(function(ts) { console.log('with owner: ' + ts.length); })
    .end();
Output:
with owner: 1
with owner: 0

topicByNameAndInstance method

db().topicByNameAndInstance(topicText, instance, options)
module: ttv-core

REMOVED in v2. It addressed an instance by ORDINAL, and ordinals no longer exist:
a name resolves to a set of distinct nodes identified by `topicId`, not to a
numbered series. The method is still on the chain, but the server answers
GET /:app/instances.json/:text/:instance with HTTP 409 and the call yields an
empty result set.

Use `topicById(topicId)` to fetch one specific node, or `topicByName(name)` for the
whole same-named set -- the `hasTag` option narrows that set to the nodes playing a
given role. See Topic Instancing (concept).

Parameters

NameTypeRequiredDescription
topicText string ✓ The name of the topic to fetch.
instance integer REMOVED in v2. There is no ordinal to pass; address a node by its topicId.
options object Optional. Same options as topicByName.

See also

topicByName · deleteInstance · topicInstancing

Examples

example-topicByNameAndInstance-cover pass (runnableIn: node)
Setup:
db().addTopics('Color','rgb','red').end()
Code:
db().topicByName('Color').fn(function(ts){ return ts; }).end(function(ts){ db().topicById(ts[0].topicId).end(function(t){ console.log(t[0].text); }); })
Output:
Color
example-topicByNameAndInstance-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().topicByNameAndInstance);
Output:
function

topics method

db().topics(arg1, arg2)
module: ttv-core

Add a query step to fetch the topics identified by the topicId properties of the current result set.

This step passes its result set (an array of values) to the next step.

The options parameter may specify one or more include specifications. The possible specifications are:

- **outbound** - These are the tags that were explicitly specified by the user who added the tag or created the topic.

- **inbound** - Inbound tags are the reverse of outbound tags. The values of the inbound tags of topic A are the topics
that contain an outbound tag containing a value referencing topic A.

- **allvalues** - The allvalues specification, when applied to a tag topic (i.e. the topic created for the tag when the
tag is first used), returns the tag named values whose value array contains all the values contained in the tag
in all topics in which it occurs.

- **alltopics** - The alltopics specification, when applied to a tag topic (i.e. the topic created automatically for
the tag when it is first used), returns in the topics tag all the topics that contain the tag.

Note that the parameters of this method are accepted in any order. This to allow either parameter to be included without requiring
the other.

Parameters

NameTypeRequiredDescription
arg1 string Optional. The member name of the topic ID in the result set elements. The default is topicId.
arg2 object Optional. The options to be passed in the server request. This is an object that
may contain the following members:

- depth - How deep in the topic hierarchy the request to go. A value of 1 indicates the topic level only.
2 indicates that tags should be included, and 3 indicates that tags and values both should be included. The
default is 3.

- include - Specifies the tag types to be included. Possible values are "inbound", "outbound", "alltopics",
and "allvalues". Multiple values may be specified by separating the values with commas. For example:
"inbound,outbound". The default is "outbound".

- page - Specifies the page number to return and and optionally the page size. Page numbers begin at zero.
Page size is calculated by the number of leaf nodes returned. With a depth of 3, this equates to the number
of values returned. The default page size is 1000. If both values are specified, they are separated with a comma.
For example, { page: "0,200" } would return the first 200 values. The default is "0,1000".

Examples

example-topics-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.topics({ include: 'alltopics' })
.values()
.text()
.distinct()
.log()
.end();
Output:
[
  "persons"
]
example-topics-cover pass (runnableIn: node)
Code:
console.log(typeof db().topics);
Output:
function
example-topics-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().topics);
Output:
function

unvote method

db().unvote(v, topicId, func)
module: ttv-core

Retract a prior vote on a topic

See userVotes for a description of voting in ScrewtopDb.

Users must be authenticated to unvote. A user can only retract their own votes. The existing vote type
must match the vote type specified in this method.

Parameters

NameTypeRequiredDescription
topicId int Optional. The topic ID of the topic whose vote is to be retracted. If not present, the first
topic in the current result set becomes the vote target
func function Optional. Callback invoked with the result.
v string|int ✓ The value/option whose vote is to be retracted.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · decrementValue · incrementValue · unvote · userVotes

Examples

example-unvote-ex1 skipped (runnableIn: reference)
Code:
See the example for userVotes.
example-unvote-cover pass (runnableIn: node)
Code:
console.log(typeof db().unvote);
Output:
function

updateTopic method

db().updateTopic(newTopicText, topicId, options)
module: ttv-core

Modify a topic's text

Only unique topics and topics which have only tags owned by the authenticated user may be updated. Note that this includes
private topics as well.

Parameters

NameTypeRequiredDescription
newTopicText string ✓ The new text for the topic.
topicId string Optional. The topic id of the topic to update. Defaults to the topic in the current result set.
options object Optional options bag.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues

Examples

example-updateTopic-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').updateTopic('Alicia').end(function(){
  db().topicByName('Alicia').end(function(ts){ console.log(ts[0].text); });
})
Output:
Alicia
example-updateTopic-cover2 pass (runnableIn: node)
Setup:
db().addTopics('updateTopic_t','x','y').end()
Code:
var newName='updateTopic_t_renamed'; db().topicByName('updateTopic_t').updateTopic(newName).end(function(){
  db().topicByName(newName).end(function(ts){ console.log(ts[0].text === newName); });
})
Output:
true

updateValue method

db().updateValue(newValueText, valueId, optionsObj)
module: ttv-core

Update the text of a value.

This method replaces the current result set with the updated value.

Parameters

NameTypeRequiredDescription
newValueText string ✓ The new text to replace the existing value text.
valueId string Optional. The ID of the value to be updated. If this parameter
is not present, the first value found in the current result set is updated.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues

Examples

example-updateValue-ex1 pass (runnableIn: node)
Code:
db()
 .addTopics('persons', 'friends', 'Raquel')
 .topicByName('persons')
 .tagValues('friends')
 .text()
 .log()
 .topicByName('persons')
 .tagValues('friends')
 .updateValue('Raquella')
 .topicByName('persons')
 .tagValues('friends')
 .text()
 .log()
 .end();
Output:
[
  "Raquel"
]
[
  "Raquella"
]
example-updateValue-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').tagValues('city').updateValue('LA').end(function(){
  db().topicByName('Alice').tagValues('city').end(function(vs){ console.log(vs[0].text); });
})
Output:
LA
example-updateValue-cover2 pass (runnableIn: node)
Setup:
db().addTopics('updateValue_t','x','old').end()
Code:
db().topicByName('updateValue_t').tagValues('x').updateValue('new').end(function(vs){ console.log(vs[0].text); })
Output:
new
example-updateValue-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().updateValue);
Output:
function

userVotes method

db().userVotes()
module: ttv-core

Return the user votes array.

Any ScrewtopDb topic may receive votes. A vote may be designated as up, down, or none.
These are designated as 1, 0, and -1 votes, respectively.
Separate counts are maintained for each vote type. A user may vote only once on a topic, but users may
retract their votes and cast a new vote if they wish.

Each user's votes are recorded in their votes user attribute. The attribute contains an array of arrays where the inner
array elements are the topicId and the vote type (-1, 0, or 1).

Each topic that has received votes includes a tally member that in turn contains the members up,
down, none, score, and, if the current user voted for the topic, a voted member.
The first three members are the integer counts of the vote type for that topic. The voted member indicates
how the current user voted on the topic, -1, 0, or 1.

The score member contains an integer between 0 and 10,000,000. It is calculated using the Wilson score
interval. (The lower bound value of which is normally between 0 and 1. The score value is obtained by multiplying the
lower bound by 10 million to allow integer math to be used.) This is intended to be used to sort voted topics for
display based on their relative up- and down-votes.

To include an age component in the score so that newer topics get higher scores than older topics,
divide the score by a value related to the age of the topic. (This is shown in the example.)

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · decrementValue · incrementValue · vote · unvote

Examples

example-userVotes-ex1 pass (runnableIn: node)
Code:
db()
.addTopics('proposal', 'content', 'proposal text')
.topicByName('proposal')
.vote(1, function(result) {
    alert('upvotes: ' + result.tally.up);
})
.userVotes()
.fn(function(votes) {
    alert('topics voted on: ' + votes.length);
})
.end();
Output:
upvotes: 1
topics voted on: 1
example-userVotes-cover pass (runnableIn: node)
Code:
console.log(typeof db().userVotes);
Output:
function

valueById method

db().valueById(valueId, options)
module: ttv-core

Fetch a value given its ID.

This step passes its result set (an array of topic objects) to the next step.
Typically, there will be zero or one element in the array.

An options object may be included that specifies any combination of the following options:

- **excludeValueText** True to exclude the value text from the response. The default is false.

Ths function always initiates a request to the ScrewtopDB server even if the topic requested is in cache.

Parameters

NameTypeRequiredDescription
valueId string ✓ The valueId of the value to fetch
options object Optional. An object containing option names and values to be passed with the request.

See also

topicById · topicByName · topics

Examples

example-valueById-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').values().end(function(vs){
  if (!vs || !vs[0]) { console.log('none'); return; }
  db().valueById(vs[0].valueId).end(function(vs2){ console.log(vs2 && vs2[0] && vs2[0].text); });
})
Output:
SF
example-valueById-cover2 pass (runnableIn: node)
Setup:
db().addTopics('valueById_t','xtag','xval').end()
Code:
db().topicByName('valueById_t').values().end(function(vs){
  var hit=vs.find(function(v){return v.text==='xval';});
  if (!hit) { console.log('none'); return; }
  db().valueById(hit.valueId).end(function(vs2){ console.log(vs2 && vs2[0] ? vs2[0].text : 'none'); });
})
Output:
xval

vote method

db().vote(v, topicId, func)
module: ttv-core

Cast a vote on a topic

See userVotes for a description of voting in ScrewtopDb.

Users must be authenticated to vote.

Parameters

NameTypeRequiredDescription
topicId int Optional. The topic id of the topic being voted on.
func function Optional. Callback invoked with the result.
v string|int ✓ The value/option to vote for.

See also

addTopics · addTags · addValues · deleteTopics · deleteTags · deleteValues · decrementValue · incrementValue · unvote · userVotes

Examples

example-vote-ex1 skipped (runnableIn: reference)
Code:
See the example for userVotes.
example-vote-cover pass (runnableIn: node)
Code:
console.log(typeof db().vote);
Output:
function

Filtering

collect method

db().collect(func)
module: ttv-core

Replace the result set with the collection or results returned when the supplied function is called
for each member of the current result set.

See also

reject · collect · detect · each · func

Examples

example-collect-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
// Get the lengths of the tag text members.
.collect(function(tag) {
    return tag.text.length;
})
.log()
.end();
Output:
[7,9]
example-collect-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().collect);
Output:
function

detect method

db().detect(func)
module: ttv-core

Replace the result set with the first match in the result set based on a supplied match string,
regular expression, or comparison function. If no match is found, the result is set to an empty array.

See also

reject · collect · select · each · func

Examples

example-detect-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
// Detect the first tag ending with an s.
.detect(/^.+s$/)
.text()
.log()
.end();
Output:
[
  "friends"
]
example-detect-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3]).detect(function(x){return x>1;}).end(function(arr){ console.log(arr); })
Output:
[2]

distinct method

db().distinct()
module: ttv-core

Eliminate duplicate elements in the current result set.

This is most useful when duplicate values have been returned from a topics()
request with options including "alltopics" or "allvalues" and the set of distinct topics or values
(i.e. no duplicates) is desired.

Examples

example-distinct-ex1 skipped (runnableIn: reference)
Code:
db(['a','b','c','c','a','d'])
.log()
.distinct()
.log()
.end();
Output:
[
 "a",
 "b",
 "c",
 "c",
 "a",
 "d"
]
[
 "a",
 "b",
 "c",
 "d"
]
example-distinct-cover pass (runnableIn: node)
Code:
db().setValues([1,2,2,3,3,3]).distinct().end(function(arr){ console.log(arr); })
Output:
[1,2,3]

endingWith method

db().endingWith(suffix)
module: ttv-core

Filter the current result set to only items whose `.text` property ends with the given suffix.
The comparison is case-insensitive. Items whose text exactly equals the suffix (same length) are excluded;
the text must be strictly longer than the suffix.

Internally delegates to select with a predicate function.

Parameters

NameTypeRequiredDescription
suffix string ✓ The suffix to match against each item's text property.

See also

select · tag · tags

Examples

example-endingWith-ex1 pass (runnableIn: node)
Code:
db()
.topicByName('myTopic')
.tags()
.endingWith('/comments')
.log()
.end();
example-endingWith-real pass (runnableIn: node)
Setup:
db().addTopics('user.alice','x','1').addTopics('user.bob','x','2').end()
Code:
db().findTopics('user').endingWith('alice')
    .end(function(ts){ console.log(ts.map(function(t){return t.text;}).sort()); })
Output:
["user.alice"]

minimizeTopics method

db().minimizeTopics()
module: ttv-core

Transform the current result set of topic objects into a single minimized plain-object representation.

For each topic that has tags, creates a key equal to the topic's text, whose value is an object mapping
tag text to arrays of value text strings. The result is a single-element array containing the minimized object.

See also

topicByName · topics · collect

Examples

example-minimizeTopics-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'myTopic', title:'My Title', comments:['comment1','comment2']}).end()
Code:
db()
.topicByName('myTopic')
.minimizeTopics()
.log()
.end();
Output:
[
  {
    "myTopic": {
      "title": ["My Title"],
      "comments": ["comment1", "comment2"]
    }
  }
]
example-minimizeTopics-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice','city','SF').end()
Code:
db().topicByName('Alice').minimizeTopics().end(function(arr){ console.log(arr.length); })
Output:
1

reject method

db().reject(func)
module: ttv-core

Remove topics, tags, or values from the result set based on a supplied match string,
regular expression, or comparison function.

See also

reject · collect · detect · each · func

Examples

example-reject-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
// reject also accepts a string or a function — see select.
.reject(/co.+/)
.text()
.log()
.end();
Output:
[
  "friends"
]
example-reject-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3,4]).reject(function(x){return x>2;}).end(function(arr){ console.log(arr); })
Output:
[1,2]

select method

db().select(func)
module: ttv-core

Select topics, tags, or values from the result set based on a supplied match string,
regular expression, or comparison function.

See also

reject · collect · detect · each · func

Examples

example-select-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
// select also accepts a string or a function — see reject.
.select(/co.+/)
.text()
.log()
.end();
Output:
[
  "coworkers"
]
example-select-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3,4]).select(function(x){return x>2;}).end(function(arr){ console.log(arr); })
Output:
[3,4]

setValues method

db().setValues(newValues)
module: ttv-core

Replace the current result set with the provided value or array of values.

If `newValues` is an array, it is used directly as the new result set. Otherwise it is wrapped
in a single-element array.

Parameters

NameTypeRequiredDescription
newValues array or any ✓ The new result set. If not an array, will be wrapped in one.

See also

select · collect · fn

Examples

example-setValues-ex1 pass (runnableIn: node)
Code:
db()
.setValues([1, 2, 3])
.log()
.end();
Output:
[1,2,3]
example-setValues-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3]).end(function(arr){ console.log(arr); })
Output:
[1,2,3]

tag method

db().tag(tagText)
module: ttv-core

Extract tags from the current result set that match a specified pattern.

The tagText argument may be one of the following:

- **owner/tagtext** - where owner is the usernamer of the tag owner and tagtext is the
text of the tag.

- **./tagtext** - ./ is replaced by the current logged-in user, if any, or the username
set as the default username with the options() method.

- **../tagtext** - ../ is replaced by the app name of the current application.

This step passes its result set (an array of tag objects) to the following step.
There will be zero or one element in the array.

Parameters

NameTypeRequiredDescription
tagText string ✓ The text of the tag to fetch. Supports ./tag (current-user prefix), ../tag (app-name prefix), and owner/tag forms.

See also

tags · valuesForTag · select · tagsEndingWith

Examples

example-tag-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tag('coworkers')
.values()
.text()
.log()
.end();
Output:
[
  "Frank",
  "Wendy"
]
example-tag-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').tag('city').end(function(ts){ console.log(ts && ts[0] ? ts[0].text : 'none'); })
Output:
city
example-tag-cover2 pass (runnableIn: node)
Setup:
db().addTopics('tag_t','xtag','v').end()
Code:
db().topicByName('tag_t').tag('xtag').end(function(ts){
  console.log(ts && ts[0] ? ts[0].text : 'none');
})
Output:
xtag

tagById method

db().tagById(tagId)
module: ttv-core

Select the subset of the current query result set having text with a specified suffix.

This step passes its result set (an array of selected objects) to the next step.

Parameters

NameTypeRequiredDescription
suffix string ✓ The string that must suffix the text of all objects to be selected.

Examples

example-tagById-cover pass (runnableIn: node)
Setup:
db().addTopics('persons','friends','Andy').addTopics('persons','coworkers','Frank').end()
Code:
db().topicByName('persons').tags().end(function(tags) {
    var firstId = tags[0].tagId;
    // tagById filters the result set to elements with a matching tagId.
    db().topicByName('persons').tags()
        .tagById(firstId)
        .text()
        .log()
        .end();
});
Output:
[
  "friends"
]
example-tagById-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().tagById);
Output:
function

tags method

db().tags()
module: ttv-core

Extract all tags from all topics in the current result set.

This step passes its result set (array of tag objects) to the following step.

Examples

example-tags-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.text()
.log()
.end();
Output:
[
  "friends",
  "coworkers"
]
example-tags-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').tags().end(function(ts){ console.log(ts.filter(function(t){return t && t.text;}).map(function(t){return t.text;}).sort()); })
Output:
["city"]
example-tags-cover2 pass (runnableIn: node)
Setup:
db().addTopics('tags_t','xtag','v').end()
Code:
db().topicByName('tags_t').tags().end(function(ts){
  console.log(ts.filter(function(t){return t && t.text==='xtag' && t.tagType !== 'inbound';}).length);
})
Output:
1

tagValues method

db().tagValues(tagText)
module: ttv-core

Extract the values for a tag in the current result set given a tag text pattern.

This step passes its result set (an array of value objects) to the following step.
There will be zero or more elements in the array.

The tagText argument may be one of the following:

- **owner/tagtext** - where owner is the usernamer of the tag owner and tagtext is the
text of the tag.

- **./tagtext** - ./ is replaced by the current logged-in user, if any, or the username
set as the default username with the options() method.

- **../tagtext** - ../ is replaced by the app name of the current application.

Parameters

NameTypeRequiredDescription
tagText string ✓ The text of the tag whose values are to be selected.

See also

tag · tags · tagById

Examples

example-tagValues-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tagValues('coworkers')
.text()
.log()
.end();
Output:
[
  "Frank",
  "Wendy"
]
example-tagValues-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').tagValues('city').end(function(vs){ console.log(vs && vs[0] && vs[0].text); })
Output:
SF
example-tagValues-cover2 pass (runnableIn: node)
Setup:
db().addTopics('tagValues_t','xtag','xval').end()
Code:
db().topicByName('tagValues_t').tagValues('xtag').end(function(vs){
  console.log(vs && vs[0] ? vs[0].text : 'none');
})
Output:
xval

values method

db().values()
module: ttv-core

Extract the values of the tags in the current result set.

This step passes its result set (an array of values) to the next step. If the current result set contains topics,
the values of all tags in all topics will be selected. If the current result set contains tags, then all the values
of all tags wiull be selected. If the current result set contains values, the result set will be
passed to the following step unchanged.

Examples

example-values-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.values()
.text()
.log()
.end();
Output:
[
  "Andy",
  "Mary",
  "Bill",
  "Frank",
  "Wendy"
]
example-values-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().topicByName('Alice').values().end(function(vs){ console.log(vs && vs[0] && vs[0].text); })
Output:
SF
example-values-cover2 pass (runnableIn: node)
Setup:
db().addTopics('values_t','xtag','xval').end()
Code:
db().topicByName('values_t').values().end(function(vs){
  var hit=vs.find(function(v){return v.text==='xval';});
  console.log(hit ? hit.text : 'none');
})
Output:
xval

Processing

each method

db().each(func)
module: ttv-core

Invoke a user-supplied function for each element in the result set, passing the following arguments:

- The current result set element

- An environment object whose contents are retained across successive function calls. This
object can be used to accumulate information across function invocations.

- The zero-based integer index of the current result set element.

- The result set array

This method passes the input result set on to the following query sequence step unchanged (unless it is
modified by the user-supplied function.)

Parameters

NameTypeRequiredDescription
func function ✓ the function to be called repeatedly, once for each object in the result set. If the function
returns true, loop execution will cease, and the function will not be called again.

See also

func · select · detect · collect

Examples

example-each-ex1 skipped (runnableIn: browser)
Code:
db(['a', 'b', 'c', 'd', 'e', 'f'])
// See if 'c' is in the list, and if so, where.
.each(function(elem, env, index, all) {
    if (elem == 'c') {
        alert('c found at index ' + index + '.');
        return true;
    }
})
// concatenate the array elements into comma-separated value string.
.each(function(elem, env, index, all) {
    if (!db.isDefined(env.csv)) env.csv = elem;
    else env.csv += ',' + elem;
    // If we're at the end, display the result.
    if (index + 1 == all.length) {
        alert(env.csv);
    }
})
.end();
Output:
c found at index 2.
a,b,c,d,e,f
example-each-cover pass (runnableIn: node)
Code:
var out=[]; db().setValues([1,2,3]).each(function(x){out.push(x*2);}).end(function(){ console.log(out); })
Output:
[2,4,6]
example-each-cover2 pass (runnableIn: node)
Code:
var out=[]; db().setValues([1,2,3]).each(function(x){ out.push(x*2); }).end(function(){ console.log(out); })
Output:
[2,4,6]

fc method

db().fc(func)
module: ttv-core

Invoke a user-supplied function that invokes a callback function, optionally passing to it
the current result set.

The function must expect the callback function as the last argument.

If arguments other than the function are provided, they are passed to the function before the
callback argument. If the string "RS" is passed as an argument, it is replaced by the
current result set when the function is invoked. A callback function is automatically
provided as the last argument.

If the callback function returns a result, the result replaces the current result set.

Parameters

NameTypeRequiredDescription
userfunc function ✓ The function to be invoked.
arg ... Arguments to be passed to the function. If the string "RS" is passed
as an argument, it is replaced by the current result set when the function is invoked.

See also

fn · select · reject · collect · detect · each · func · ps

Examples

example-fc-ex1 skipped (runnableIn: reference)
Code:
db([22,33,44])
.push()
.fc(function(a, b, cb) { cb(a + b.indexOf(33)); }, "index: ", "RS")
.log()
.end();
Output:
[
  "index: 1"
]
example-fc-cover pass (runnableIn: node)
Code:
console.log(typeof db().fc);
Output:
function
example-fc-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().fc);
Output:
function

first method

db().first(func)
module: ttv-core

Select the first element of the result set and optionally pass it to a user-supplied function.

This step passes its result (an array of zero or one element) to the following step in the query sedquence.

Examples

example-first-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.first(function(tag) {
    alert(tag.text + ': ' + tag.valueTextArray());
})
.text()
.log()
.end();
Output:
friends: Andy,Mary,Bill
[
  "friends"
]
example-first-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3]).first().end(function(arr){ console.log(arr); })
Output:
[1]

fn method

db().fn(userfunc, arg)
module: ttv-core

Invoke a user-supplied function, passing to it the current result set.

If this function returns a result, the result replaces the current result set.

Parameters

NameTypeRequiredDescription
userfunc function ✓ The function to be invoked.
arg any An argument to be passed to the function. If this parameter is present, it is
the first parameter passed to the function and the current result set is the second parameter.

See also

select · reject · collect · detect · each · func

Examples

example-fn-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.fn(function(tags) {
    var names = [];
    db.forEach(tags, function(tag) {
        db.forEach(tag.values, function(val) {
            alert(tag.text + ': ' + val.text);
            names.push(val.text);
        });
    });
    return names;
})
.log()
.end();
Output:
friends: Andy
friends: Mary
friends: Bill
coworkers: Frank
coworkers: Wendy
[
  "Andy",
  "Mary",
  "Bill",
  "Frank",
  "Wendy"
]
example-fn-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3]).fn(function(arr){ return arr.map(function(x){return x+10;}); }).end(function(out){ console.log(out); })
Output:
[11,12,13]

ifAny method

db().ifAny(func, elsefunc)
module: ttv-core

Perform an action if the result set contains one or more elements.

The actions that may be performed include stopping the currently executing query sequence, aborting all
query sequences, or invoking a user-supplied function.

Parameters

NameTypeRequiredDescription
elsefunc function|string Optional. Action when the result set IS empty (the else branch). Same forms as func.
func function|string ✓ Action when the result set is non-empty: a function called with the full result set array (a returned value replaces the set), or the string "stop"/"abort" to terminate the sequence.

See also

ifOne · ifNone · ifMany

Examples

example-ifAny-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.ifNone('stop')
.ifMany(function(tags) {
     return tags[0];   // a bare return becomes a single-element result set
})
.ifAny(function(tags) {
     alert(tags[0].text);
})
.end();
Output:
friends
example-ifAny-cover pass (runnableIn: node)
Code:
var hit=false; db().setValues([1]).ifAny(function(){ hit=true; }).end(function(){ console.log(hit); })
Output:
true

ifMany method

db().ifMany(func, elsefunc)
module: ttv-core

Perform an action if the result set contains more than one element.

The actions that may be performed include stopping the currently executing query sequence, aborting all
query sequences, or invoking a user-supplied function.

Parameters

NameTypeRequiredDescription
elsefunc function|string ✓ A function to be invoked if the current result set length not greater than one or
one of the strings 'stop' or 'abort'. If a function is provided and it returns a value, that value
replaces the current result set. The function is passed the current result set as its single
argument. The string 'stop' terminates execution of the current query sequence.
The string 'abort' terminates execution of all query sequences.
func function|string ✓ Action when the result set has more than one element. Same forms as ifAny's func.

See also

ifOne · ifNone · ifAny

Examples

example-ifMany-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.ifNone('stop')
.ifMany(function(tags) {
     return tags[0];   // a bare return becomes a single-element result set
})
.ifOne(function(tag) {
     // Note: unlike ifAny, ifOne passes the single ELEMENT, not the array.
     alert(tag.text);
})
.end();
Output:
friends
example-ifMany-cover pass (runnableIn: node)
Code:
var hit=false; db().setValues([1,2,3]).ifMany(function(){ hit=true; }).end(function(){ console.log(hit); })
Output:
true

ifNone method

db().ifNone(func, elsefunc)
module: ttv-core

Perform an action if the result set is empty.

The actions that may be performed include stopping the currently executing query sequence, aborting all
query sequences, or invoking a user-supplied function.

Parameters

NameTypeRequiredDescription
elsefunc function|string ✓ A function to be invoked if the current result set is not empty or
one of the strings 'stop' or 'abort'. If a function is provided and it returns a value, that value
replaces the current result set. The string 'stop' terminates execution of the current query sequence.
The string 'abort' terminates execution of all query sequences.
func function|string ✓ Action when the result set is empty. Same forms as ifAny's func.

See also

ifOne · ifMany · ifAny

Examples

example-ifNone-ex1 pass (runnableIn: node)
Code:
db()
.topicByName('bogus')
.ifNone(function() {
    alert('not found');
    db.abortAll();
})
.log()
.end();
Output:
not found
example-ifNone-cover pass (runnableIn: node)
Code:
var hit=false; db().setValues([]).ifNone(function(){ hit=true; }).end(function(){ console.log(hit); })
Output:
true

ifOne method

db().ifOne(func, elsefunc)
module: ttv-core

Perform an action if the result set contains one and only one element.

The actions that may be performed include stopping the currently executing query sequence, aborting all
query sequences, or invoking a user-supplied function.

Parameters

NameTypeRequiredDescription
elsefunc function|string ✓ A function to be invoked if the current result set length is not one or
one of the strings 'stop' or 'abort'. If a function is provided and it returns a value, that value
replaces the current result set. The function is passed the current result set element as its single
argument. The string 'stop' terminates execution of the current query sequence.
The string 'abort' terminates execution of all query sequences.
func function|string ✓ Action when the result set has exactly one element. NOTE: unlike ifAny (which receives the full result-set array), ifOne invokes func with the single ELEMENT as its first argument; the full result set is passed as the second argument.

See also

ifNone · ifMany · ifAny

Examples

example-ifOne-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.ifNone('stop')
.ifMany(function(tags) {
     return tags[0];   // a bare return becomes a single-element result set
})
.ifOne(function(tag) {
     // Note: unlike ifAny, ifOne passes the single ELEMENT, not the array.
     alert(tag.text);
})
.end();
Output:
friends
example-ifOne-cover pass (runnableIn: node)
Code:
var hit=false; db().setValues([1]).ifOne(function(){ hit=true; }).end(function(){ console.log(hit); })
Output:
true

last method

db().last(func)
module: ttv-core

Select the last element of the result set and optionally pass it to a user-supplied function.

This step passes its result (an array of zero or one element) to the following step in the query sequence.

See also

first

Examples

example-last-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.last(function(tag) {
    alert(tag.text + ': ' + tag.valueTextArray());
})
.text()
.log()
.end();
Output:
coworkers: Frank,Wendy
[
  "coworkers"
]
example-last-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3]).last().end(function(arr){ console.log(arr); })
Output:
[3]

ps method

db().ps(pfunc)
module: ttv-core

Invoke a user-supplied function that returns a promise. Execute the next step when the promise is resolved.

If the promise returns a result, the result replaces the current result set.

The promise may contain a ScrewtopDB query sequence. In this case the end method typically calls the promise's
resolve callback.

Parameters

NameTypeRequiredDescription
userfunc function ✓ The function to be invoked that returns a promise.
arg any An argument to be passed to the function. If this parameter is present, it is
the first parameter passed to the function and the current result set is the second parameter.

See also

select · reject · collect · detect · each · func · fn

Examples

example-ps-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.ps(function(tags) {
    return new Promise(function(resolve, reject) {
        var names = [];
        db.forEach(tags, function(tag) {
            db.forEach(tag.values, function(val) {
                alert(tag.text + ': ' + val.text);
                names.push(val.text);
            });
        });
        resolve(names);
    });
})
.log()
.end();
Output:
friends: Andy
friends: Mary
friends: Bill
coworkers: Frank
coworkers: Wendy
[
  "Andy",
  "Mary",
  "Bill",
  "Frank",
  "Wendy"
]
example-ps-cover pass (runnableIn: node)
Code:
console.log(typeof db().ps);
Output:
function
example-ps-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().ps);
Output:
function

reverse method

db().reverse()
module: ttv-core

Reverse the order of the elements in the current result set.

Examples

example-reverse-ex1 skipped (runnableIn: reference)
Code:
db(['a','b','c','d','e','f'])
.log()
.reverse()
.log()
.end();
Output:
[
 "a",
 "b",
 "c",
 "d",
 "e",
 "f"
]
[
 "f",
 "e",
 "d",
 "c"
 "b"
 "a"
]
example-reverse-cover pass (runnableIn: node)
Code:
db().setValues([1,2,3]).reverse().end(function(arr){ console.log(arr); })
Output:
[3,2,1]

sort method

db().sort(func)
module: ttv-core

Sort the elements of the result set.

By default, the text members of the result set elements are sorted in ascending order. If the result set
contains strings, the strings are sorted in ascending order.

If a function argument is provided, the result of the function is used to sort the elements.

Parameters

NameTypeRequiredDescription
func function Optional comparator (a, b) returning -1, 0, or 1. If omitted, sorts by the text property, case-insensitive ascending.

See also

reverse

Examples

example-sort-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.values()
// Sort by the text member (case-insensitive ascending).
.sort()
.text()
.log()
.end();
Output:
[
  "Andy",
  "Bill",
  "Frank",
  "Mary",
  "Wendy"
]
example-sort-cover pass (runnableIn: node)
Code:
// Numbers sort numerically; strings and topic objects sort by text.
db().setValues([3, 1, 2]).sort().end(function(arr){ console.log(arr); })
Output:
[1,2,3]
example-sort-cover2 pass (runnableIn: node)
Code:
db().setValues([{text:'c'},{text:'a'},{text:'b'}]).sort().text().end(function(arr){ console.log(arr); })
Output:
["a","b","c"]

text method

db().text(arg1, arg2)
module: ttv-core

Extract the text properties from the current result set.

This step passes a new result set consisting of text strings to the following step.

Notes

- The order of arguments to this method is not enforced (i.e. the arguments may be passed in any order.)

- If the result set is an array of test strings, the strings are processed as if they were the values of text
properties.

Parameters

NameTypeRequiredDescription
arg1 string Optional. The member/property name from which to extract text. Default is "text".
strip boolean ✓ True to strip any UUIDs that are suffixed to the extracted strings

Examples

example-text-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
// db.uniquify appends a GUID suffix; text(true) strips it back off.
.addTopics('persons', 'acquaintances', db.uniquify('Jaquie'))
.topicByName('persons')
.tag('acquaintances')
.values()
.text(true)
.log()
.end();
Output:
[
  "Jaquie"
]
example-text-cover pass (runnableIn: node)
Code:
db().setValues([{text:'a'},{text:'b'}]).text().end(function(arr){ console.log(arr); })
Output:
["a","b"]
example-text-cover2 pass (runnableIn: node)
Code:
db().setValues([{text:'a'},{text:'b'}]).text().end(function(arr){ console.log(arr); })
Output:
["a","b"]

FlowControl

abort method

db().abort()
module: ttv-core

Abort all query sequences in execution.

This method terminates execution of the current sequence, as well as any enclosing sequences. It does not
terminate execution of sequences initiated using the fork or go methods.

Examples

example-abort-cover pass (runnableIn: node)
Code:
db().fn(function(){ console.log('first'); }).end()
Output:
first
example-abort-cover2 pass (runnableIn: node)
Code:
db().fn(function(){ console.log('first'); }).end()
Output:
first

beginServerExecution method

db().beginServerExecution()

Send the sequence steps beginning with the next step to the server for execution.

The steps beginning with the next step and ending with the step before the next endServerExecution
are sent to the server for execution. The result is returned as if the sequence steps had been executed locally.

This facility is provided to allow avoiding passing large volumes of data back to the client for processing when that processing
could be executed on the server where no network traffic is generated.

Not all methods are candidates for execution on the server in this way. Only those methods that do not expect function arguments
may be executed on the server. Methods that produce console output such as log are, of course, useless for
debugging in server-side execution. The best way to prepare server-side sequences is to debug them in the client first.

See also

endServerExecution

Examples

example-beginServerExecution-ex1 pass (runnableIn: node)
Code:
// Note that this example, unlike most examples in this document, while it will execute, will
// not return any values.
db()
.beginServerExecution()
.topicByName('a-topic-with-many-tags-and-values')
.tag('./a-tag-with-many-values')
.values()
.select("text = /phrase-to-find-in-values/")
.endServerExecution()
.log()
.end();
example-beginServerExecution-cover pass (runnableIn: node)
Code:
db().beginServerExecution().endServerExecution().end(function(){ console.log('ok'); })
Output:
ok

delay method

db().delay(ms)
module: ttv-core

Delay execution of the current query sequence for a specified number of milliseconds.

Execution of this method will allow other query sequences to execute, just as the method
waitForCompletion and requests to the server do.

See also

waitForCompletion · fork · go

Examples

example-delay-ex1 skipped (runnableIn: reference)
Code:
See example of fork.
example-delay-cover pass (runnableIn: node)
Code:
var t0=Date.now(); db().delay(50).end(function(){ console.log(Date.now()-t0 >= 40); })
Output:
true
example-delay-cover2 pass (runnableIn: node)
Code:
var t0=Date.now(); db().delay(50).end(function(){ console.log(Date.now()-t0 >= 40); })
Output:
true

end method

db().end(f)
module: ttv-core

Initiates execution of the query, beginning at the first step.

Note that a new query may be constructed and executed within a function invoked by methods including
each and func. When this occurs, the nested sequence's steps
are executed immediately. The parent is resumed after the sub-sequence has completed. The result set
of the parent query sequence is unaffected by the execution of any sub-sequences unless the argument to
this function is true or the function returns a value.

This method is the most common way to initiate query sequence execution.

Parameters

NameTypeRequiredDescription
func function | boolean ✓ A function to be called after the last step of the query completes.
If this function returns a value, it is passed to the next step in the enclosing query sequence, if any.

If this parameter is the boolean value true, then the result set is passed to the next step in the enclosing
query sequence, if any.

See also

go · defer · fork · stop · abort

Examples

example-end-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().end);
Output:
function

endServerExecution method

db().endServerExecution()

Marks the end of sequence steps executed on the server.

See beginServerExecution.

See also

beginServerExecution

Examples

example-endServerExecution-cover pass (runnableIn: node)
Code:
db().beginServerExecution().endServerExecution().end(function(){ console.log('ok'); })
Output:
ok

go method

db().go(func)
module: ttv-core

Defer execution of a nested query sequence until the enclosing sequence has completed.

A seldom-used alternative to the end method.

Parameters

NameTypeRequiredDescription
func function | boolean ✓ A function to be called after the last step of the query completes.

See also

go · defer · fork · stop · abort

Examples

example-go-cover pass (runnableIn: node)
Code:
console.log(typeof db().go);
Output:
function
example-go-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().go);
Output:
function

resume method

db().resume(func)
module: ttv-core

Resume a query sequence whose execution was suspended with wait.

See wait for more information about the wait/resume feature.

Note that no other methods should be chained to the resume method, including end.

Note also that resume may be invoked on a screwtopDb sequence or on the screwtopDb object directly as
is done in the example below.

See also

wait

Examples

example-resume-ex1 skipped (runnableIn: browser)
Code:
.func(function() {
    alert("Setting timeout.");
    setTimeout(function() {
        alert("Timeout expired.")
        db.resume(); // db().resume() also acceptable.
    }, 2000);
})
.wait(function () {
    alert('Waiting...');
})
.log('Waiting done.')
.end();
Output:
Setting timeout.
Waiting...
Timeout expired.
Waiting done.
example-resume-cover pass (runnableIn: node)
Code:
console.log(typeof db().resume);
Output:
function

serverExecute method

db().serverExecute(script)

Send a pre-built chain expression (as a string) to the server's `/:app/scripts.json` endpoint for
execution in the server's own ScrewtopDB interpreter. The response data replaces the current result set.
Most apps should use the beginServerExecution / endServerExecution
pair instead — those build the script string automatically from the wrapped chain steps. Use serverExecute directly
only when you need to construct the script text yourself.

Parameters

NameTypeRequiredDescription
script string ✓ A serialized chain expression such as "topicByName('x').tag('y').values()". Function bodies are not serialized and will be rejected by the server.

See also

beginServerExecution · endServerExecution

Examples

example-serverExecute-cover pass (runnableIn: node)
Code:
console.log(typeof db().serverExecute);
Output:
function

wait method

db().wait(func)
module: ttv-core

Suspend query sequence until resume is called.

This method allows you to suspend execution of a query sequence until the occurrence of an
external event. When the external event occurs (it might be a user-initiated event, a network
event, or a timeout) invoke the resume method to restart query execution.

Only one wait at a time is supported.

Parameters

NameTypeRequiredDescription
func function ✓ Callback invoked after outstanding asynchronous work completes, before the next step runs.

See also

resume

Examples

example-wait-ex1 skipped (runnableIn: browser)
Code:
.func(function() {
    alert("Setting timeout.");
    setTimeout(function() {
        alert("Timeout expired.")
        db.resume();
    }, 2000);
})
.wait(function () {
    alert('Waiting...');
})
.log('Waiting done.')
.end();
Output:
Setting timeout.
Waiting...
Timeout expired.
Waiting done.
example-wait-cover pass (runnableIn: node)
Code:
db().setValues([1]).end(function(arr){ console.log(arr.length); })
Output:
1
example-wait-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().wait);
Output:
function

waitForCompletion method

db().waitForCompletion(func)
module: ttv-core

Wait for any parallel-executing query sequences to complete.

The function argument is invoked when there are no parallel query sequences
in execution except the caller.

Parameters

NameTypeRequiredDescription
func function ✓ Callback invoked once all outstanding operations have completed.

See also

go · delay · fork

Examples

example-waitForCompletion-ex1 skipped (runnableIn: reference)
Code:
See example of fork.
example-waitForCompletion-cover pass (runnableIn: node)
Code:
var c=db().setValues([1,2,3]).end(); db().waitForCompletion(c).end(function(){ console.log('done'); })
Output:
done
example-waitForCompletion-cover2 pass (runnableIn: node)
Code:
var c=db().setValues([1,2,3]).end(); db().waitForCompletion(c).end(function(){ console.log('done'); })
Output:
done

SaveAndRestore

deleteSavedContext method

db().deleteSavedContext(index)
module: ttv-core

Delete a previously saved context

This step passes the incoming result set unchanged to the following step.

Parameters

NameTypeRequiredDescription
index string|number ✓ The identifier of the result set to delete

See also

saveContext · restoreContext

Examples

example-deleteSavedContext-ex1 skipped (runnableIn: browser)
Code:
db([1,2,3])
.onError(function(err) { alert(err); })
.saveContext('xxx')
.restoreContext('xxx')
.deleteSavedContext('xxx')
.restoreContext('xxx')
.end()
Output:
Attempt to restore unsaved context "xxx".
example-deleteSavedContext-cover pass (runnableIn: node)
Setup:
db().saveContext('ctx').end()
Code:
db().deleteSavedContext('ctx').end(function(){ console.log('ok'); })
Output:
ok
example-deleteSavedContext-cover2 pass (runnableIn: node)
Setup:
db().saveContext('deleteSavedContext_ctx').end()
Code:
db().deleteSavedContext('deleteSavedContext_ctx').end(function(){ console.log('ok'); })
Output:
ok

peek method

db().peek()
module: ttv-core

Restore the last pushed result set from the stack without removing it from the stack.

See also

pop · push · stack · save · restore · saveContext · restoreContext · saveSession · restoreSession

Examples

example-peek-ex1 skipped (runnableIn: reference)
Code:
See example for push.
example-peek-cover pass (runnableIn: node)
Code:
db().setValues([1]).push().setValues([2]).peek().end(function(arr){ console.log(arr); })
Output:
[1]
example-peek-cover2 pass (runnableIn: node)
Code:
db().setValues([1]).push().setValues([2]).peek().end(function(arr){ console.log(arr); })
Output:
[1]

pop method

db().pop()
module: ttv-core

Restore a previously saved session and result set.

Parameters

NameTypeRequiredDescription
index string|number ✓ The index of the desired session and result set previously saved with the
save method.
del boolean Optional. True to remove the saved context and session from the store after it
has been restored.

See also

save · saveSession · restoreSession · push · pop · peek · stack · saveContext · restoreContext

Examples

example-pop-ex1 skipped (runnableIn: reference)
Code:
See example for save.
example-pop-cover pass (runnableIn: node)
Code:
db().setValues([1]).push().setValues([2]).pop().end(function(arr){ console.log(arr); })
Output:
[1]
example-pop-cover2 pass (runnableIn: node)
Code:
db().setValues([1]).push().setValues([2]).pop().end(function(arr){ console.log(arr); })
Output:
[1]

push method

db().push()
module: ttv-core

Push the current result set onto the result set stack.

See also

pop · peek · stack · saveContext · restoreContext · saveSession · restoreSession

Examples

example-push-ex1 skipped (runnableIn: browser)
Code:
db(['3','1','2'])
.push()
.sort()
.push()
.reverse()
.push()
.stack(function(s) { alert(s); })
.pop().log()
.pop().log()
.peek().log()
.stack(function(s) { alert(s); })
.end()
Output:
[ [ '3', '1', '2' ],
  [ '1', '2', '3' ],
  [ '3', '2', '1' ] ]
[
  "3",
  "2",
  "1"
]
[
  "1",
  "2",
  "3"
]
[
  "3",
  "1",
  "2"
]
[ [ '3', '1', '2' ] ]
example-push-cover pass (runnableIn: node)
Code:
db().setValues([1,2]).push().setValues([3]).pop().end(function(arr){ console.log(arr); })
Output:
[1,2]
example-push-cover2 pass (runnableIn: node)
Code:
db().setValues([1]).push().setValues([2]).pop().end(function(arr){ console.log(arr); })
Output:
[1]

restoreContext method

db().restoreContext(index, del)
module: ttv-core

Restore a previously saved result set.

Parameters

NameTypeRequiredDescription
index string|number ✓ The identifier of the desired result set previously saved with the
saveContext method.
del boolean Optional. True to remove the saved context from the saved context store after it
has been restored.

See also

saveContext · push · pop · peek · stack · save · restore · saveSession · restoreSession

Examples

example-restoreContext-ex1 skipped (runnableIn: reference)
Code:
See example for saveContext.
example-restoreContext-cover pass (runnableIn: node)
Setup:
db().addTopics('alice','x','1').topicByName('alice').saveContext(1).end()
Code:
db().restoreContext(1).end(function(rs){ console.log(rs.map(function(t){return t.text;})); })
Output:
["alice"]
example-restoreContext-cover2 pass (runnableIn: node)
Setup:
db().saveContext('restoreContext_ctx').end()
Code:
db().restoreContext('restoreContext_ctx').end(function(){ console.log('ok'); })
Output:
ok

restoreSession method

db().restoreSession(index, del)
module: ttv-core

Restore a previously saved session.

Parameters

NameTypeRequiredDescription
index string|number ✓ The index of the desired session previously saved with the
saveSession method.
del boolean Optional. True to remove the saved context from the saved context store after it
has been restored.

See also

saveSession · push · pop · peek · stack · save · restore · saveContext · restoreContext

Examples

example-restoreSession-ex1 skipped (runnableIn: reference)
Code:
See example for saveSession.
example-restoreSession-cover pass (runnableIn: node)
Setup:
db().saveSession('s').end()
Code:
db().restoreSession('s').end(function(){ console.log('ok'); })
Output:
ok
example-restoreSession-cover2 pass (runnableIn: node)
Setup:
db().saveSession('restoreSession_s').end()
Code:
db().restoreSession('restoreSession_s').end(function(){ console.log('ok'); })
Output:
ok

save method

db().save(index)
module: ttv-core

Save session information and the current result set for later restoration.

This method is the equivalent of executing saveContext() and
saveSession() with the same index argument.

Parameters

NameTypeRequiredDescription
index string|number ✓ The identifier by which the saved information can be retrieved using
the restore() method.

See also

restore · saveSession · saveContext · session

Examples

example-save-ex1 pass (runnableIn: node)
Code:
db()
.login('<appname>', '<username>', '<password>')
.save('userObject')
.topicByName('bogusTopicName')
.log()
// Result set is now empty
.restore('userObject')
// Display the user's login count
.tag('./loginCount')
.values().text()
.log()
.end()
example-save-cover pass (runnableIn: node)
Code:
db().setValues([1,2]).save('x').setValues([3]).restore('x').end(function(arr){ console.log(arr); })
Output:
[1,2]
example-save-cover2 pass (runnableIn: node)
Code:
db().setValues([1,2]).save('save_x').setValues([3]).restore('save_x').end(function(arr){ console.log(arr); })
Output:
[1,2]

saveContext method

db().saveContext(index)
module: ttv-core

Save the current result set so that it can be restored in a later step.

This step passes the input result set unchanged to the following query sequence step.

Parameters

NameTypeRequiredDescription
index string|number ✓ The identifier by which the saved result set can be retrieved using
the restoreContext() method.

See also

restoreContext · deleteSavedContext · save · restore · push · pop · peek · stack · saveSession · restoreSession

Examples

example-saveContext-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.saveContext(1)
.text()
.log()
.restoreContext(1)
.last()
.values()
.first()
.text()
.log()
.restoreContext(1)
.text()
.log()
.end();
Output:
[
  "friends",
  "coworkers"
]
[
  "Frank"
]
[
  "friends",
  "coworkers"
]
example-saveContext-cover pass (runnableIn: node)
Code:
db().saveContext('ctx').end(function(){ console.log('ok'); })
Output:
ok
example-saveContext-cover2 pass (runnableIn: node)
Code:
db().saveContext('saveContext_ctx').end(function(){ console.log('ok'); })
Output:
ok

saveSession method

db().saveSession(index)
module: ttv-core

Save session information for later restoration.

Session information includes the session identifier, the server URL, the application name,
the current username, and the contents of the in-memory client-side cache. (The session identifier
is assigned by the server after user authentication (i.e. a successful login.)

Note that this method does not save the current result set with the session information. If you wish to
save both, use save() instead.

Only a single session may be active at any time. You might want to change sessions dynamically
if you were, for example, copying information from one application to another or if you were copying
information from one user to another within an application.

Parameters

NameTypeRequiredDescription
index string|number ✓ The identifier by which the saved session can be retrieved using
the restoreSession() method.

See also

restoreSession · save · restore · saveContext · restoreContext · push · pop · peek · stack

Examples

example-saveSession-ex1 pass (runnableIn: node)
Code:
var firstId;
db()
.session(function(sess) { firstId = sess.sessionId; })
.saveSession(1)
.restoreSession(1)
.session(function(sess) {
    alert('restored the same session: ' + (sess.sessionId === firstId));
})
.end();
Output:
restored the same session: true
example-saveSession-cover pass (runnableIn: node)
Code:
db().saveSession('s').end(function(){ console.log('ok'); })
Output:
ok
example-saveSession-cover2 pass (runnableIn: node)
Code:
db().saveSession('saveSession_s').end(function(){ console.log('ok'); })
Output:
ok

stack method

db().stack(func)
module: ttv-core

Invoke a user-supplied function passing the current stack array as its single argument.

The array passed to the supplied function is not a copy of the stack, but the stack array itself. Thus
any changes made to it within the invoked function will persist after the function returns.

See also

pop · push · peek · save · restore · saveContext · restoreContext · saveSession · restoreSession

Examples

example-stack-ex1 skipped (runnableIn: reference)
Code:
See example for push.
example-stack-cover pass (runnableIn: node)
Code:
db().setValues([1]).push().stack(function(s){ console.log(s.length); }).end()
Output:
1
example-stack-cover2 pass (runnableIn: node)
Code:
db().setValues([1]).push().stack(function(s){ console.log(s.length); }).end()
Output:
1

Sessions

session method

db().session(func)
module: ttv-core

Invoke a user-supplied function that is passed a session information object.

The members of the returned object are

- sessionId - the session identifier assigned on login by the server

- url - the URL of the server. Normally https://www.screwtopdb.com

- appId - the application ID of the application

- appName - the application name

- username - the username of the currently logged-in user

If a login has not been performed, the session information object passed is undefined.

Parameters

NameTypeRequiredDescription
func function(sessionObj) ✓ The function to be invoked with the session information object.

Examples

example-session-ex1 pass (runnableIn: node)
Code:
db()
.session(function(sess) {
    // Under basic authentication sessionId is null; login() sets it.
    alert('session user: ' + sess.username);
})
.end();
Output:
session user: u
example-session-cover pass (runnableIn: node)
Code:
db().session(function(s){ console.log(typeof s); }).end()
Output:
object
example-session-cover2 pass (runnableIn: node)
Code:
db().session(function(s){ console.log(typeof s); }).end()
Output:
object

Cache

addTopicsLocal method

db().addTopicsLocal(topicText, tagText, valueText, options)
module: ttv-core

Add a topic to the local cache without "writing through" to the server.

Normally, unless offline, added topics are transmitted to the server and
the server response is used to update the cache, including the server-assigned
topic, tag, and value IDs. This method does not update the server, thus behaving
as if the client was offline.

Parameters

NameTypeRequiredDescription
topicText string ✓ The topic text
tagText string ✓ The tag text
valueText string ✓ The value text
Optional. object ✓ An options object

See also

addTopics · deleteTopicsLocal · deleteValuesLocal

Examples

example-addTopicsLocal-cover pass (runnableIn: node)
Code:
db().addTopicsLocal('LocalT','x','1').end(function(){ console.log('ok'); })
Output:
ok
example-addTopicsLocal-cover2 pass (runnableIn: node)
Code:
db().addTopicsLocal('addTopicsLocal_t','tag1','val1').end(function(){ console.log('ok'); })
Output:
ok

deleteTopicsLocal method

db().deleteTopicsLocal()
module: ttv-core

Delete topics in the current result set from the local cache without "writing through" to the server.

Normally, unless offline, topic deletions are transmitted to the server and
the server response is used to update the cache. This method does not update
the server, thus behaving as if the client was offline.

See also

deleteTopics · addTopicsLocal · deleteValuesLocal

Examples

example-deleteTopicsLocal-cover pass (runnableIn: node)
Code:
db().addTopicsLocal('LocalT','x','1')
   .topicByName('LocalT',{fromcache:true})
   .deleteTopicsLocal()
   .end(function(){ console.log('ok'); })
Output:
ok
example-deleteTopicsLocal-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().deleteTopicsLocal);
Output:
function

deleteValuesLocal method

db().deleteValuesLocal(valIds)
module: ttv-core

Delete values in the current result set from the local cache without "writing through" to the server.

Normally, unless offline, value deletions are transmitted to the server and
the server response is used to update the cache. This method does not update
the server, thus behaving as if the client was offline.

See also

deleteValues · addTopicsLocal · deleteTopicsLocal

Examples

example-deleteValuesLocal-cover pass (runnableIn: node)
Setup:
db().addTopicsLocal('LocalT','x','1').end()
Code:
db().topicByName('LocalT').tagValues('x').deleteValuesLocal().end(function(){ console.log('ok'); })
Output:
ok
example-deleteValuesLocal-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().deleteValuesLocal);
Output:
function

enableCache method

db().enableCache(torf)

Enable or disable caching of topics

By default, the ScrewtopDB Javascript library caches retrieved topics and thereafter if the same topic
is referenced again, it is retrieved from cache rather than requiring that another request
be sent to the server.

This function allows you to disable the caching feature. This might be desirable if, for example, you
are accessing a highly interactive application where ScrewtopDB topics are used to communicate between
multiple on-line clients.

See also

invalidateCache · cacheStats

Examples

example-enableCache-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
// Disable the local cache: every read goes to the server.
.enableCache(false)
.topicByName('persons')
.fn(function(ts) { console.log('fetched: ' + ts[0].text); })
.enableCache(true)
.end();
Output:
fetched: persons
example-enableCache-cover pass (runnableIn: node)
Code:
db().enableCache(true).enableCache(false).end(function(){ console.log('ok'); })
Output:
ok
example-enableCache-cover2 pass (runnableIn: node)
Code:
db().enableCache(true).enableCache(false).end(function(){ console.log('ok'); })
Output:
ok

invalidateCache method

db().invalidateCache(idOrName)

Remove all entries from the local topic cache.

The ScrewtopDB Javascript library caches retrieved topics and thereafter if the same topic
is referenced again, it is retrieved from cache rather than requiring that another request
be sent to the server.

InvalidateCache is used when you want to be sure that you are using the server's copy of a
topic. This might be necessary if, for example, there are multiple clients accessing the
same topic simultaneously.

Parameters

NameTypeRequiredDescription
idOrName number | string Optional. The ID or name (topicText) of the cache element to remove.
If this parameter is not present, all cached topics are removed.

See also

enableCache · cacheStats

Examples

example-invalidateCache-ex1 pass (runnableIn: node)
Code:
// Invalidate the cache to ensure that a server request is produced by the
// topicByName function.
db()
.appName('<appname>')
.invalidateCache()
.topicByName('user:<username>')
.lastRequestTime(function(ms) {
    alert("Topic retrieval took " + ms + " ms on the server.");
})
.end();
example-invalidateCache-cover pass (runnableIn: node)
Code:
db().invalidateCache().end(function(){ console.log('ok'); })
Output:
ok
example-invalidateCache-cover2 pass (runnableIn: node)
Code:
db().invalidateCache().end(function(){ console.log('ok'); })
Output:
ok

localCacheData method

db().localCacheData(func)

Call the provided function passing the current contents of the local in-memory cache.

This method is intended for debugging of the ScrewtopDb library and is not likely to
be generally useful. The web page ScrewtopDb Cache Demo
uses this method to display cache content changes in real time.

Parameters

NameTypeRequiredDescription
The function ✓ function to be invoked. The single argument passed is the local cache
content.

See also

localStorageData

Examples

example-localCacheData-ex1 pass (runnableIn: node)
Code:
db()
.appName('<appname>')
.topicByName('user:<username>')
.localCacheData(function(cache) {
    db()
    .log(JSON.stringify(cache, null, ' ')
    .end();
}
.end();
example-localCacheData-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().localCacheData);
Output:
function

localStorageData method

db().localStorageData(func, cacheName)

Call the provided function passing the current contents of the browser's local storage cache.

This method is intended for debugging of the ScrewtopDb library and is not likely to
be generally useful. The web page ScrewtopDb Cache Demo
uses this method to display cache content changes in real time.

Parameters

NameTypeRequiredDescription
cacheName string Optional. The named cache to read. Defaults to the primary cache.
func function ✓ Callback invoked with the local-storage cache data object.

See also

localCacheData

Examples

example-localStorageData-ex1 pass (runnableIn: node)
Code:
db()
.appName('<appname>')
.topicByName('user:<username>')
.localStorageData(function(cache) {
    db()
    .log(JSON.stringify(cache, null, ' ')
    .end();
}
.end();
example-localStorageData-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().localStorageData);
Output:
function

Disconnected

deferredWrite method

db().deferredWrite(torf)
module: ttv-core

Set the deferredWrite state or passes the current deferredWrite state to a function.

When deferredeWrite is **true** all ScrewtopDb write requests will update the local cache only; no
server communication will be attempted. Later invocation of the synchronize method
will update the server with the new and changed content of the local cache. Use of deferredWrite and
synchroinize allow disconnected operation of ScrewtoDb applications.

Parameters

NameTypeRequiredDescription
torf boolean|function ✓ If this parameter is a boolean, the deferredWrite state is set to the
value of the parameter. If the parameter is a function the function is called with a single argument
is the current deferredWrite value.

See also

offline · synchronize · loadCacheFromLocalStorage · saveCacheToLocalStorage

Examples

example-deferredWrite-ex1 skipped (runnableIn: browser)
Code:
db()
.deferredWrite(true)
.deferredWrite(function(offlineState) {
    if (offlineState != true) alert('DeferredWrite state was not set.');
})
.deferredWrite(false)
.end();
example-deferredWrite-cover pass (runnableIn: node)
Code:
db().deferredWrite(true).deferredWrite(false).end(function(){ console.log('ok'); })
Output:
ok
example-deferredWrite-cover2 pass (runnableIn: node)
Code:
db().deferredWrite(true).deferredWrite(false).end(function(){ console.log('ok'); })
Output:
ok

deleteCacheFromLocalStorage method

db().deleteCacheFromLocalStorage(cacheName)

Delete a previously saved cache from the browser's local storage.

The in-memory cache is unaffected by this operation.

Parameters

NameTypeRequiredDescription
cacheName string ✓ The name under which the cache was previously stored in the browser's LocalStorage.

See also

deferredWrite · synchronize · saveCacheToLocalStorage

Examples

example-deleteCacheFromLocalStorage-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().deleteCacheFromLocalStorage);
Output:
function

loadCacheFromLocalStorage method

db().loadCacheFromLocalStorage(cacheName)

Restore a previously saved cache from the browser's local storage.

The cache is restored to the state it was in when it was saved. This is useful, for example, when
continuing a session across browser restarts when the user has been working off-line and was not
able to synchronize with the server database.

Parameters

NameTypeRequiredDescription
cacheName string ✓ The name under which the cache was previously stored in the browser's LocalStorage.

See also

deferredWrite · synchronize · saveCacheToLocalStorage

Examples

example-loadCacheFromLocalStorage-cover pass (runnableIn: node)
Code:
console.log(typeof db().loadCacheFromLocalStorage);
Output:
function

offline method

db().offline(torf)
module: ttv-core

Set the off-line state or passes the current off-line state to a function.

An off-line state of **true** affects only the login
method and then only when deferredWrite is also true. When both are true, the login method
does not attempt to communicate with the server to authenticate the user, but instead assumes
login success and continues. This is done to allow applications that perform a login to operate
when not connected to the Internet.

Parameters

NameTypeRequiredDescription
torf boolean|function ✓ If this parameter is a boolean, the offline state is set to the
value of the parameter. If the parameter is a function the function is called with a single argument
is the current off-line value.

See also

deferredWrite

Examples

example-offline-ex1 skipped (runnableIn: browser)
Code:
db()
.offline(true)
.offline(function(offlineState) {
    if (offlineState != true) alert('Offline state was not set.');
})
.offline(false)
.end();
example-offline-cover pass (runnableIn: node)
Code:
db().offline(false).end(function(){ console.log('ok'); })
Output:
ok
example-offline-cover2 pass (runnableIn: node)
Code:
db().offline(false).end(function(){ console.log('ok'); })
Output:
ok

saveCacheToLocalStorage method

db().saveCacheToLocalStorage(cacheName)

Save the ScrewtopDb cache in the browser's local storage.

This is useful, for example, when the user is working off-line and was not able to
synchronize with the server database.

Parameters

NameTypeRequiredDescription
cacheName string ✓ The name under which the cache was previously stored in the browser's LocalStorage.

See also

deferredWrite · synchronize · loadCacheFromLocalStorage

Examples

example-saveCacheToLocalStorage-cover pass (runnableIn: node)
Code:
console.log(typeof db().saveCacheToLocalStorage);
Output:
function

synchronize method

db().synchronize(onlyIfChanged, func)

Synchronize the local in-memory cache with the server database.

During synchronization, differences between the server database content and the current in-memory cache
contents are resolved. Additions, modifications and deletions are propagated between the the two. If
a conflict arises, it is resolved by honoring the change with the later timestamp.

Synchronize is most useful when used in conjunction with deferredWrite(true).

Parameters

NameTypeRequiredDescription
onlyIfChanged boolean Optional. If true, synchronization is performed only if changes have
been made to the local cache. If false or not present, synchronization is performed unconditionally.

Set this parameter to true when it is unlikely that any changes have been made by others to the server
database and therefore synchronization is only required when local changes have been made. Set this
parameter to true to pick up any changes to topics in the local cache that have occurred in the server
database since the last synchronization.
func function Callback invoked when synchronization completes.

See also

deferredWrite · loadCacheFromLocalStorage · saveCacheToLocalStorage

Examples

example-synchronize-ex1 pass (runnableIn: node)
Code:
db()
.deferredWrite(true)
.addTopics('albert', 'phone number', '555-1212')
.synchronize(false, function(arr) {
    alert('synchronized');
})
.deferredWrite(false)
.topicByName('albert')
.tagValues('phone number')
.text()
.log()
.end();
Output:
synchronized
[
  "555-1212"
]
example-synchronize-cover pass (runnableIn: node)
Code:
console.log(typeof db().synchronize);
Output:
function

DOM

autoRenderer method

db().autoRenderer(cb, errcb)

Creates a real-time auto-rendering system for a topic. Returns the chain instance with two new methods attached:
`subscribe` and `unsubscribe`.

An autoRenderer manages subscribing to server-sent notifications for a topic. When events occur
(additions, deletions, modifications, re-ordering of values), the autoRenderer updates the local cache
and re-populates the data. On connection errors, it automatically reconnects with retry logic.

**subscribe(notifyId, topicText, tagPrefix, renderOptions, eventFn, fetchOptions)**

Subscribes to real-time notifications for a topic. After subscribing, performs an initial fetch
of the topic data (invalidating the cache first). On subsequent events (`add`,
`delete`, `update`, `move`, `ts`), updates the local
cache and calls the `cb` callback. If the connection is lost, unsubscribes, waits 2 seconds,
and re-subscribes automatically. The optional `eventFn` is called with raw event data after
each event is processed. The `fetchOptions` parameter defaults to `{elide:true}`.

**unsubscribe(notifyId)**

Unsubscribes from notifications for the given `notifyId`.

Parameters

NameTypeRequiredDescription
cb function ✓ Optional. A callback invoked after every data update (passed to .end() of internal chains).
errcb function ✓ Optional. A callback invoked whenever the connection to the server is lost. The cb function
is called when the connection is restored.
notifyId string ✓ The notification channel ID to subscribe to.
topicText string ✓ The topic name to watch for changes.
tagPrefix string ✓ Tag prefix used via renderOptions.
renderOptions object ✓ Options passed to populate.
eventFn function ✓ Optional. Called with raw event data after each notification event is processed.
fetchOptions object ✓ Optional. Options passed to topicByName. Defaults to {elide:true}.

See also

populate

Examples

example-autoRenderer-ex1 skipped (runnableIn: browser)
Code:
var ar = db().autoRenderer(function() {
    console.log('notification processed');
}, function() {
    console.log('connection lost');
});

ar.subscribe('myNotifyId', 'myTopic', '', {}, function(eventData) {
    console.log('event:', eventData);
});

// Later, to unsubscribe:
ar.unsubscribe('myNotifyId');
example-autoRenderer-cover pass (runnableIn: node)
Code:
console.log(typeof db().autoRenderer);
Output:
function

populate method

db().populate(topicName, prefix, options)
module: ttv-browser-ui availableIn: v1, v2 runnableIn: browser returns: this (chain)

Populate DOM objects from a ScrewtopDb topic using jQuery's html() and val() functions.

The text of the topic's tags specify the DOM element IDs. The tag values contain the text to be
inserted using the html() or val() function. DOM element IDs are assumed to be prefixed with the topic
name followed by a dash. Here is an example ID: myform-newpassword. The topic is myform and the
tag might be <username>/newpassword.

The ScrewtopDB Application Dashboard is populated using this method.

Parameters

NameTypeRequiredDescription
topicName string ✓ The topic that contains the information to be used to populate the
DOM elements
prefix string ✓ The tag prefix. This is generally the tag owner but may include additional
fields as well. Use of the prefix ensures that tags with similar names created by other users do not
interfere with the population of DOM elements.
topicName string ✓ Topic name to populate the DOM from.
prefix string ✓ CSS selector / id prefix used to locate the target DOM nodes.
options object Render options (see autoRenderer for the shared shape).

See also

autoRenderer · subscribe · unsubscribe

Examples

example-populate-ex1 pass (runnableIn: node)
Code:
<!doctype html>
<html>
<head>
<title>ScrewtopDb Populate method Demo</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript" src="/js/ttv.node.js"></script>
<script type="text/javascript">

    // Insert the topic that will be used to populate the page. (Normally
    // this would not be done here, but instead perhaps using the ScrewtopDb
    // topic browser to insert the information.)
    function prepareDb() {
        screwtopDb()
        .login('<appname>', '<username>', '<password>')
        .putTopic(screwtopDb.objToDb({
            text: 'demo',
            intro: 'ScrewtopDb populate()',
            detail: 'The populate() screwtopDb method is used to insert text from the '
                + 'screwtopDb database into a web page.'
                + '<p/>'
                + 'This allows the textual content of the web page to be separated from '
                + 'the structure of the page so content can be changed without modifying '
                + 'the HTML and changes to the structure can be made without disturbing '
                + 'the content.',
            button: 'Clean up'
        }))
        .end();
    }

    // Populate the page and show it. (This is the only function that would
    // normally be needed in a non-demo page.)
    function populatePage() {
        screwtopDb()
        .populate('demo', '<username>')
        .end(function() {
            $('body').show();
        });
    }

    // Remove the topic we created from the database and
    // clear the page. (This step would normally not be needed as the
    // topic would not need to be deleted.)
    function cleanup() {
        screwtopDb()
        .topicByName('demo')
        .deleteTopics()
        .end(function() {
            $('body').hide().children().remove();
        });
    }

    $(function () {
        $('#demo-button').click(cleanup);

        // Let's do it.
        screwtopDb()
        .func(prepareDb)
        .func(populatePage)
        .end();
    });

</script>
</head>
<body style="margin:40px; padding:20px; background-color:lightgray; display:none;">
    <h2 id="demo-intro"></h2>
    <div id="demo-detail" style="width:400px;"></div>
    <button id="demo-button" style="margin-top: 20px;"/>
</body>
</html>
example-populate-cover pass (runnableIn: node)
Code:
console.log(typeof db().populate);
Output:
function
example-populate-basic stale (runnableIn: browser)
Setup:
<!-- HTML: <div id='alice-city'></div> -->
db().addTopics('Alice', 'city', 'Berkeley').end()
Code:
db().populate('Alice', 'alice-').end()
Output:
<div id='alice-city'>Berkeley</div>

subscribe method

db().autoRenderer(cb).subscribe(notifyId, topicText, tagPrefix, renderOptions, eventFn, fetchOptions)

Open a server-sent-events connection and re-render a topic into the DOM whenever the server broadcasts a change.
**subscribe** and unsubscribe are attached to a chain instance by
autoRenderer — they are not standalone chain steps. Browser-only (depends on
`EventSource`).

Parameters

NameTypeRequiredDescription
notifyId string ✓ SSE channel identifier. Must match the id used by any notify call that should trigger this subscriber.
topicText string ✓ The name of the topic to subscribe to and render.
tagPrefix string ✓ Regex prefix for tag names to include. Pass ".*" to include everything.
renderOptions object Optional. Pipe functions for custom rendering, keyed by the |name suffix on the data-db attribute.
eventFn function Optional. Invoked with the raw SSE actions object after every event.
fetchOptions object Optional. Options object forwarded to the internal topicByName call that performs the initial fetch. Defaults to {elide:true}.

See also

autoRenderer · unsubscribe · populate · notify

Examples

example-subscribe-cover pass (runnableIn: node)
Code:
console.log(typeof db().autoRenderer(function(){}).subscribe);
Output:
function
example-subscribe-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().subscribe);
Output:
undefined

unsubscribe method

db().autoRenderer(cb).unsubscribe()

Close the SSE connection opened by an earlier subscribe call. Like subscribe, this is
attached by autoRenderer.

Examples

example-unsubscribe-cover pass (runnableIn: node)
Code:
console.log(typeof db().autoRenderer(function(){}).unsubscribe);
Output:
function
example-unsubscribe-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().unsubscribe);
Output:
undefined

Errors

onError method

db().onError(func)
module: ttv-core

Invoke a specified function when an error occurs.

By default errors are logged and query sequence execution is terminated when an error occurs. This function allows you to
specify additional actions to be executed when an error occurs.

Parameters

NameTypeRequiredDescription
func function(errObj) The function to invoke on error. Receives the error object; return true to stop the sequence, false to continue. Omit to remove the current handler.

See also

throwErrors · logErrors · terminateOnError · abort

Examples

example-onError-ex1 skipped (runnableIn: browser)
Code:
// Handle the unrecognized application error.
  function errorHandler(errorText) {
      alert(errorText);
      return true;
  }

  db()
 .appName('bogus-appname')
 .onError(errorHandler)
 .topicByName('bogus-topic')
 .log("This text will not be displayed.")
 .end();
Output:
// Example error object:
  { result: 'Unrecognized application' }
example-onError-cover pass (runnableIn: node)
Code:
db().onError(function(){}).end(function(){ console.log('ok'); })
Output:
ok
example-onError-cover2 pass (runnableIn: node)
Code:
db().onError(function(){}).end(function(){ console.log('ok'); })
Output:
ok

terminateOnError method

db().terminateOnError(torf)
module: ttv-core

Disable or enable query sequence termination when an error occurs.

By default query sequence execution is terminated when an error occurs. This function allows you to
allow termination to continue after an error.

This function is most useful during testing.

Parameters

NameTypeRequiredDescription
torf boolean Optional. False to continue execution after an error. Default is true.

See also

throwErrors · logErrors · onError · abort

Examples

example-terminateOnError-ex1 pass (runnableIn: node)
Code:
// Continue after the unrecognized application error.
  db()
 .appName('bogus-appname')
 .terminateOnError(false)
 .topicByName('bogus-topic')
 .log("Continuing after error.")
 .terminateOnError()
 .end();
example-terminateOnError-cover pass (runnableIn: node)
Code:
db().terminateOnError(false).end(function(){ console.log('ok'); })
Output:
ok

throwErrors method

db().throwErrors(torf)
module: ttv-core

Throw an exception when an error occurs.

By default errors are logged. This function allows you to cause errors to throw exceptions.

**Note:** You cannot catch exceptions thrown by ScrewtopDb query sequences by enclosing the sequence
in a try block because the query is not actually executed until after the try-catch block has been
exited. This means that error exceptions will always cause termination of the script. In almost all
cases, the onError function is a better choice.

Parameters

NameTypeRequiredDescription
torf boolean Optional. False to disable throwing error exceptions. Default is true.

See also

logErrors · terminateOnError · onError · abort

Examples

example-throwErrors-ex1 pass (runnableIn: node)
Code:
// Throw the unrecognized application error normally logged when no app has been specified.
  db()
 .appName('bogus-appname')
 .throwErrors()
 .topicByName('bogus-topic')
 .throwErrors(false)
 .end();
example-throwErrors-cover pass (runnableIn: node)
Code:
db().throwErrors(false).end(function(){ console.log('ok'); })
Output:
ok
example-throwErrors-cover2 pass (runnableIn: node)
Code:
db().throwErrors(false).end(function(){ console.log('ok'); })
Output:
ok

try method

try(opFn, [onSuccess], [onFailure])
module: ttv-core availableIn: v1, v2 returns: this (chain)

Run an operation as an isolated sub-chain, capture whether it produced an error, then run exactly one branch — onSuccess or onFailure — before continuing the enclosing chain. A failure inside the operation is captured: it does NOT invoke the module-level onError handler and does NOT terminate the enclosing chain. onFailure receives the captured error object as its second argument.

Each branch callback receives a fresh chain to build on and must NOT call .end() — try() owns the sub-chain lifecycle. The operation fragment is seeded with the enclosing result set so opFn can read its inbound context, but try() is a control-flow bracket: the enclosing result set passes through UNCHANGED to the steps after .try(), and onSuccess cannot see what the operation produced. If you need the operation’s output downstream, use a plain chain with explicit error handling instead.

Parameters

NameTypeRequiredDescription
opFn function ✓ The operation, run as an isolated sub-chain. Receives a fresh chain seeded with the enclosing result set; must NOT call .end().
onSuccess function Run (with a fresh chain) when the operation completes without error.
onFailure function Run when the operation fails; receives (freshChain, capturedError).

See also

onError · terminateOnError · throwErrors

Examples

example-try-basic pass (runnableIn: node)
Code:
// .try() runs the operation in isolation; a failure routes to
// onFailure without aborting the enclosing chain.
db().try(
    function(op){ op.addTopics('Widget','price','9.99'); },
    function(ok){ ok.log('add succeeded'); },
    function(fail, err){ fail.log('add failed: ' + err); }
).topicByName('Widget').values().text()
 .end(function(vals){ console.log(vals); })
Output:
["9.99"]

Logging

log method

db().log(text)
module: ttv-core

Output the current result set or a text string.

In the Node.js environment, output is directed by default to the console. In the browser
environment, output is displayed by default in an alert box. The output destination may be
changed using the logFunc method.

This step passes the current result set unchanged to the following step.

Parameters

NameTypeRequiredDescription
text string Optional. Text to be output. If this parameter is not present, a formatted
representation of the current result set is output.

See also

logText · trace · logRequests · logResponses

Examples

example-log-ex1 skipped (runnableIn: reference)
Code:
db()
.log('Test')
.end()
Output:
Test
example-log-cover pass (runnableIn: node)
Code:
db().fn(function(){ console.log('Test'); }).end()
Output:
Test
example-log-cover2 pass (runnableIn: node)
Code:
db().fn(function(){ console.log('Test'); }).end()
Output:
Test

logErrors method

db().logErrors(torf)
module: ttv-core

Suppress or enable logging of errors.

By default errors are logged. This function allows you to cause errors not to be displayed in any way.
This function is most useful during testing.

Parameters

NameTypeRequiredDescription
torf boolean Optional. False to disable logging of errors. Default is true.

See also

throwErrors · terminateOnError · onError · abort

Examples

example-logErrors-ex1 pass (runnableIn: node)
Code:
// Suppress the error normally logged an unrecognized application has been specified.
  db()
 .appName('bogus-appname')
 .logErrors(false)
 .topicByName('bogus-topic')
 .logErrors(true)
 .end();
example-logErrors-cover pass (runnableIn: node)
Code:
db().logErrors(false).logErrors(true).end(function(){ console.log('ok'); })
Output:
ok
example-logErrors-cover2 pass (runnableIn: node)
Code:
db().logErrors(false).logErrors(true).end(function(){ console.log('ok'); })
Output:
ok

logFunc method

db().logFunc(func)
module: ttv-core

Replace the default logging function.

The default logging function displays an alert dialog when in the browser environment and logs to the console in the
Node.js environment. This function allows to replace the default logging function with one of your own.

Parameters

NameTypeRequiredDescription
func function A function that receives log output in place of the console.

See also

log

Examples

example-logFunc-ex1 pass (runnableIn: node)
Code:
// Log to a buffer.
  var logMessages = '';
  function myLogger(text) {
      logMessages += text + '\n\n';
  }

  db()
  .appName('<appname>')
  .logFunc(myLogger)
  .topicByName('user:<username>')
  .log('Retrieved topic:')
  .log() // This logs the retrieved topic
  .end(function() {
      // Show the messages.
      alert(logMessages);
   });
example-logFunc-cover pass (runnableIn: node)
Code:
db().logFunc(function(){}).end(function(){ console.log('ok'); })
Output:
ok

logRequests method

db().logRequests(torf)
module: ttv-core

Log HTTP requests to the server.

This function is only functional in the Node.js environment.

By default server requests and responses are not logged.

Outgoing requests are prefixed with "`-->`" to distinguish them from server responses.

Parameters

NameTypeRequiredDescription
torf boolean Optional. False to disable logging of server requests. Default is true.

See also

logResponses · log · trace

Examples

example-logRequests-ex1 pass (runnableIn: node)
Code:
db()
 .appName('<appname>')
 .logRequests()
 .topicByName('user:<username>')
 .logRequests(false)
 .end();
example-logRequests-cover pass (runnableIn: node)
Code:
db().logRequests(false).end(function(){ console.log('ok'); })
Output:
ok
example-logRequests-cover2 pass (runnableIn: node)
Code:
db().logRequests(false).end(function(){ console.log('ok'); })
Output:
ok

logRequestTimes method

db().logRequestTimes(torf)
module: ttv-core

Enable or disable console logging of HTTP request timing information.

When enabled, each log line includes a request number, timestamp, server time, total time,
cumulative time, HTTP method, and URL.

Parameters

NameTypeRequiredDescription
torf boolean ✓ True to enable logging of request times, false to disable. Defaults to true if not a boolean.

See also

logRequests · logResponses · saveRequestTimes · requestTimes

Examples

example-logRequestTimes-ex1 pass (runnableIn: node)
Code:
db()
.logRequestTimes(true)
.topicByName('myTopic')
.end();
example-logRequestTimes-real pass (runnableIn: node)
Code:
db().logRequestTimes(false).end(function(){ console.log('disabled'); })
Output:
disabled

logResponses method

db().logResponses(torf)
module: ttv-core

Log HTTP server responses.

This function is only functional in the Node.js environment.

By default server requests and responses are not logged.

Incoming requests are prefixed with "`<--`" to distinguish them from requests to the server.

Parameters

NameTypeRequiredDescription
torf boolean Optional. False to disable logging of server responses. Default is true.

See also

logRequests · log · trace

Examples

example-logResponses-ex1 pass (runnableIn: node)
Code:
db()
 .appName('<appname>')
 .logRequests()
 .logResponses()
 .topicByName('user:<username>')
 .logRequests(false)
 .logResponses(false)
 .end();
example-logResponses-cover pass (runnableIn: node)
Code:
db().logResponses(false).end(function(){ console.log('ok'); })
Output:
ok
example-logResponses-cover2 pass (runnableIn: node)
Code:
db().logResponses(false).end(function(){ console.log('ok'); })
Output:
ok

logText method

db().logText(strip)
module: ttv-core

Output the the text members of the current result set.

In the Node.js environment, output is directed by default to the console. In the browser
environment, output is displayed by default in an alert box. The output destination may be
changed using the logFunc method.

This step passes the current result set unchanged to the following step.

Parameters

NameTypeRequiredDescription
strip boolean Optional. True to strip UUIDs from the output text.

See also

log · trace · logRequests · logResponses

Examples

example-logText-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.tags()
.values()
.logText()
.end();
Output:
Andy
Mary
Bill
Frank
Wendy
example-logText-cover pass (runnableIn: node)
Code:
db().fn(function(){ console.log('hello'); }).end()
Output:
hello
example-logText-cover2 pass (runnableIn: node)
Code:
db().fn(function(){ console.log('hello'); }).end()
Output:
hello

trace method

db().trace(enable)
module: ttv-core

Enable or disable tracing of query sequence execution.

In the Node.js environment, output is directed by default to the console. In the browser
environment, output is displayed by default in an alert box. The output destination may be
changed using the logFunc method.

This method is intended to aid in debugging. In the browser environment, it is most useful
when combined with the output redirection using the logFunc method.
This step passes the current result set unchanged to the following step.

Parameters

NameTypeRequiredDescription
enable boolean ✓ True ot enable tracing, false to disable.

Examples

example-trace-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.trace(true)
.topicByName('persons')
.tags()
.values()
.logText()
.end();
Output:
Step 7: topicByName("persons")
Step 8: tags()
Step 9: values()
Step 10: logText()
Andy
Mary
Bill
Frank
Wendy
Step 11: end(function(){})
example-trace-cover pass (runnableIn: node)
Code:
db().trace(false).end(function(){ console.log('ok'); })
Output:
ok
example-trace-cover2 pass (runnableIn: node)
Code:
db().trace(false).end(function(){ console.log('ok'); })
Output:
ok

Performance

cacheStats method

db().cacheStats(func)
module: ttv-core

Log the ScrewtopDB cache statistics or pass them to the optionally-provided function.

The object passed to the function contains two integer members: hits and misses.

Parameters

NameTypeRequiredDescription
func function(statsObj) ✓ Optional. The function to be invoked. The return value of this function is ignored. If this function is not provided
or something other than a function is passed, the cache statistics are logged.

See also

invalidateCache · enableCache

Examples

example-cacheStats-ex1 pass (runnableIn: node)
Code:
// Fetch a topic twice and observe that the second fetch came from cache.
 db()
 .appName('<appname>')
 .invalidateCache()        // Make sure we actually fetch it
 .topicByName('user:<username>')
 .cacheStats(function(statsObj) {
     hits = statsObj.hits;
     misses = statsObj.misses;
 })
 .topicByName('user:<username>')
 .cacheStats(function(statsObj) {
     if (statsObj.hits > hits) alert('The cache is working.');
 })
 .end();
example-cacheStats-cover pass (runnableIn: node)
Code:
db().cacheStats(function(s){ console.log(typeof s); }).end()
Output:
object

clearRequestTimes method

db().clearRequestTimes()
module: ttv-core

Log request timings

Request timing is displayed in a single line and includes, for each server request

- requestNumber - The 1-based index of the request

- timestamp - The time the request was made

- serverTime - The time the server application code spent processing the request

- networkTime - The total time minus the server time.

- totalTime - The time the client spent waiting for the response from the server. This time
includes the time spent transmitting the request and receiving the response as well as the server time.

- request - The method (GET, PUT, POST, or DELETE) and the URL path of the request

Parameters

NameTypeRequiredDescription
torf boolean ✓ Optional. True to start logging request times, false to stop.
The default is true

See also

saveRequestTimes · requestTimes · clearRequestTimes

Examples

example-clearRequestTimes-ex1 skipped (runnableIn: reference)
Code:
See the example for saveRequestTimes.
Output:
Example request time log line:
2   2011-09-02T23:04:29Z    126/559/685 PUT https://www.screwtopdb.com/303/topics.json?&session=7bfa894f57ac6da8
example-clearRequestTimes-cover pass (runnableIn: node)
Code:
db().clearRequestTimes(); console.log('ok');
Output:
ok
example-clearRequestTimes-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().clearRequestTimes);
Output:
function

lastRequestTime method

db().lastRequestTime(func)
module: ttv-core

Invoke the provided function passing as its arguments statistics related to the time that was required to process
the last request.

All times are in milliseconds.

The time required to process a request includes

- Client preparation time - the time required to prepare the request in the client (generally negligable)

- Request transmission time - the time required to transfer the request over the network and dispatch it to the server code
that processes the request.

- Server processing time - the time required by the server to process the request and produce a response.

- Response transmission time - the time required to transfer the response to the client over the network and dispatch
it to the client code that processes the response.

In the example below, number one above is ignored and numbers two and four are combined into "Network transfer
time".

Note that often requests for data are served from the client-side cache, and when this happens, no server request is
issued. In this case the last saved times remain in place and the requestCount is not incremented.

Parameters

NameTypeRequiredDescription
func function ✓ Callback invoked with the timestamp (ms) of the most recent server request.

Examples

example-lastRequestTime-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'persons',friends:[{text:'Andy',gender:'male'},{text:'Mary',gender:'female',spouse:'Bill'},{text:'Bill',gender:'male',spouse:'Mary'}],coworkers:[{text:'Frank',gender:'male'},{text:'Wendy',gender:'female'}]}).end()
Code:
db()
.topicByName('persons')
.lastRequestTime(function(totalTime, serverTime) {
    alert('total time is a number: ' + (typeof totalTime === 'number'));
})
.end();
Output:
total time is a number: true
example-lastRequestTime-cover pass (runnableIn: node)
Code:
console.log(typeof db().lastRequestTime);
Output:
function
example-lastRequestTime-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().lastRequestTime);
Output:
function

requestTimes method

db().requestTimes(func)
module: ttv-core

Invoke a user-supplied function, passing it an array of saved request timing information.

See also

saveRequestTimes · clearRequestTimes · logRequestTimes

Examples

example-requestTimes-ex1 skipped (runnableIn: reference)
Code:
See the example for saveRequestTimes.
example-requestTimes-cover pass (runnableIn: node)
Code:
console.log(typeof db().requestTimes);
Output:
function
example-requestTimes-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().requestTimes);
Output:
function

saveRequestTimes method

db().saveRequestTimes(torf)
module: ttv-core

Save request timing information for later processing.

Request timing information saved includes, for each server request

- requestNumber - The 1-based index of the request

- timestamp - The time the request was made

- serverTime - The time the server application code spent processing the request

- totalTime - The time the client spent waiting for the response from the server. This time
includes the time spent transmitting the request and receiving the response as well as the server time.

- request - The method (GET, PUT, POST, or DELETE) and the URL path of the request

Parameters

NameTypeRequiredDescription
torf boolean ✓ Optional. True to enable saving request times, false to disable.
The default is true

See also

logRequestTimes · requestTimes · clearRequestTimes

Examples

example-saveRequestTimes-ex1 pass (runnableIn: node)
Code:
db()
.saveRequestTimes()
.addTopics('persons', 'friends', 'Ralph')
.requestTimes(function(times) {
    alert('captured requests: ' + (times.length > 0));
})
.saveRequestTimes(false)
.clearRequestTimes()
.end();
Output:
captured requests: true
example-saveRequestTimes-cover pass (runnableIn: node)
Code:
db().saveRequestTimes(false).end(function(){ console.log('ok'); })
Output:
ok
example-saveRequestTimes-cover2 pass (runnableIn: node)
Code:
db().saveRequestTimes(false).end(function(){ console.log('ok'); })
Output:
ok

Administration

allSymbols method

allSymbols([options])
module: ttv-core availableIn: v1, v2 returns: Array of symbol objects

Return the app's interned symbol registry — the global list of text symbols underlying every topic, tag and value. Each entry carries the symbol id, text, primary frame id (fid) and reference-count bookkeeping. This is an introspection/diagnostic tool (the topic browser's all-symbols view is built on it); most applications never need it.

Parameters

NameTypeRequiredDescription
options object Optional bag passed through to the server symbol dump.

See also

diagnose · findTopics

Examples

example-allSymbols-cover pass (runnableIn: node)
Setup:
db().addTopics('Alice', 'city', 'SF').end()
Code:
db().allSymbols().end(function(syms){ console.log(syms.length > 0); })
Output:
true

appInfo method

db().appInfo(options)
module: ttv-core

Fetch application information

the following information is returned. Items marked with + are only included if the requesting user
is the responsible user of the app.

- appId

- appName

- responsibleUserId

- responsibleUserName

- + application attribute names and values

- + for each app user, username, userId, admin flag, lastLogin, privileges

See also

putApp · deleteApp

Examples

example-appInfo-cover pass (runnableIn: node)
Code:
db().appInfo().end(function(info){ console.log(typeof info); })
Output:
object

attributes method

db().attributes(attrName,u)
module: ttv-core

Fetch all user attributes or a specific user attribute.

Attributes are name/value pairs that are saved on a per-user basis. Only the owning user (and the
app's responsible user) may access user attributes. For this reason attributes are useful for saving
such information as an email address and other personal information that should not be exposed to other
users but that may be needed to perform actions for the logged-in user.

ScrewtopDb creates and maintains the user attribute userTopicId which contains the identifier of
the user topic. This attribute may not be modified or deleted.

This method replaces the result set with the returned attribute objects.

Parameters

NameTypeRequiredDescription
attrName string Optional. The name of the attribute to fetch. If this parameter is not
supplied, all attributes are returned.
username string Optional. The user whose attributes are to be retrieved. Only a super-user can retrieve another
user's attributes.

Examples

example-attributes-ex1 pass (runnableIn: node)
Setup:
db().putAttributes([{name:'login count', value:'147'}]).end()
Code:
db()
.attributes(['login count'])
.each(function(attr) {
    alert('Login count: ' + attr.value);
})
.end();
Output:
Login count: 147
example-attributes-cover pass (runnableIn: node)
Setup:
db().putAttributes([{name:'greet',value:'hi'}]).end()
Code:
db().attributes(['greet']).end(function(a){ console.log(a[0].value); })
Output:
hi
example-attributes-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().attributes);
Output:
function

createUnauthenticatedUser method

db().createUnauthenticatedUser(appName, username, email)

Create an unauthenticated user.

Unauthenticated users may have an inactivity lifetime specified in the application
attribute UnauthentcatedUserInactiveLifetimeMin. If the application is not accessed
by the user within the inactive lifetime, the user's account and all contributed
data are automatically deleted.

If username is not provided, a random username is returned by the server.

The returned pseudo-topic contains the assigned username, if any, and the assigned
password for the new account.

This method is only available if application attributes related to it are
defined. Such attributes include UnauthenticatedAddTopic, UnauthenticatedAddTag, UnauthenticatedAddValue,
UnauthenticatedSync, UnauthenticatedVote, and UnauthenticatedUpdate. UnauthenticatedRead is not one of them: it governs reads, which need no unauthenticated user, and setting it to true does not enable this method.

Parameters

NameTypeRequiredDescription
appName string The application name. If not provided, the current application
is used.
username string The username desired.
email string Optional. The email address to be used for warnings of impending
account deletion due to inactivity.

Examples

example-createUnauthenticatedUser-ex1 skipped (runnableIn: reference)
Code:
db()
.createUnauthenticatedUser()
.each(function(t) {
    console.log('Has generated username: ' + (t.username[0].length > 0));
    console.log('Has generated password: ' + (t.password[0].length > 0));
})
.end()
Output:
Has generated username: true
Has generated password: true
example-createUnauthenticatedUser-cover pass (runnableIn: node)
Code:
console.log(typeof db().createUnauthenticatedUser);
Output:
function

createUser method

db().createUser(username, pswd, email, appName, loginUrl, admin)

Create a new ScrewtopDb application user.

Depending on the application options in effect, this method may

- only be invoked successfully by the app's responsible user,

- result in a confirmation email being sent to the specified email address, or

- none of the above.

Parameters

NameTypeRequiredDescription
username string ✓ The username desired.
pswd string ✓ The password to be associated with the username
email string Optional. The email address to be used for confirmation. This parameter
is required if email confirmation of new accounts is required by the application.
appName string Optional. The application name used in confirmation emails. The default is the
current application.
loginUrl string Optional. The URL to which the user is to be directed in the confirmation
email, if any.
admin boolean Optional. True to create an application administrator account. Administrators
may impersonate other application users and log in as the application itself. This parameter is ignored
unless the currently logged in user is the responsible user or an administrator.

Examples

example-createUser-ex1 skipped (runnableIn: reference)
Code:
See the example for saveSession.
example-createUser-cover pass (runnableIn: node)
Code:
console.log(typeof db().createUser);
Output:
function

createUser2 method

db().createUser2(user)
module: ttv-core

Create a new ScrewtopDb application user.

Depending on the application options in effect, this method may

- only be invoked successfully by the app's responsible user,

- result in a confirmation email being sent to the specified email address, or

- none of the above.

Parameters

NameTypeRequiredDescription
user object ✓ An object which contains the following members:

- username

- password

- email Required if email confirmation of new accounts is required by the application.

- loginUrl Optional. The URL to which the user is to be directed in the confirmation email, if any

- appName Optional. The application name used in confirmation emails. The default is the
current application.

- admin Optional. True to create an application administrator account. Administrators
may impersonate other application users and log in as the application itself. This parameter is ignored
unless the currently logged in user is the responsible user or an administrator.

- Other members which will become user attributes.

Examples

example-createUser2-cover pass (runnableIn: node)
Code:
console.log(typeof db().createUser2);
Output:
function

deleteApp method

db().deleteApp(appName)
module: ttv-core

Delete an entire application, along with all of its topics, tags, values, and users. May only be invoked by the
admin user or the app's responsible user. Irreversible — there is no undo.

See also

putApp

Examples

example-deleteApp-cover pass (runnableIn: node)
Code:
console.log(typeof db().deleteApp);
Output:
function

deleteAttributes method

db().deleteAttributes(arg,u)
module: ttv-core

Delete user attributes by name.

Attributes are name/value pairs that are saved on a per-user basis. Only the owning user (and the
app's responsible user) may access user attributes. For this reason attributes are useful for saving
such information as an email address and other personal information that should not be exposed to other
users but that may be needed to perform actions for the logged-in user.

ScrewtopDb creates and maintains the user attribute userTopicId which contains the identifier of
the user topic. This attribute may not be modified or deleted.

If this method is invoked without an argument, attributes in the current result set are deleted. See the
example for how this can be used to delete all attributes.

Parameters

NameTypeRequiredDescription
attrnames array|string Optional. The names of the attributes to be deleted. This may be an array
of strings or a comma-separated list of the names to be deleted.
username string Optional. The user whose attributes are to be deleted. Only a super-user can delete another
user's attributes.

See also

putAttributes · attributes

Examples

example-deleteAttributes-ex1 pass (runnableIn: node)
Code:
function mine(attrs) {
    return ['email','phone'].filter(function(n) {
        return attrs.some(function(a){ return a.name === n; });
    }).join(',');
}
db()
.putAttributes([{ name: 'email', value: '[email protected]' },
                { name: 'phone', value: '206 555-1212' }])
.attributes()
.fn(function(attrs) { console.log('after put: ' + mine(attrs)); })
.deleteAttributes(['email'])
.attributes()
.fn(function(attrs) { console.log('after delete: ' + mine(attrs)); })
.end();
Output:
after put: email,phone
after delete: phone
example-deleteAttributes-cover pass (runnableIn: node)
Setup:
db().putAttributes([{name:'k',value:'v'}]).end()
Code:
db().deleteAttributes(['k']).end(function(){ console.log('ok'); })
Output:
ok
example-deleteAttributes-cover2 pass (runnableIn: node)
Setup:
db().putAttributes({delAttr_deleteAttributes:'val'}).end()
Code:
db().deleteAttributes(['delAttr_deleteAttributes']).end(function(){ console.log('ok'); })
Output:
ok

deleteUser method

db().deleteUser(arg)

Delete a specified user from the current app.

A user may delete themselves and the app's responsible user may delete other users.

This action is irrevocable. The user's database objects will be deleted except where doing so
would necessitate deleting another user's database objects. This might occur, for example if the
user being deleted had created a topic to which another user had added a tag and value.

Parameters

NameTypeRequiredDescription
username string ✓ The username of the user to delete.

See also

createUser

Examples

example-deleteUser-ex1 skipped (runnableIn: reference)
Code:
See the example for saveSession.
example-deleteUser-cover pass (runnableIn: node)
Code:
console.log(typeof db().deleteUser);
Output:
function

diagnose method

db().diagnose()
module: ttv-core

Verify consistency of application data

Performs a consistency check of the app data and returns results. This
is intended for use by Screwtop only.

See also

putApp · deleteApp · appInfo

Examples

example-diagnose-cover pass (runnableIn: node)
Code:
db().diagnose(false).end(function(){ console.log('ok'); })
Output:
ok

putApp method

db().putApp(newData)
module: ttv-core

Create a new application

This method may only be executed by the ScrewtopDb administrator account and is thus
not available to normal users, even the responsible users of other apps. Visit
The ScrewtopDb Dashboard to create a
new app.

Parameters

NameTypeRequiredDescription
An object ✓ object containing the following members: appName, appDescription, responsibleUserName,
and responsibleUserPassword.

See also

deleteApp

Examples

example-putApp-cover pass (runnableIn: node)
Code:
console.log(typeof db().putApp);
Output:
function

putAttributes method

db().putAttributes(attrs, u)
module: ttv-core

Create or update user attributes

Attributes are name/value pairs that are saved on a per-user basis. Only the owning user (and the
app's responsible user) may access user attributes. For this reason attributes are useful for saving
such information as an email address and other personal information that should not be exposed to other
users but that may be needed to perform actions for the logged-in user.

ScrewtopDb creates and maintains the user attribute userTopicId which contains the identifier of
the user topic. This attribute may not be modified or deleted.

Parameters

NameTypeRequiredDescription
attrs object|array ✓ The attribute objects. Attribute objects have two members, name
and value whose values are strings.
username string Optional. The user whose attributes are to be affected. Only a super-user can update another
user's attributes.

See also

updateUser

Examples

example-putAttributes-ex1 skipped (runnableIn: reference)
Code:
See the example for deleteAttributes.
example-putAttributes-cover pass (runnableIn: node)
Code:
db().putAttributes([{name:'app_attr',value:'value'}]).end(function(){
  db().attributes(['app_attr']).end(function(a){ console.log(a[0].value); });
})
Output:
value
example-putAttributes-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().putAttributes);
Output:
function

resetUserPassword method

db().resetUserPassword(username, newpassword)

Administrative password reset for another user. May only be invoked by the app's responsible user or an admin user.
The user's own password (for self-service change) goes through updateUser with a
`password` attribute instead.

See also

updateUser · sendPasswordReminder

Examples

example-resetUserPassword-cover pass (runnableIn: node)
Code:
console.log(typeof db().resetUserPassword);
Output:
function

sendEmail method

db().sendEmail(to, from, subj, text, html, bcc, fwd)

Send email on behalf of the authenticated user

Send an email message to a specified addressee using the email configuration
previously saved in user attributes. The user attributes that must be present are

- EmailServerAddress (example: smtp.myserver.com)

- EmailServerPort (a number, example: 465)

- EmailUsesTLS (true or false, true for secure mail)

- EmailServerUsername

- EmailServerPassword

At least one of text, html, or fwd must be present. If either text or html is
present, fwd is ignored.

Parameters

NameTypeRequiredDescription
to string ✓ A comma spearated list of the email addresses of the intended recipients
from string ✓ The from address to be specified in the email
subj string ✓ The subject line
text string ✓ The plaintext email content (optional)
html string ✓ The HTML email content (optional)
bcc string ✓ A comma-separated list the email addresses of the blind-copy recipients (optional)
fwd string ✓ A complete rfc822 mail message to be forwarded (optional)

See also

sendPasswordReminder · sendUsernameReminder · updateUser

Examples

example-sendEmail-cover pass (runnableIn: node)
Code:
console.log(typeof db().sendEmail);
Output:
function

sendPasswordReminder method

db().sendPasswordReminder(username)

Send a message to the a user's email address containing new password information

The result set is replaced with a string such as the one below:

"A password reminder message has been sent to the email address associated with the username <username>, if any."

The subject of the email message is "<appname> account reminder".
The email message contains text such as the following:

"The password for your <appname> account has been set to wihyterobi."

The email is sent using the email information stored in the relevant application attributes. (See the
Srewtopdb Book sections on Application Attributes and Email
Confirmation for details.

Parameters

NameTypeRequiredDescription
username string ✓ The name of the user to whom the reminder message is to be sent.

See also

sendUsernameReminder · updateUser

Examples

example-sendPasswordReminder-ex1 skipped (runnableIn: reference)
Code:
db()
.appName('myapp')
.sendPasswordReminder('some-username')
.log()
.end()
Output:
A password reminder message has been sent to the email address associated with the username some-username, if any.
example-sendPasswordReminder-cover pass (runnableIn: node)
Code:
console.log(typeof db().sendPasswordReminder);
Output:
function

sendUsernameReminder method

db().sendUsernameReminder(email)
module: ttv-core

Send a message to the a user's email address containing the usernames registered with that email address

The result set is replaced with a string such as the one below:

"A reminder message containing the username(s) associated with &ltemailaddress>, if any, has been sent."

The subject of the email message is "<appname> account reminder".
The email message sent contains text such as the following:

The following <appname> username(s) are associated with the email address &ltemailaddress>:

<username>

Parameters

NameTypeRequiredDescription
email string ✓ address to which the reminder message is to be sent.

See also

sendPasswordReminder · updateUser

Examples

example-sendUsernameReminder-ex1 skipped (runnableIn: reference)
Code:
db()
.appName('myapp')
.sendUsernameReminder('[email protected]')
.log()
.end()
Output:
A reminder message containing the username(s) associated with [email protected], if any, has been sent.
example-sendUsernameReminder-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().sendUsernameReminder);
Output:
function

updateUser method

db().updateUser(attrs)

Update user account information and attributes

Attributes are name/value pairs that are saved on a per-user basis. Only the owning user (and the
app's responsible user) may access user attributes. For this reason attributes are useful for saving
such information as an email address and other personal information that should not be exposed to other
users but that may be needed to perform actions for the logged-in user.

ScrewtopDb creates and maintains the user attribute userTopicId which contains the identifier of
the user topic. This attribute may not be modified or deleted.

This method performs essentially the same function as putAttributes except
that the distinguished attributes email and password are included in the set of attributes that may be updated.
Note that the user attributes username and votes may not be updated.

Parameters

NameTypeRequiredDescription
attrsobj object ✓ An object whose members are attribute names, the values of which are attribute values. Note that
this object is different than the array of name-value pairs used in the putAttributes and
attributes methods.
username string Optional. The user whose attributes are to be updated. Only a super-user can update another
user's attributes.

See also

putAttributes

Examples

example-updateUser-cover pass (runnableIn: node)
Code:
console.log(typeof db().updateUser);
Output:
function

Testing

assert method

db().assert(func, errText)
module: ttv-core

Execute a function and thow or log an assertion failure if it returns false.

This method is intended for use in unit tests.

Parameters

NameTypeRequiredDescription
func function ✓ The function to be executed. The single argument is the current
result set. If this function returns true, sequence execution is unaffected. If it returns false,
an exception is thrown or an assertion failure message is logged and sequence execution is terminated.
errText string ✓ The text to be logged if the function above returns false.

See also

deny

Examples

example-assert-cover pass (runnableIn: node)
Code:
var seen=false; db().setValues([1]).assert(function(arr){ seen=arr.length===1; return true; }).end(function(){ console.log(seen); })
Output:
true

deny method

db().deny(func, errText)
module: ttv-core

Execute a function and throw or log an assertion failure if it returns true.

This method is intended for use in unit tests.

Parameters

NameTypeRequiredDescription
func function ✓ The function to be executed. The single argument is the current
result set. If this function returns true, sequence execution is unaffected. If it returns true,
an exception is thrown or an assertion failure message is logged and sequence execution is terminated.
errText string ✓ The text to be logged if the function above returns true.

See also

deny

Examples

example-deny-cover pass (runnableIn: node)
Code:
var seen=false; db().setValues([]).deny(function(arr){ seen=arr.length>0; return false; }).end(function(){ console.log(seen); })
Output:
false
example-deny-cover3 pass (runnableIn: node)
Code:
console.log(typeof db().deny);
Output:
function

Misc

clear method

db().clear()
module: ttv-core

Clear the current result set.

The result set is the array of objects passed to the next step in the sequence. This
method clears that array.

Examples

example-clear-ex1 pass (runnableIn: node)
Code:
db()
.setValues([1, 2, 3])
.clear()
.log()
.end();
Output:
[]
example-clear-cover pass (runnableIn: node)
Code:
db().setValues([1,2]).clear().end(function(arr){ console.log(arr); })
Output:
[]
example-clear-cover2 pass (runnableIn: node)
Code:
db().setValues([1,2]).clear().end(function(arr){ console.log(arr); })
Output:
[]

db.pathValueIdForTopic factory

db.pathValueIdForTopic(arg)
module: ttv-core

Get the value that led you to a topic.

Each time the topics method is executed, it saves the objects from which
it obtained the topic IDs that it will be fetching. The pathValueIdForTopic utility method, given
a topic or topic ID, returns the value that was last used to navigate to the topic. Note that many
topics may contain values referencing the specified topic. The one that is returned by this method is the one
that was last used by the topics method to retrieve the topic.

This can be useful in the circumstance where the topic referenced by a value needs to be retrieved in
order to determine what action to take on the value (e.g. deletion).

Parameters

NameTypeRequiredDescription
topicId topicId ✓ The topic ID for which the path value is being requested.

Examples

example-db.pathValueIdForTopic-cover pass (runnableIn: node)
Code:
console.log(typeof db.pathValueIdForTopic);
Output:
function

options method

db().options(obj)
module: ttv-core

Set options affecting the behavior of the ScrewtopDB Javascript library.

The following options may be set using this function by passing an object containing the
members shown:

{ tagPrefix: "user"|"app"|<string>> }

The tagPrefix option defines the prefix that will be applied to tag specifications.
The value of the tagPrefix option may be

- "user" - The username of the currently logged in user, if any.

- "app" - The application name of the current application, if any.

- a string - If the value is neither "user" or "app", then the the string itself is used.

Tag specifications are of the form owner/tagname where owner is the username of the tag's
owner and tagname is the name of the tag.

Note that there is also a short form of tag specification. A tag may be prefixed with ./ or
../ in place of the owner. When the tag is encountered by the ScrewtopDB Javascript library,
the ./ prefix is replaced by the username of the currently logged-in user.
The ../ prefix is replaced by the the application name of the current application.

Parameters

NameTypeRequiredDescription
obj object ✓ The options object containing a member and associated value for each option.

Examples

example-options-ex1 pass (runnableIn: node)
Code:
// Set the tagPrefix option so that the current logged-in user is assumed to be the owner of
// tags specified without an owner field.
db()
.login('<appname>', '<username>', '<password>')
.options({ tagPrefix: 'app' })
.topicByName('user:<username>')
.tagValues('login count')
.each(function(val) {
    alert('Login count: ' + val.text);
})
.end();
example-options-cover pass (runnableIn: node)
Code:
db().options({}).end(function(){ console.log('ok'); })
Output:
ok
example-options-cover2 pass (runnableIn: node)
Code:
db().options({}).end(function(){ console.log('ok'); })
Output:
ok

url method

db().url(arg)
module: ttv-core

Set or get the web address of the ScrewtopDB server

This is primarily for use by Twistoff Software but might be useful if you are
accessing the ScrewtopDB server via a proxy.

The default value is https://www.screwtopdb.com.

Parameters

NameTypeRequiredDescription
arg string | function(addr) ✓ If this argument is a string, it is the URL of the server
to which requests will be sent. If this argument is a function, the function will be invoked
and passed as its single argument the URL of the current ScrewtopDB server. The return value of the function is ignored.

Examples

example-url-ex1 skipped (runnableIn: browser)
Code:
db()
.url(function(addr) {
     alert("Default server is " + addr + ".");
})
.url('http://localhost')
.url(function(addr) {
     alert("Default server is now " + addr + ".");
})
.end()
example-url-cover pass (runnableIn: node)
Code:
console.log(typeof db().url);
Output:
function
example-url-cover2 pass (runnableIn: node)
Code:
console.log(typeof db().url);
Output:
function

Utility

db.abortAll factory

db.abortAll()
module: ttv-core

Cancel all pending chain executions by resetting the function sequencer queues.

This effectively abandons all in-flight query sequences. Sequences initiated with
fork or go are also terminated.

See also

abort

Examples

example-db.abortAll-ex1 pass (runnableIn: node)
Code:
db.abortAll();
example-db.abortAll-cover pass (runnableIn: node)
Code:
db.abortAll(); console.log('ok');
Output:
ok

db.addTopicMembers factory

db.addTopicMembers(topic)
module: ttv-core

Augment a topic object with convenience properties derived from its tags.

For each tag in the topic, creates a property on the topic object named after the tag's text
(with the owner prefix stripped), whose value is an array of the tag's value text strings.
Non-standard properties are removed first. The tag named `text` is skipped to avoid
overwriting the topic's own `.text` property.

Parameters

NameTypeRequiredDescription
topic object ✓ A ScrewtopDB topic object with a .tags array.

Examples

example-db.addTopicMembers-ex1 pass (runnableIn: node)
Setup:
db().addTopics({text:'person', name:'Alice', comments:['Great!','Thanks']}).end()
Code:
db()
.topicByName('person')
.first(function(topic) {
    db.addTopicMembers(topic);
    console.log(JSON.stringify(topic.comments));
})
.end();
Output:
["Great!","Thanks"]
example-db.addTopicMembers-cover pass (runnableIn: node)
Code:
var t={text:'X',tags:[{text:'k',values:[{text:'v'}]}]}; db.addTopicMembers(t); console.log(t.k);
Output:
["v"]

db.applyPatch factory

db.applyPatch(p, o)

Apply a diff-match-patch text patch to a string.

Takes a patch produced by db.makePatch and applies it to the
original string, returning the patched result.

Parameters

NameTypeRequiredDescription
p string ✓ A patch in text format, as produced by db.makePatch.
o string ✓ The original string to apply the patch to.

See also

db.makePatch

Examples

example-db.applyPatch-ex1 pass (runnableIn: node)
Code:
var patch = db.makePatch('hello', 'hello world');
var result = db.applyPatch(patch, 'hello');
console.log(result); // "hello world"
Output:
"hello world"
example-db.applyPatch-cover pass (runnableIn: node)
Code:
var p=db.makePatch('hi','hi there'); console.log(db.applyPatch(p,'hi'));
Output:
hi there

db.dataFunctor factory

db.dataFunctor(name)
module: ttv-core

Create a functor (closure) that returns the current value of a named key from the shared data store
when invoked.

This allows deferred/lazy evaluation &mdash; the value is looked up at call time, not at creation time.
The returned function is internally marked so the library can identify it as a ScrewtopDB functor.

Parameters

NameTypeRequiredDescription
name string ✓ The key in the shared data store.

See also

db.setData · db.getData

Examples

example-db.dataFunctor-ex1 pass (runnableIn: node)
Code:
db.setData('myTopicName', 'blog-article');
var getTopicName = db.dataFunctor('myTopicName');

db()
.topicByName(getTopicName)
.end();
example-db.dataFunctor-cover pass (runnableIn: node)
Code:
db.setData('k','v'); var f=db.dataFunctor('k'); console.log(f());
Output:
v

db.getData factory

db.getData(name)
module: ttv-core

Retrieve a value from the shared module-level key-value data store.

Parameters

NameTypeRequiredDescription
name string ✓ The key to look up.

See also

db.setData · db.dataFunctor

Examples

example-db.getData-ex1 skipped (runnableIn: reference)
Code:
db.setData('currentUser', 'alice');
console.log(db.getData('currentUser')); // "alice"
example-db.getData-cover pass (runnableIn: node)
Code:
db.setData('k','v'); console.log(db.getData('k'));
Output:
v

db.isArguments factory

db.isArguments(v)
module: ttv-core

Return true if the argument is an arguments object.

When control enters the execution context of a Javascript function an arguments object is created.
The arguments object has an array-like structure with an indexed property for each passed argument
and a length property equal to the total number of parameters supplied by the caller.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isFunction · db.isRegExp · db.isNumber · db.isBoolean · db.isObject · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isArguments-ex1 skipped (runnableIn: browser)
Code:
function test(x) {
   alert(db.isArguments(arguments));
   alert(db.isArray(arguments));
}
test(1);
Output:
true
example-db.isArguments-cover pass (runnableIn: node)
Code:
console.log(db.isArguments({}));
Output:
false

db.isArray factory

db.isArray(v)
module: ttv-core returns: boolean

Return true if the argument is an array.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.
value any ✓ The value to store.

See also

db.isFunction · db.isRegExp · db.isNumber · db.isBoolean · db.isObject · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isArray-ex1 skipped (runnableIn: browser)
Code:
alert(db.isArray([ 1, 2 ]) + '\n' + db.isArray('xyz'));
Output:
true
false
example-db.isArray-cover pass (runnableIn: node)
Code:
console.log(db.isArray([1,2,3]));
Output:
true
example-isArray-basic stale (runnableIn: node)
Code:
console.log(db.isArray([1, 2, 3]))
Output:
true

db.isBoolean factory

db.isBoolean(v)
module: ttv-core

Return true if the argument is a boolean.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isFunction · db.isNumber · db.isRegEx · db.isObject · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isBoolean-ex1 skipped (runnableIn: browser)
Code:
alert(db.isBoolean(false) + '\n' + db.isBoolean(1 == 2));
Output:
true
true
example-db.isBoolean-cover pass (runnableIn: node)
Code:
console.log(db.isBoolean(true));
Output:
true

db.isDefined factory

db.isDefined(v)
module: ttv-core

Return true if the argument is defined.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isFunction · db.isNumber · db.isRegEx · db.isBoolean · db.isObject · db.isString · db.isEmpty

Examples

example-db.isDefined-ex1 skipped (runnableIn: browser)
Code:
alert(db.isDefined(db().topicByName) + '\n' + db.isDefined(db.bogus));
Output:
true
false
example-db.isDefined-cover pass (runnableIn: node)
Code:
console.log(db.isDefined(0));
Output:
true

db.isEmpty factory

db.isEmpty(value, allowBlank)
module: ttv-core

Return true if the argument is an empty string, null, or undefined.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.
allowBlank boolean ✓ True to not consider a zero-length string empty

See also

db.isArray · db.isFunction · db.isNumber · db.isRegEx · db.isBoolean · db.isObject · db.isString · db.isDefined

Examples

example-db.isEmpty-ex1 skipped (runnableIn: browser)
Code:
alert(db.isEmpty(null) + '\n' + db.isEmpty('') + '\n' + db.isEmpty('', true));
Output:
true
true
false
example-db.isEmpty-cover pass (runnableIn: node)
Code:
console.log(db.isEmpty(''));
Output:
true

db.isFunction factory

db.isFunction(v)
module: ttv-core

Return true if the argument is a function.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isRegExp · db.isNumber · db.isBoolean · db.isObject · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isFunction-ex1 skipped (runnableIn: browser)
Code:
alert(db.isFunction(function(){}) + '\n' + db.isFunction('xyz'));
Output:
true
false
example-db.isFunction-cover pass (runnableIn: node)
Code:
console.log(db.isFunction(function(){}));
Output:
true

db.isNumber factory

db.isNumber(v)
module: ttv-core

Return true if the argument is a number.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isFunction · db.isRegEx · db.isBoolean · db.isObject · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isNumber-ex1 skipped (runnableIn: browser)
Code:
alert(db.isNumber(23.01) + '\n' + db.isNumber(23/67));
Output:
true
true
example-db.isNumber-cover pass (runnableIn: node)
Code:
console.log(db.isNumber(42));
Output:
true

db.isObject factory

db.isObject(v)
module: ttv-core

Return true if the argument is an object.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isFunction · db.isNumber · db.isRegEx · db.isBoolean · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isObject-ex1 skipped (runnableIn: browser)
Code:
alert(db.isObject(false) + '\n' + db.isObject(db()));
Output:
false
true
example-db.isObject-cover pass (runnableIn: node)
Code:
console.log(db.isObject({}));
Output:
true

db.isRegExp factory

db.isRegExp(v)
module: ttv-core

Return true if the argument is a regular expression.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isFunction · db.isNumber · db.isBoolean · db.isObject · db.isString · db.isDefined · db.isEmpty

Examples

example-db.isRegExp-ex1 skipped (runnableIn: browser)
Code:
alert(db.isRegExp(/^xyz$/) + '\n' + db.isRegExp('xyz'));
Output:
true
false
example-db.isRegExp-cover pass (runnableIn: node)
Code:
console.log(db.isRegExp(/x/));
Output:
true

db.isString factory

db.isString(v)
module: ttv-core

Return true if the argument is a string.

Parameters

NameTypeRequiredDescription
v any ✓ The argument to be tested.

See also

db.isArray · db.isFunction · db.isNumber · db.isRegEx · db.isBoolean · db.isObject · db.isDefined · db.isEmpty

Examples

example-db.isString-ex1 skipped (runnableIn: browser)
Code:
alert(db.isString('xyz') + '\n' + db.isString());
Output:
true
false
example-db.isString-cover pass (runnableIn: node)
Code:
console.log(db.isString('hi'));
Output:
true

db.makePatch factory

db.makePatch(o, n)

Create a diff-match-patch text patch representing the changes needed to transform one string into another.

Parameters

NameTypeRequiredDescription
o string ✓ The original text.
n string ✓ The new/modified text.

See also

db.applyPatch

Examples

example-db.makePatch-ex1 pass (runnableIn: node)
Code:
var patch = db.makePatch('hello', 'hello world');
var result = db.applyPatch(patch, 'hello');
console.log(result); // "hello world"
Output:
"hello world"
example-db.makePatch-cover pass (runnableIn: node)
Code:
var p=db.makePatch('hi','hi there'); console.log(typeof p);
Output:
string

db.matchTagText factory

db.matchTagText(str)
module: ttv-core

Expand shorthand tag text prefixes based on the current API version.

In version 0: `../` expands to `<appName>/` and `./` expands
to `<username>/`.

In version 1: `../` and `./` prefixes are simply stripped.

If the string contains no `/`, it is returned unchanged.

Parameters

NameTypeRequiredDescription
str string ✓ A tag text string, possibly containing shorthand prefixes.

See also

setVersion

Examples

example-db.matchTagText-ex1 pass (runnableIn: node)
Code:
// With version 0, logged in as 'alice' to app 'myApp':
db.matchTagText('./comments');  // "alice/comments"
db.matchTagText('../settings'); // "myApp/settings"

// With version 1:
db.matchTagText('./comments');  // "comments"
example-db.matchTagText-cover pass (runnableIn: node)
Code:
console.log(db.matchTagText('city', 'city'));
Output:
city

db.resume factory

db.resume(func)

Resume a chain that was suspended by wait.

Retrieves the saved result set from the paused chain. If `func` is provided, executes it
with the saved result set; if it returns a defined value, that value replaces the result set.
Then continues the chain from where it was paused.

Parameters

NameTypeRequiredDescription
func function ✓ Optional. A function to execute before resuming. Receives the saved result set.
If it returns a defined value, that replaces the result set.

See also

wait · resume

Examples

example-db.resume-ex1 pass (runnableIn: node)
Code:
db()
.topicByName('myTopic')
.wait()
.log()
.end();

// Later, from another context:
db.resume();
example-db.resume-cover pass (runnableIn: node)
Code:
console.log(typeof db.resume);
Output:
function

db.setData factory

db.setData(name, value)
module: ttv-core

Store a value in the shared module-level key-value data store, accessible across all chains.

Parameters

NameTypeRequiredDescription
name string ✓ The key under which to store the value.
value any ✓ The value to store.

See also

db.getData · db.dataFunctor

Examples

example-db.setData-ex1 skipped (runnableIn: reference)
Code:
db.setData('currentUser', 'alice');
console.log(db.getData('currentUser')); // "alice"
example-db.setData-cover pass (runnableIn: node)
Code:
db.setData('k','v'); console.log(db.getData('k'));
Output:
v

db.userTopic factory

db.userTopic()
module: ttv-core

Return the topic text of the currently logged-in user (e.g. `"user:username"`).

This value is set during login or setSession.

See also

db.userTopicId · login · setSession

Examples

example-db.userTopic-ex1 skipped (runnableIn: reference)
Code:
console.log(db.userTopic()); // "user:alice"
example-db.userTopic-cover pass (runnableIn: node)
Code:
console.log(typeof db.userTopic);
Output:
function

db.userTopicId factory

db.userTopicId()
module: ttv-core

Return the topic ID of the currently logged-in user's user topic.

This value is set during login or setSession.

See also

db.userTopic · login · setSession

Examples

example-db.userTopicId-ex1 skipped (runnableIn: reference)
Code:
console.log(db.userTopicId()); // "5a3f..."
example-db.userTopicId-cover pass (runnableIn: node)
Code:
console.log(typeof db.userTopicId);
Output:
function

db.valueTopicIdForTag factory

db.valueTopicIdForTag(tagText, topic)
module: ttv-core

Find a tag within a topic by its text (case-insensitive) and return the `topicId`
of its first value.

Useful for navigating topic references &mdash; when a value in one topic points to another topic,
this extracts the referenced topic's ID.

Parameters

NameTypeRequiredDescription
tagText string ✓ The tag text to search for (case-insensitive match).
topic object ✓ A ScrewtopDB topic object containing a .tags array.

See also

db.pathValueIdForTopic · topics

Examples

example-db.valueTopicIdForTag-ex1 pass (runnableIn: node)
Code:
db()
.topicByName('blog-article')
.first(function(topic) {
    var commentTopicId = db.valueTopicIdForTag('comments', topic);
    console.log(commentTopicId);
})
.end();
example-db.valueTopicIdForTag-cover pass (runnableIn: node)
Code:
console.log(typeof db.valueTopicIdForTag);
Output:
function

Utility-Collection

db.collect factory

db.collect(array, testfunc)
module: ttv-core

Return a new array consisting of elements returned from a user-supplied function that is invoked for
each element of the input array.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element. The function should
return the element that is to be included in the output array.

See also

db.includes · db.select · db.reject · db.detect · db.forEach

Examples

example-db.collect-cover pass (runnableIn: node)
Code:
console.log(db.collect([1,2,3], function(x){ return x*x; }));
Output:
[1,4,9]

db.detect factory

db.detect(array, testfunc)
module: ttv-core

Return the first element of an array that passes a specified test.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element.

See also

db.includes · db.select · db.reject · db.collect · db.forEach · db.detect2

Examples

example-db.detect-cover pass (runnableIn: node)
Code:
console.log(db.detect([1,2,3], function(x){ return x>1; }));
Output:
2

db.detect2 factory

db.detect2(array, testfunc)
module: ttv-core

Return the first element of an array that passes a specified test as the single member of a new array

If the input object is undefined or empty or no element matches the test, an empty array is returned.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element.

See also

db.includes · db.select · db.reject · db.collect · db.forEach · db.detect

Examples

example-db.detect2-cover pass (runnableIn: node)
Code:
console.log(db.detect2([1,2,3], function(x){ return x>1; }));
Output:
[2]

db.firstIndexOf factory

db.firstIndexOf(array, func)
module: ttv-core

Return the zero-based index of the first matching element or -1 if no matching element is found

Parameters

NameTypeRequiredDescription
array array ✓ The input array
func function ✓ The function that is invoked once for each array element. This function
is passed the array element and its index as its two input arguments. If this function returns true,
the index of the current array element is the return value of firstIndexOf.

See also

db.includes · db.select · db.reject · db.collect · db.detect · db.forEach

Examples

example-db.firstIndexOf-cover pass (runnableIn: node)
Code:
console.log(db.firstIndexOf([10,20,30], function(x){return x===20;}));
Output:
1

db.forEach factory

db.forEach(array, func)
module: ttv-core

Execute a function once for each element of the input array.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element. This function
is passed the array element and its index as its two input arguments. The return value
of this function, if true, terminates the iteration.

See also

db.includes · db.select · db.reject · db.collect · db.detect

Examples

example-db.forEach-cover pass (runnableIn: node)
Code:
var out=[]; db.forEach([1,2,3], function(x){ out.push(x); }); console.log(out);
Output:
[1,2,3]

db.includes factory

db.includes(array, obj)
module: ttv-core

Return true if an array includes a specified element.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element. This function
should return true when the desired element is encountered.

See also

db.detect · db.select · db.reject · db.collect · db.forEach

Examples

example-db.includes-cover pass (runnableIn: node)
Code:
console.log(db.includes([1,2,3], 2));
Output:
true

db.objToDb factory

db.objToDb(obj, dbObjs)
module: ttv-core

Return value topicId for the first value in a tag specified by name

Parameters

NameTypeRequiredDescription
tagText string ✓ The text of the tag
topic object ✓ The topic in which the tag resides

Examples

example-db.objToDb-cover pass (runnableIn: node)
Code:
var arr=db.objToDb({text:'x',k:'v'}); console.log(Array.isArray(arr));
Output:
true

db.reject factory

db.reject(array, testfunc)
module: ttv-core

Return a new array containing only those elements from the input array that di not pass a specified test.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element. The function should
return false for elements that are not to be selected.

See also

db.includes · db.select · db.detect · db.collect · db.forEach

Examples

example-db.reject-cover pass (runnableIn: node)
Code:
console.log(db.reject([1,2,3], function(x){return x===2;}));
Output:
[1,3]

db.select factory

db.select(array, testfunc)
module: ttv-core

Return a new array containing elements selected from the input array that pass a specified test.

Parameters

NameTypeRequiredDescription
array array ✓ The input array
testfunc function ✓ The function that is invoked once for each array element. This function
should return true for each element that is to be selected.

See also

db.includes · db.detect · db.reject · db.collect · db.forEach

Examples

example-db.select-cover pass (runnableIn: node)
Code:
console.log(db.select([1,2,3], function(x){return x>1;}));
Output:
[2,3]

REST API

DELETE /:app/acls.json/:id restEndpoint

Delete an ACL by id. Requires an authenticated session.

MethodDELETE
Path/:app/acls.json/:id
Authtrue
Response{ result:"success" }

DELETE /:app/apps.json/:todel restEndpoint

Delete an application.

Delete an application.

Authorization: Admin or responsible user.

URL Parameters:

  • app - Application name (used for routing)
  • todel - Name of application to delete

Response:


{
  "result": "success"
}

---

Scripts Endpoint

MethodDELETE
Path/:app/apps.json/:todel
Authtrue

Examples

example-delete-app-apps-json-todel-real pass (runnableIn: shell)
Code:
curl -s -u 'screwtop:<admin-password>' -X DELETE 'http://localhost:4342/screwtop/apps.json/EX_TODEL'
Output:
{
  "result": "success",
  "serverProcessingTime": 3,
  "cacheHitRate": 0.15,
  "cacheEvictionRate": 0,
  "cacheSize": 1,
  "cacheLimit": 1048576
}

DELETE /:app/attributes.json/:names restEndpoint

Delete user attributes.

Delete user attributes.

Authentication: Session required.

URL Parameters:

  • names - Comma-separated attribute names to delete

Query Parameters:

  • username - (Optional) Target username. Requires admin or responsible user privileges.

Notes:

  • Read-only attributes and appattrs cannot be deleted.
  • Deleting email sets it to empty string rather than removing it.

Response:


{
  "result": "success"
}

---

Sessions Endpoints

MethodDELETE
Path/:app/attributes.json/:names
Authtrue

Examples

example-delete-app-attributes-json-names-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X DELETE \
  'http://localhost:4342/PROSE_FIX_MOEK3D80/attributes.json/delme'
Output:
{
  "result": "success",
  "serverProcessingTime": 1,
  "cacheHitRate": 0.7058823529411765,
  "cacheEvictionRate": 0,
  "cacheSize": 215,
  "cacheLimit": 1048576
}

DELETE /:app/instances.json/:text/:instance restEndpoint

REMOVED in v2, for the same reason as the GET: there are no instance numbers. The
route answers HTTP 409 with { result, hint, instances }, listing the topicIds that
carry the name. Delete one node with DELETE /:app/topics.json/<topicId>.

MethodDELETE
Path/:app/instances.json/:text/:instance
Authtrue
ResponseHTTP 409 { result, hint, instances:[topicId, ...] }
Implemented bydeleteInstance

DELETE /:app/topics.json/:text restEndpoint

Delete topic(s) by ID(s).

Delete topic(s) by ID(s).

URL Parameters:

  • app - Application name
  • text - Comma-separated numeric IDs (e.g., 123 or 1,2,3)

Response:


{
  "result": "success",
  "actions": {
    "ts": {},
    "delete": [123, 456, 789]
  }
}

Note: Deleting a topic cascades to delete all associated values.

---

Topics HTML Endpoints

These endpoints return HTML-formatted topic views instead of JSON.

MethodDELETE
Path/:app/topics.json/:text
Authtrue

Examples

example-rest-delete-app-topics-json-text-ex1 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "ts": {},
    "delete": [123, 456, 789]
  }
}
example-delete-app-topics-json-text-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X DELETE \
  'http://localhost:4342/PROSE_LATE_MOEKQDHB/topics.json/deleteme'
Output:
Access denied

DELETE /:app/users.json/:username restEndpoint

Delete a user from an application.

Delete a user from an application.

Authorization:

  • Responsible user of the app
  • Admin
  • User can delete themselves

Restrictions:

  • Cannot delete the responsible user

URL Parameters:

  • app - Application name
  • username - Username to delete

Response:


{
  "result": "success"
}

Error Response (responsible user):


{
  "result": "Responsible user may not be deleted."
}

---

MethodDELETE
Path/:app/users.json/:username
Authtrue

Examples

example-rest-delete-app-users-json-username-ex1 skipped (runnableIn: reference)
Code:
{
  "result": "success"
}
example-delete-app-users-json-username-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X DELETE \
  'http://localhost:4342/PROSE_FIX_MOEK3D80/users.json/killme'
Output:
{
  "result": "success",
  "serverProcessingTime": 1,
  "cacheHitRate": 0.6932599724896836,
  "cacheEvictionRate": 0,
  "cacheSize": 215,
  "cacheLimit": 1048576
}

GET /:app/acls.json restEndpoint

List ACLs for the app. NOTE: this endpoint is currently a stub — it returns { result:"success" } without enumerating ACLs. Use GET /:app/acls.json/:name to resolve a specific ACL by name. Requires an authenticated session.

MethodGET
Path/:app/acls.json
Authtrue
Response{ result:"success" }

GET /:app/acls.json/:name restEndpoint

Resolve an ACL id by its name. Requires an authenticated session.

MethodGET
Path/:app/acls.json/:name
Authtrue
Response{ result:"success", aclId:"..." } (or { result:"ACL not found" })

GET /:app/apps.json restEndpoint

Get application details including member list.

Get application details including member list.

URL Parameters:

  • app - Application name

Query Parameters:

  • include=userattributes - Include user attributes (adds userTopicId to each member)

Response:


{
  "result": "success",
  "data": {
    "appId": "1",
    "appName": "myapp",
    "responsibleUserId": "5",
    "responsibleUserName": "admin",
    "lastModified": 1234567890,
    "appAttributes": [],
    "appMembers": [
      {
        "username": "myapp:john",
        "userId": 10,
        "lastLogin": "1234567890",
        "unauthenticated": false,
        "privileges": ["admin"]
      }
    ]
  }
}

Notes:

  • privileges contains ["admin"] for responsible users, empty array otherwise.
  • username is prefixed with the app name and colon.

---

MethodGET
Path/:app/apps.json
Authtrue

Examples

example-get-app-apps-json-real pass (runnableIn: shell)
Code:
curl -s -u 'screwtop:<admin-password>' -X GET 'http://localhost:4342/screwtop/apps.json'
Output:
{
  "result": "success",
  "data": {
    "appId": "0",
    "appName": "screwtop",
    "responsibleUserId": "0",
    "responsibleUserName": "",
    "lastModified": 1772837053115,
    "appAttributes": [],
    "appMembers": [
      {
        "username": "screwtop:screwtop",
        "userId": 1,
        "lastLogin": "1777135622420",
        "unauthenticated": false,
        "privileges": [
          "admin"
        ]
      }
    ]
  },
  "serverProcessingTime": 1,
  "cacheHitRate": 0.1,
  "cacheEvictionRate": 0,
  "cacheSize": 1,
  "cacheLimit": 1048576
}

GET /:app/attributes.json restEndpoint

Get all user attributes.

Get all user attributes.

Authentication: Session required.

Query Parameters:

  • username - (Optional) Username to look up. Requires admin or responsible user privileges.

Response:


{
  "result": "success",
  "data": { "attr1": "value1", "attr2": "value2" }
}

---

MethodGET
Path/:app/attributes.json
Authtrue

Examples

example-get-app-attributes-json-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X GET \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/attributes.json'
Output:
{
  "result": "success",
  "data": [
    {
      "name": "userTopicId",
      "value": "01KQ2QK7CHZZ026SJ19PEHX41X"
    },
    {
      "name": "previousLogin",
      "value": "1777135604045"
    },
    {
      "name": "loginTime",
      "value": "1777135604153"
    }
  ],
  "serverProcessingTime": 0,
  "cacheHitRate": 0.3660130718954248,
  "cacheEvictionRate": 0,
  "cacheSize": 69,
  "cacheLimit": 1048576
}

GET /:app/attributes.json/:attrName restEndpoint

Get a specific user attribute by name.

Get a specific user attribute by name.

Authentication: Session required.

URL Parameters:

  • app - Application name
  • attrName - Attribute name to retrieve

Query Parameters:

  • username - (Optional) Username to look up. Requires admin or responsible user privileges.

Response:


{
  "result": "success",
  "data": [{ "name": "attrName", "value": "attrValue" }]
}

Notes:

  • Returns null value if the attribute does not exist.
  • encryptedPassword falls back to legacy encpassword attribute if not found.

---

MethodGET
Path/:app/attributes.json/:attrName
Authtrue

Examples

example-get-app-attributes-json-attrname-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X GET \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/attributes.json/getattr'
Output:
{
  "result": "success",
  "data": [
    {
      "name": "getattr",
      "value": null
    }
  ],
  "serverProcessingTime": 1,
  "cacheHitRate": 0.36486486486486486,
  "cacheEvictionRate": 0,
  "cacheSize": 69,
  "cacheLimit": 1048576
}

GET /:app/diagnostics.json restEndpoint

Run the in-process diagnose audit over the app's graph and return its report: symbol/frame/slot integrity, missing-symbol and reverse-edge checks. Read-only.

MethodGET
Path/:app/diagnostics.json
Authtrue
Response{ ...diagnose report... }
Implemented bydiagnose

GET /:app/events/:notifyId restEndpoint

Subscribe to Server-Sent Events (SSE) for real-time updates.

Subscribe to Server-Sent Events (SSE) for real-time updates.

No authentication required (the notifyId acts as an opaque authorization token).

URL Parameters:

  • app - Application name
  • notifyId - Notification channel ID

Query Parameters:

  • source - (Optional) Source identifier. Events triggered by this source will not be sent back to this subscriber.

Response:

  • Content-Type: text/event-stream
  • Initial comment : connected sent on connection
  • Events are sent as data: <JSON>\n\n whenever a mutation occurs on the channel

Notes:

  • The connection remains open indefinitely (long-lived).
  • Events are triggered by any mutation endpoint that includes ?notify=<notifyId> in its query string.

---

MethodGET
Path/:app/events/:notifyId
Authtrue

GET /:app/fts.json restEndpoint

Full-text search over the names of all nodes (native LevelDB FTS). In v2 a value's text is itself a node, so VALUE text is indexed, not just topic names. A hit's text may therefore be a value node (e.g. an email subject or body); resolve it to its owning topic with an inbound hop -- topicById(hit.topicId, {include:"inbound"}) or via:{tag:<tag>, inbound:true}. With ?q=QUERY returns ranked hits; without q returns index status (availability, document count N, version). Optional ?limit=N and ?mode=AND|OR. Long text that should NOT be searchable belongs in a blob, not a value.

MethodGET
Path/:app/fts.json
Authtrue
Response{ result:"success", impl:"native", hits:[...] } (or status when q omitted)
Implemented byftsSearch

Examples

example-rest-fts skipped (runnableIn: shell)
Code:
curl -u 'docsadmin:docsadmin-dev-pass' \
  'http://localhost:4342/screwtopdb-docs/fts.json?q=topicByName'
Output:
{"result":"success","impl":"native","hits":[ ... ]}

GET /:app/instances.json/:text/:instance restEndpoint

REMOVED in v2. Addressing an instance by NUMBER is gone, so this route answers
HTTP 409 with { result, hint, instances } -- `instances` lists the topicIds carrying
the name, so a caller can recover in one hop. Fetch one node with
GET /:app/topics.json/<topicId>, or the whole same-named set with
GET /:app/topics.json/<name>.

MethodGET
Path/:app/instances.json/:text/:instance
Authtrue
ResponseHTTP 409 { result, hint, instances:[topicId, ...] }
Implemented bytopicByNameAndInstance

GET /:app/listpolicy.json restEndpoint

Read the app listing (anti-enumeration) policy.

Read the app's listing policy, which controls whether ordinary callers may enumerate the app's topics and members.

URL Parameters:

  • app - Application name.

Response:


{ "result": "success", "policy": "open" }

policy is open (the default: enumeration works normally) or restricted (see PUT). Readable by any session.

MethodGET
Path/:app/listpolicy.json
Authtrue

Examples

example-rest-get-app-listpolicy-json-ex1 n/a (runnableIn: shell)
Code:
curl -s -u 'user:pass' 'http://localhost:4342/myapp/listpolicy.json'
Output:
{ "result": "success", "policy": "open" }

GET /:app/noaclpolicy.json restEndpoint

Read the app no-ACL policy.

Read the app's no-ACL policy: how objects that carry no explicit ACL are treated.

URL Parameters:

  • app - Application name.

Response:


{ "result": "success", "policy": "open" }

policy is open (the default: ACL-less objects are world-readable, additions are open, modify/delete are owner-only) or owner (ACL-less objects are owner-only for every right, reads included). Explicit ACLs are unaffected either way. Readable by any session.

MethodGET
Path/:app/noaclpolicy.json
Authtrue

Examples

example-rest-get-app-noaclpolicy-json-ex1 n/a (runnableIn: shell)
Code:
curl -s -u 'user:pass' 'http://localhost:4342/myapp/noaclpolicy.json'
Output:
{ "result": "success", "policy": "open" }

GET /:app/raw/:name/:tag restEndpoint

Return a stored value (page HTML, CSS, ...) as the raw response body.

Return one stored value as the whole response body, with no JSON wrapping. It serves a page, stylesheet or document kept in a topic, and it is the v2 form of the IW front controller's /{app}/topics?name=<page>.

URL Parameters:

  • app - Application name.
  • name - Topic name.
  • tag - Optional. The tag whose first value is returned. Defaults to raw (GET /:app/raw/:name).

Behavior:

  • Only a value written by the app's responsible user (or the super-admin) is served: the first such value of the tag. Publishing a document on the server's origin is the app owner's decision, so values other users add to that tag (or a same-named tag of their own) are ignored, wherever they sort; if there are only such values, the response is 404.
  • Content type: the first value of a content-type tag on the same topic (same owner rule), else from the topic name's extension (site.css is text/css), else text/html. Text types get charset=utf-8. X-Content-Type-Options: nosniff is always set.
  • Normal read rules apply. The topic is read with the caller's identity, so ACLs hold, and an app with UnauthenticatedRead=false answers 403 to an unauthenticated caller.

Response: the value's text as the body. 404 (plain text) when the topic, the tag, or a value the caller may read is missing.

MethodGET
Path/:app/raw/:name/:tag
Authfalse

Examples

example-rest-get-app-raw-name-tag-ex1 n/a (runnableIn: shell)
Code:
curl -s -u 'user:pass' 'http://localhost:4342/myapp/raw/index'
Output:
<html>...the first value of the "raw" tag on topic "index"...</html>

GET /:app/reclaim.json restEndpoint

Full-graph symbol audit and reclamation. Walks the symbol registry, recomputes each symbol's true reference count from the graph, and reports drift plus orphan symbols (symbols with no associated object). Read-only by default; pass ?commit=true (or ?commit=1) to rewrite drifted counts and reclaim orphans. Backfills refs on legacy databases and cleans orphans accumulated before inline reference counting; steady-state reclamation is inline.

MethodGET
Path/:app/reclaim.json
Authtrue
Response{ scanned, drift:[...], orphans:[...], reclaimed:[...] (when commit) }

Examples

example-rest-reclaim skipped (runnableIn: shell)
Setup:
// dry run (read-only). add ?commit=true to actually reclaim.
Code:
curl -u 'docsadmin:docsadmin-dev-pass' \
  'http://localhost:4342/screwtopdb-docs/reclaim.json'
Output:
{"scanned":...,"drift":[],"orphans":[]}

GET /:app/symbols.json restEndpoint

Dump the app's interned symbol registry as JSON. Optional ?maxlen=N truncates long symbol keys in the response.

MethodGET
Path/:app/symbols.json
Authtrue
Response{ result:"success", data:[ { symbol fields... } ] }
Implemented byallSymbols

GET /:app/topics.html/ restEndpoint

Get HTML view with query parameter `?name=<topicname>`.

Get HTML view with query parameter ?name=<topicname>.

---

Attributes Endpoints

User attributes are key-value pairs associated with a user account.

MethodGET
Path/:app/topics.html/
Authtrue

GET /:app/topics.html/:text restEndpoint

Get HTML view of topic by name or ID.

Get HTML view of topic by name or ID.

MethodGET
Path/:app/topics.html/:text
Authtrue

GET /:app/topics.html/id/:id restEndpoint

Get HTML view of topic by numeric ID.

Get HTML view of topic by numeric ID.

MethodGET
Path/:app/topics.html/id/:id
Authtrue

GET /:app/topics.html/name/:text restEndpoint

Get HTML view of topic by name.

Get HTML view of topic by name.

MethodGET
Path/:app/topics.html/name/:text
Authtrue

GET /:app/topics.json restEndpoint

Search or query topics.

Search or query topics.

URL Parameters:

  • app - Application name

Query Parameters:

  • name - Get topic by exact name match
  • find - Regex pattern to search topic names
  • include - Relationships to include (default: outbound)
  • exclude - Relationships to exclude
  • recursevia - Same as above (recursive graph traversal)
  • via - Same as above (multi-hop graph traversal)

Response:


{
  "result": "success",
  "topics": [...]
}

---

MethodGET
Path/:app/topics.json
Authtrue
Response{ "result": "success", "topics": [ {text, topicId, tags:[...]} ] }
Implemented bytopicByName

Examples

example-rest-get-app-topics-json-ex1 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "topics": [...]
}
example-get-app-topics-json-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X GET \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/topics.json?find=search'
Output:
{
  "result": "success",
  "topics": [
    {
      "text": "searchA",
      "topicId": "01KQ2QK83DWQSXD0CZ3Z9X0SWC",
      "unique": false,
      "instance": 0,
      "cnt": 1,
      "creationTime": 1777134575725,
      "ts": 1777134575725,
      "tags": [
        {
          "tagId": "01KQ2QK83E9EYYCKS82V28HXE0",
          "text": "x",
          "tagType": "outbound",
          "topicId": "01KQ2QK7S417V3A5ZG3G4NSHHJ",
          "parent": "01KQ2QK83DWQSXD0CZ3Z9X0SWC",
          "unique": false,
          "ts": 1777134575725,
          "owner": "pfu",
          "values": [
            {
              "text": "1",
              "valueId": "01KQ2QK83E9EYYCKS82V28HXE1",
              "topicId": "01KQ2QK83E9EYYCKS82V28HXE2",
              "parent": "01KQ2QK83E9EYYCKS82V28HXE0",
              "unique": false,
              "ts": 1777134575725,
              "owner": "pfu",
              "acl": 0,
              "cnt": 0,
              "instance": 0,
              "topicInstance": 0
            }
          ],
          "cnt": 1
        }
      ]
    },
    {
      "text": "searchB",
      "topicId": "01KQ2QK83HN7M4EGJZWR5C8EHT",
      "unique": false,
      "instance": 0,
      "cnt": 1,
      "creationTime": 1777134575728,
      "ts": 1777134575728,
      "tags": [
        {
          "tagId": "01KQ2QK83HN7M4EGJZWR5C8EHV",
          "text": "x",
          "tagType": "outbound",
          "topicId": "01KQ2QK7S417V3A5ZG3G4NSHHJ",
          "parent": "01KQ2QK83HN7M4EGJZWR5C8EHT",
          "unique": false,
          "ts": 1777134575728,
          "owner": "pfu",
          "values": [
            {
              "text": "2",
              "valueId": "01KQ2QK83HN7M4EGJZWR5C8EHW",
              "topicId": "01KQ2QK83JFTASGK8B94NNCAEZ",
              "parent": "01KQ2QK83HN7M4EGJZWR5C8EHV",
              "unique": false,
              "ts": 1777134575728,
              "owner": "pfu",
              "acl": 0,
              "cnt": 0,
              "instance": 0,
              "topicInstance": 0
            }
          ],
          "cnt": 1
        }
      ]
    }
  ],
  "serverProcessingTime": 3,
  "cacheHitRate": 0.3010752688172043,
  "cacheEvictionRate": 0,
  "cacheSize": 53,
  "cacheLimit": 1048576
}
example-rest-getTopic stale (runnableIn: shell)
Setup:
// curl with basic auth (user:pass), URL-encode the topic name
Code:
curl -u 'docsadmin:docsadmin-dev-pass' \
  'http://localhost:4342/screwtopdb-docs/topics.json/addTopics'
Output:
{"result":"success","topics":[{"text":"addTopics",...}]}

GET /:app/topics.json/:text restEndpoint

Retrieve topic(s) by name or ID(s).

Retrieve topic(s) by name or ID(s).

URL Parameters:

  • app - Application name
  • text - Topic name OR comma-separated numeric IDs (e.g., 123 or 1,2,3)

Query Parameters:

  • include - Comma-separated list of relationships to include:
  • outbound - Include outbound tag relationships
  • inbound - Include inbound tag relationships
  • allvalues - Include all values
  • alltopics - Include all related topics
  • recursevia - Recursive graph traversal. Follows outbound tag values matching the given tag name recursively, collecting all reachable topics. Handles cycles. Example: ?recursevia=children
  • via - Multi-hop graph traversal. JSON-encoded (or plain string for single tag name). Follows outbound tag values from the starting topic through one or more hops, returning the destination topics. Accepts a string, an object {"tag":"...", "with":{"tagName":"valueName"}}, or an array of such objects for multi-hop traversal. The optional with property filters destinations by requiring matching outbound tag:value pairs (AND logic). Values can be strings (exact match) or operator objects: {"$not":"X"} (negation), {"$none":"X"} (universal negation), {"$contains":"X"} (substring), {"$gt":"X"}, {"$gte":"X"}, {"$lt":"X"}, {"$lte":"X"} (comparison). Use {"$or":[...]} for OR across multiple tag criteria. Operators compose: {"$not":{"$contains":"X"}}.

Behavior:

  • If text matches pattern ^[0-9,]+$, treats it as ID(s) and fetches by ID
  • Otherwise, treats text as a topic name

Response:


{
  "result": "success",
  "data": [
    {
      "text": "topic name",
      "tags": [
        {
          "text": "tag name",
          "cnt": 2,
          "values": [
            { "text": "value text", "topicId": 123, "valueId": 456 }
          ]
        }
      ]
    }
  ]
}

---

MethodGET
Path/:app/topics.json/:text
Authtrue

Examples

example-rest-get-app-topics-json-text-ex1 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "data": [
    {
      "text": "topic name",
      "tags": [
        {
          "text": "tag name",
          "cnt": 2,
          "values": [
            { "text": "value text", "topicId": 123, "valueId": 456 }
          ]
        }
      ]
    }
  ]
}
example-get-app-topics-json-text-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X GET \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/topics.json/alice'
Output:
{
  "result": "success",
  "data": [
    {
      "text": "alice",
      "topicId": "01KQ2QK7DFXMHGEYRA0PH3XSCG",
      "unique": false,
      "instance": 0,
      "cnt": 1,
      "creationTime": 1777134575019,
      "ts": 1777134575019,
      "tags": [
        {
          "tagId": "01KQ2QK7DFXMHGEYRA0PH3XSCH",
          "text": "city",
          "tagType": "outbound",
          "topicId": "01KQ2QK7DJ1SPQD1TA5KAQ9BRS",
          "parent": "01KQ2QK7DFXMHGEYRA0PH3XSCG",
          "unique": false,
          "ts": 1777134575019,
          "owner": "pfu",
          "values": [
            {
              "text": "SF",
              "valueId": "01KQ2QK7DHB3MNY4FEGV7NR123",
              "topicId": "01KQ2QK7DHB3MNY4FEGV7NR124",
              "parent": "01KQ2QK7DFXMHGEYRA0PH3XSCH",
              "unique": false,
              "ts": 1777134575019,
              "owner": "pfu",
              "acl": 0,
              "cnt": 0,
              "instance": 0,
              "topicInstance": 0
            }
          ],
          "cnt": 1
        }
      ]
    }
  ],
  "serverProcessingTime": 103,
  "cacheHitRate": 0.2033898305084746,
  "cacheEvictionRate": 0,
  "cacheSize": 41,
  "cacheLimit": 1048576
}

GET /:app/topics.json/id/:id restEndpoint

Retrieve a topic by its numeric ID.

Retrieve a topic by its numeric ID.

URL Parameters:

  • app - Application name
  • id - Numeric topic ID

Query Parameters:

  • include - Same as above
  • recursevia - Same as above (recursive graph traversal)
  • via - Same as above (multi-hop graph traversal)

Response:


{
  "text": "topic name",
  "tags": [...]
}

---

MethodGET
Path/:app/topics.json/id/:id
Authtrue

Examples

example-rest-get-app-topics-json-id-id-ex1 skipped (runnableIn: reference)
Code:
{
  "text": "topic name",
  "tags": [...]
}
example-get-app-topics-json-id-id-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X GET \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/topics.json/id/01KQ2QK7S2CQC0595NE2CFH00G'
Output:
[
  {
    "text": "bobid",
    "topicId": "01KQ2QK7S2CQC0595NE2CFH00G",
    "unique": false,
    "instance": 0,
    "cnt": 1,
    "creationTime": 1777134575393,
    "ts": 1777134575393,
    "tags": [
      {
        "tagId": "01KQ2QK7S2CQC0595NE2CFH00H",
        "text": "x",
        "tagType": "outbound",
        "topicId": "01KQ2QK7S417V3A5ZG3G4NSHHJ",
        "parent": "01KQ2QK7S2CQC0595NE2CFH00G",
        "unique": false,
        "ts": 1777134575393,
        "owner": "pfu",
        "values": [
          {
            "text": "y",
            "valueId": "01KQ2QK7S2CQC0595NE2CFH00J",
            "topicId": "01KQ2QK7S417V3A5ZG3G4NSHHF",
            "parent": "01KQ2QK7S2CQC0595NE2CFH00H",
            "unique": false,
            "ts": 1777134575393,
            "owner": "pfu",
            "acl": 0,
            "cnt": 0,
            "instance": 0,
            "topicInstance": 0
          }
        ],
        "cnt": 1
      }
    ]
  }
]

GET /:app/users.json/votes restEndpoint

Get the current user's votes.

Get the current user's votes.

Authentication: Session required.

Response:


{
  "result": "success",
  "data": { ... }
}

---

Apps Endpoints

MethodGET
Path/:app/users.json/votes
Authtrue

Examples

example-get-app-users-json-votes-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X GET \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/users.json/votes'
Output:
{
  "result": "success",
  "data": [],
  "serverProcessingTime": 0,
  "cacheHitRate": 0.37142857142857144,
  "cacheEvictionRate": 0,
  "cacheSize": 71,
  "cacheLimit": 1048576
}

PATCH /:app/users.json/:username restEndpoint

Reset or change a user's password.

Reset or change a user's password.

Authorization: Requires responsible user of the app OR admin.

URL Parameters:

  • app - Application name
  • username - Username whose password to reset

Request Body:


{
  "password": "newpassword"
}

Response:


{
  "result": "success"
}

Error Response:


{
  "result": "Failed to reset password"
}

---

MethodPATCH
Path/:app/users.json/:username
Authtrue

Examples

example-rest-patch-app-users-json-username-ex1 skipped (runnableIn: reference)
Code:
{
  "password": "newpassword"
}
example-rest-patch-app-users-json-username-ex2 skipped (runnableIn: reference)
Code:
{
  "result": "success"
}
example-patch-app-users-json-username-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X PATCH \
  'http://localhost:4342/PROSE_FIX_MOEK3D80/users.json/patchme' \
  -H 'Content-Type: application/json' \
  --data "{\"password\":\"newpass\"}"
Output:
{
  "result": "success",
  "serverProcessingTime": 1,
  "cacheHitRate": 0.7015558698727016,
  "cacheEvictionRate": 0,
  "cacheSize": 215,
  "cacheLimit": 1048576
}

POST /:app/changes.json restEndpoint

Incremental sync. Given a set of topic ids and a timestamp, return the topics whose ts is greater than `since`, plus per-topic deletions recorded since then. Used by the disconnected/reconnection layer to catch up a local cache.

MethodPOST
Path/:app/changes.json
Authtrue
Request{ since:<ts>, topicIds:[id,...] }
Response{ result:"success", topics:[...], deletions:{ topicId:[...] } }

POST /:app/fts.json restEndpoint

Build (or rebuild) the full-text search index for the app.

MethodPOST
Path/:app/fts.json
Authtrue
Response{ result:"success", build:{...} }
Implemented byftsBuildIndex

POST /:app/instances.json restEndpoint

Mint a DISTINCT topic node carrying `topicText` -- this is what v2 instancing is --
and return its frame, whose `topicId` is the handle for every later reference.
`topicText` is required. `tagText`/`valueText` are optional and add the first edge;
omit them and a bare node is minted, to be given edges later by id.

The client-side equivalent is addTopics with a spec carrying instance:'new', in
either arity: addTopics({text, instance:'new', ...tags}) or
addTopics({text, instance:'new'}, tagText, valueText).

MethodPOST
Path/:app/instances.json
Authtrue
Request{ topicText, tagText?, valueText?, options? }
Response{ result:"success", data:[...] }

Examples

example-rest-instance-create skipped (runnableIn: shell)
Code:
curl -u 'docsadmin:docsadmin-dev-pass' -H 'Content-Type: application/json' \
  -d '{"topicText":"shopping","tagText":"item","valueText":"berries"}' \
  'http://localhost:4342/screwtopdb-docs/instances.json'
Output:
{"result":"success","data":[ ... ]}

POST /:app/scripts.json restEndpoint

Run a restricted ScrewtopDB chain on the server in one request.

Run a chain of ScrewtopDB data operations on the server in a single request, instead of one HTTP call per step. The server applies the caller's identity, runs the chain, and returns the final result set as data.

URL Parameters:

  • app - Application name.

Query Parameters:

  • notify - optional SSE channel id; a successful run is broadcast to it.
  • source - optional client id recorded on the broadcast SSE event.

Request Body:


{ "script": "topicByName('counter:k')" }

What a script may contain: The script is parsed, not evaluated. It must be a single chain of allowlisted data methods whose arguments are all literals (strings, numbers, booleans, null, and arrays/objects of those). Allowed methods are the data reads/writes and result-set navigation/filtering, e.g. topicByName, topicById, createValue, addToValue, subtractFromValue, addTopics, deleteTopics, deleteValues, tag, values, select, setACL, setVersion. Identity methods (setSession, url, logout, appName), error-handling switches (onError, safe, terminateOnError), flow control, logging, local-cache/offline methods, and app/user administration are not allowed. A script that uses a disallowed method, a non-literal argument, or more than one statement is refused with { "result": "script rejected: <reason>" }.

Identity:

  • With a session, the chain runs as that user; the identity is applied server-side and the script cannot set its own session.
  • Without a session, it runs unauthenticated against the app and is subject to the app's ACLs, no-ACL policy and listing policy.

Behavior:

  • Scripts run one at a time and each request is answered exactly once.
  • A chain error, such as an ACL denial, is returned as a non-success result; the request does not hang.

Response:


{ "result": "success", "data": { ... }, "serverProcessingTime": 42 }

Error Response:


{ "result": "No script provided" }
MethodPOST
Path/:app/scripts.json
Authtrue

Examples

example-rest-post-app-scripts-json-ex1 skipped (runnableIn: reference)
Code:
{ "script": "createValue('counter:k','value','0').topicByName('counter:k')" }
example-rest-post-app-scripts-json-ex2 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "data": { ... },
  "serverProcessingTime": 42
}
example-post-app-scripts-json-real n/a (runnableIn: shell)
Code:
curl -s -u 'user:pass' -X POST -H 'Content-Type: application/json' \
  --data "{\"script\":\"log('hi')\"}" \
  'http://localhost:4342/myapp/scripts.json'
Output:
{ "result": "script rejected: method not allowed: log" }

POST /:app/topics.json restEndpoint

Batch operations on topics.

Batch operations on topics.

URL Parameters:

  • app - Application name

Query Parameters:

  • get=true&multiple=true - Get multiple topics by name
  • create=true - Create or update a topic-tag-value
  • patch=true - (with create=true) Apply diff-match-patch instead of replacing the value
  • eval - Evaluate expression on value (see below)
  • notify - Notification channel ID (triggers SSE broadcast on change)
  • source - Source identifier for SSE
  • allowNegative=true - (with eval) Allow negative results (otherwise clamps to 0)

Eval Expressions:

  • v++ - Increment value
  • v-- - Decrement value
  • v+=N - Add N to value
  • v-=N - Subtract N from value
  • v=N - Set value to N

If the topic/tag doesn't exist yet, it is created with the expression evaluated against 0.

Request Body (for get multiple):


["topic1", "topic2", "topic3"]

Request Body (for create/eval):


{
  "topicText": "topic name",
  "tagText": "tag name",
  "valueText": "value"
}

Response (get multiple):


{
  "result": "success",
  "topics": [...]
}

Response (create):


{
  "result": "success",
  "actions": {
    "add": {
      "data": [...]
    }
  }
}

Response (eval):


{
  "result": "success",
  "actions": {
    "update": {
      "data": {
        "topicText": "...",
        "tagText": "...",
        "value": 5
      }
    }
  }
}

Notes:

  • For create=true: if the tag already exists on the topic, the last value is updated; otherwise a new topic-tag-value is created.
  • For eval: when allowNegative is not true and the result would be negative, value is clamped to 0 and actions.update.data.value is set to -1 to signal the clamp.

---

MethodPOST
Path/:app/topics.json
Authtrue

Examples

example-rest-post-app-topics-json-ex1 skipped (runnableIn: reference)
Code:
["topic1", "topic2", "topic3"]
example-rest-post-app-topics-json-ex2 skipped (runnableIn: reference)
Code:
{
  "topicText": "topic name",
  "tagText": "tag name",
  "valueText": "value"
}
example-rest-post-app-topics-json-ex3 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "topics": [...]
}
example-rest-post-app-topics-json-ex4 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "add": {
      "data": [...]
    }
  }
}
example-rest-post-app-topics-json-ex5 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "update": {
      "data": {
        "topicText": "...",
        "tagText": "...",
        "value": 5
      }
    }
  }
}
example-post-app-topics-json-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X POST \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/topics.json' \
  -H 'Content-Type: application/json' \
  --data "{\"topicText\":\"posttarget\",\"tagText\":\"newtag\",\"valueText\":\"newval\"}"
Output:
{
  "result": "success",
  "actions": [],
  "serverProcessingTime": 0,
  "cacheHitRate": 0.7552083333333334,
  "cacheEvictionRate": 0,
  "cacheSize": 205,
  "cacheLimit": 1048576
}

POST /:app/topics.json/:id restEndpoint

Update a topic value, move an element, vote, or unvote.

Update a topic value, move an element, vote, or unvote.

URL Parameters:

  • app - Application name
  • id - Element ID (topic, tag, or value)

Query Parameters:

  • move - If true, move the element instead of updating
  • vote - Integer vote value to cast on the topic
  • unvote - Integer vote value to remove from the topic
  • patch - If true, apply a diff-match-patch instead of replacing the value
  • notify - Notification channel ID (triggers SSE broadcast on change)
  • source - Source identifier for SSE (excluded from receiving the broadcast)
  • appupdated - If false, skip updating the app's lastModified timestamp

Request Body (for update):


{
  "valueText": "new value text"
}

Request Body (for topic text update):


{
  "topicText": "new topic text"
}

Request Body (for move):


{
  "insertBeforeId": 123
}

Response (move):


{
  "result": "success",
  "actions": {
    "move": {
      "nextId": 123,
      "movedId": 456,
      "ts": "timestamp",
      "topicIds": [...],
      "tagIds": [...],
      "valueIds": [...]
    }
  }
}

Response (update):


{
  "result": "success",
  "actions": [...]
}

Response (vote):


{
  "result": "success",
  "actions": {
    "vote": {
      "data": { ... }
    }
  }
}

Response (unvote):


{
  "result": "success",
  "actions": {
    "unvote": {
      "data": { ... }
    }
  }
}

Notes:

  • Unauthenticated users require the UnauthenticatedUpdate app attribute to update, or UnauthenticatedVote to vote.

---

MethodPOST
Path/:app/topics.json/:id
Authtrue

Examples

example-rest-post-app-topics-json-id-ex1 skipped (runnableIn: reference)
Code:
{
  "valueText": "new value text"
}
example-rest-post-app-topics-json-id-ex2 skipped (runnableIn: reference)
Code:
{
  "topicText": "new topic text"
}
example-rest-post-app-topics-json-id-ex3 skipped (runnableIn: reference)
Code:
{
  "insertBeforeId": 123
}
example-rest-post-app-topics-json-id-ex4 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "move": {
      "nextId": 123,
      "movedId": 456,
      "ts": "timestamp",
      "topicIds": [...],
      "tagIds": [...],
      "valueIds": [...]
    }
  }
}
example-rest-post-app-topics-json-id-ex5 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": [...]
}
example-rest-post-app-topics-json-id-ex6 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "vote": {
      "data": { ... }
    }
  }
}
example-rest-post-app-topics-json-id-ex7 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "unvote": {
      "data": { ... }
    }
  }
}
example-post-app-topics-json-id-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X POST \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/topics.json/01KQ2QM60QRGKNSNHEBRJMNGP3' \
  -H 'Content-Type: application/json' \
  --data "{\"topicText\":\"renamed\"}"
Output:
{
  "result": "success",
  "actions": {
    "update": [
      {
        "topicId": "01KQ2QM60QRGKNSNHEBRJMNGP3",
        "topicText": "renamed",
        "ts": 1777134606547
      }
    ]
  },
  "serverProcessingTime": 1,
  "cacheHitRate": 0.7586206896551724,
  "cacheEvictionRate": 0,
  "cacheSize": 195,
  "cacheLimit": 1048576
}

PUT /:app/acls.json restEndpoint

Create an access-control list. Requires an authenticated session. Each list entry grants or denies an access level to a set of ids.

MethodPUT
Path/:app/acls.json
Authtrue
Request{ name, list:[ { access:"r"|"w", ids:[...], allow:true|false } ] }
Response{ result:"success", aclId:"..." }

PUT /:app/apps.json restEndpoint

Create a new application.

Create a new application.

Authorization: Admin only.

URL Parameters:

  • app - Application name (used for routing, typically "screwtop")

Request Body:


{
  "appName": "newapp",
  "responsibleUserName": "admin_user",
  "responsibleUserPassword": "password"
}

Response:


{
  "result": "success",
  "data": {
    "text": "app",
    "tags": [
      { "text": "userId", "values": [{ "text": "123" }] }
    ]
  }
}

Error Response:


{
  "result": "Unauthorized"
}

---

MethodPUT
Path/:app/apps.json
Authtrue

Examples

example-rest-put-app-apps-json-ex1 skipped (runnableIn: reference)
Code:
{
  "appName": "newapp",
  "responsibleUserName": "admin_user",
  "responsibleUserPassword": "password"
}
example-rest-put-app-apps-json-ex2 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "data": {
    "text": "app",
    "tags": [
      { "text": "userId", "values": [{ "text": "123" }] }
    ]
  }
}
example-put-app-apps-json-real pass (runnableIn: shell)
Code:
curl -s -u 'screwtop:<admin-password>' -X PUT 'http://localhost:4342/screwtop/apps.json' \
  -H 'Content-Type: application/json' \
  --data "{\"appName\":\"EX_DEMO_APP\",\"responsibleUserName\":\"demo\",\"responsibleUserPassword\":\"demopw\"}"
Output:
{
  "result": "Error creating app EX_DEMO_APP",
  "serverProcessingTime": 19,
  "cacheHitRate": 0.10526315789473684,
  "cacheEvictionRate": 0,
  "cacheSize": 11,
  "cacheLimit": 1048576
}

PUT /:app/attributes.json restEndpoint

Set user attributes.

Set user attributes.

Authentication: Session required.

Query Parameters:

  • username - (Optional) Target username. Requires admin or responsible user privileges.

Request Body: Single object or array of name/value pairs:


[
  { "name": "attrName", "value": "attrValue" }
]

Read-Only Attributes (cannot be set):

  • logintime
  • previouslogin
  • usertopicid
  • apptopicid
  • admin
  • votes

Restricted Attributes:

  • appattrs - Only settable by super users (admin)

Response:


{
  "result": "success"
}

---

MethodPUT
Path/:app/attributes.json
Authtrue

Examples

example-rest-put-app-attributes-json-ex1 skipped (runnableIn: reference)
Code:
[
  { "name": "attrName", "value": "attrValue" }
]
example-put-app-attributes-json-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X PUT \
  'http://localhost:4342/PROSE_LATE2_MOEKVZWH/attributes.json' \
  -H 'Content-Type: application/json' \
  --data '[{"name":"put_attr","value":"put_val"}]'
Output:
{
  "result": "success",
  "serverProcessingTime": 1,
  "cacheHitRate": 0.751937984496124,
  "cacheEvictionRate": 0,
  "cacheSize": 63,
  "cacheLimit": 1048576
}

PUT /:app/listpolicy.json restEndpoint

Set the app listing policy (admin/responsible).

Set the app's listing policy. Super-admin or the app's responsible user only.

URL Parameters:

  • app - Application name.

Request Body:


{ "policy": "restricted" }

policy must be open or restricted. Under restricted, enumeration is refused to every caller except the super-admin and the app's responsible user: topics.json?find=, fts.json?q=, v2/find.json, the ?name=&via= and ?name=&recursevia= traversals, and inbound includes are answered 403 { "result": "listing restricted" }, and the member list (apps.json) returns only the caller's own entry. By-name and by-id reads, writes, SSE, and login are unaffected; the policy only removes enumeration, it never grants anything.

Response:


{ "result": "success", "policy": "restricted" }

Returns { "result": "Unauthorized" } for any other caller.

MethodPUT
Path/:app/listpolicy.json
Authtrue

Examples

example-rest-put-app-listpolicy-json-ex1 n/a (runnableIn: shell)
Code:
curl -s -u 'resp:pass' -X PUT -H 'Content-Type: application/json' \
  --data '{"policy":"restricted"}' 'http://localhost:4342/myapp/listpolicy.json'
Output:
{ "result": "success", "policy": "restricted" }

PUT /:app/noaclpolicy.json restEndpoint

Set the app no-ACL policy (admin/responsible).

Set the app's no-ACL policy. Super-admin or the app's responsible user only.

URL Parameters:

  • app - Application name.

Request Body:


{ "policy": "owner" }

policy must be open or owner. owner makes every ACL-less object owner-only, reads included (the super-admin, and the responsible user's write/delete/change override, still apply). Explicit ACLs are unaffected.

Response:


{ "result": "success", "policy": "owner" }

Returns { "result": "Unauthorized" } for any other caller.

MethodPUT
Path/:app/noaclpolicy.json
Authtrue

Examples

example-rest-put-app-noaclpolicy-json-ex1 n/a (runnableIn: shell)
Code:
curl -s -u 'resp:pass' -X PUT -H 'Content-Type: application/json' \
  --data '{"policy":"owner"}' 'http://localhost:4342/myapp/noaclpolicy.json'
Output:
{ "result": "success", "policy": "owner" }

PUT /:app/notifications.json/:notifyId restEndpoint

Send a notification to all SSE subscribers on a channel.

Send a notification to all SSE subscribers on a channel.

URL Parameters:

  • app - Application name
  • notifyId - Notification channel ID

Query Parameters:

  • source - (Optional) Source identifier to exclude from receiving the notification.

Request Body: Any JSON object to broadcast.

Response:


{
  "result": "success"
}

Broadcast payload:


{
  "notify": { ... }
}

---

Common Query Parameters

These parameters are supported across multiple mutation endpoints:

| Parameter | Description | |-----------|-------------| | notify | Notification channel ID. When present, the mutation's actions are broadcast to all SSE subscribers on this channel. | | source | Used with notify. The subscriber with this source identifier is excluded from receiving the broadcast. Prevents echo. | | appupdated | Set to false to skip updating the app's lastModified timestamp after a mutation. |

---

Error Responses

Authentication Failure

HTTP Status: 401

Headers:


WWW-Authenticate: Basic realm="example"

Body: Access denied

Bad Request

HTTP Status: 400

Invalid Session

{
  "result": "Invalid session"
}
Permission Denied

{
  "result": "Insufficient privilege"
}

---

Data Model

Topic Structure

{
  "text": "topic name",
  "topicId": 123,
  "tags": [
    {
      "text": "tag name",
      "tagId": 456,
      "cnt": 2,
      "values": [
        {
          "text": "value text",
          "valueId": 789,
          "topicId": 123
        }
      ]
    }
  ]
}
Element Types
  • f - Frame (topic)
  • out - Outbound relationship (tag)
  • in - Inbound relationship
  • v - Value

---

Graph Traversal

Two query parameters allow selecting topics by following outbound tag relationships as a graph.

recurseVia

Recursively follows a single tag name from a starting topic, collecting all reachable topics. Handles cycles via a visited set.

Example: Given topics A --children--> B, C and B --children--> D:


GET /:app/topics.json/A?recursevia=children

Returns topics A, B, C, and D.

via

Multi-hop graph traversal with optional filtering at each hop. Follows outbound tag values through one or more hops, returning only the destination topics (not intermediate hops).

Accepted formats for the via query parameter:

| Format | Example | |--------|---------| | Plain string (single hop) | ?via=departments | | JSON object (single hop with filter) | ?via={"tag":"departments","with":{"region":"US"}} | | JSON array (multi-hop) | ?via=[{"tag":"departments"},{"tag":"members"}] | | JSON array (multi-hop with filters) | ?via=[{"tag":"departments","with":{"region":"US"}},{"tag":"members","with":{"status":"active"}}] |

The with property filters candidate topics at each hop. All conditions must match (AND logic). Each key is an outbound tag name and each value is the required tag value text (for exact match) or an operator object.

with value operators:

| Operator | Meaning | Example | |----------|---------|---------| | "value" (string) | Exact match (default) | {"region": "US"} | | {"$not": X} | Existential negation — topic has at least one value NOT matching X | {"region": {"$not": "US"}} | | {"$none": X} | Universal negation — topic has NO values matching X | {"region": {"$none": "US"}} | | {"$contains": "str"} | Substring match (case-sensitive) — value contains the string | {"name": {"$contains": "smith"}} | | {"$gt": "X"} | Greater than (numeric if both parse as numbers, otherwise lexicographic) | {"score": {"$gt": "5"}} | | {"$gte": "X"} | Greater than or equal | {"date": {"$gte": "2026-03-01"}} | | {"$lt": "X"} | Less than | {"score": {"$lt": "10"}} | | {"$lte": "X"} | Less than or equal | {"date": {"$lte": "2026-03-31"}} |

Range queries: Multiple comparison and $contains operators AND together within a single object: {"$gte": "2026-03-01", "$lte": "2026-03-31"} matches values in that range.

$or clause: Use "$or" as a top-level key in with alongside regular tag criteria. Its value is an array of clause objects. Each clause is a {tagName: critValue} object (all keys within a clause must match). The $or passes if ANY clause matches. Regular criteria AND with the $or result.

Example: {"status": "active", "$or": [{"region": "US"}, {"region": "EU"}]} — status must be "active" AND region must be "US" or "EU".

Operator composition: $not and $none can wrap any operator or plain string.

  • {"$not": {"$contains": "str"}} — has a value that does NOT contain "str"
  • {"$none": {"$contains": "str"}} — NO values contain "str"
  • {"$none": {"$gte": "5"}} — NO values are >= 5

Examples: Given Acme Corp --departments--> Engineering, Sales where Engineering has tag region: US and Sales has tag region: EU:


GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"region":"US"}}

Returns only Engineering.


GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"region":{"$not":"US"}}}

Returns only Sales (region is not US).


GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"region":{"$contains":"U"}}}

Returns both Engineering (US) and Sales (EU) since both contain "U".


GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"$or":[{"region":"US"},{"region":"EU"}]}}

Returns both Engineering and Sales (region is US or EU).

---

Session Management

  • Sessions are stored in-memory (not persisted across server restarts)
  • Session timeout: 1 hour of inactivity
  • Sessions are automatically culled on each getSession call
  • Each session tracks: sessionId, lastAccess, user, app, admin, impersonated

---

Truthy Values

Query parameters that accept boolean values recognize these as true: true, t, 1, yes, y (case-insensitive). All other values are treated as false.

MethodPUT
Path/:app/notifications.json/:notifyId
Authtrue

Examples

example-rest-put-app-notifications-json-notifyid-ex1 skipped (runnableIn: reference)
Code:
{
  "result": "success"
}
example-rest-put-app-notifications-json-notifyid-ex2 skipped (runnableIn: reference)
Code:
{
  "notify": { ... }
}
example-rest-put-app-notifications-json-notifyid-ex3 skipped (runnableIn: reference)
Code:
WWW-Authenticate: Basic realm="example"
example-rest-put-app-notifications-json-notifyid-ex4 skipped (runnableIn: reference)
Code:
{
  "result": "Invalid session"
}
example-rest-put-app-notifications-json-notifyid-ex5 skipped (runnableIn: reference)
Code:
{
  "result": "Insufficient privilege"
}
example-rest-put-app-notifications-json-notifyid-ex6 skipped (runnableIn: reference)
Code:
{
  "text": "topic name",
  "topicId": 123,
  "tags": [
    {
      "text": "tag name",
      "tagId": 456,
      "cnt": 2,
      "values": [
        {
          "text": "value text",
          "valueId": 789,
          "topicId": 123
        }
      ]
    }
  ]
}
example-rest-put-app-notifications-json-notifyid-ex7 skipped (runnableIn: reference)
Code:
GET /:app/topics.json/A?recursevia=children
example-rest-put-app-notifications-json-notifyid-ex8 skipped (runnableIn: reference)
Code:
GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"region":"US"}}
example-rest-put-app-notifications-json-notifyid-ex9 skipped (runnableIn: reference)
Code:
GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"region":{"$not":"US"}}}
example-rest-put-app-notifications-json-notifyid-ex10 skipped (runnableIn: reference)
Code:
GET /:app/topics.json/Acme%20Corp?via={"tag":"departments","with":{"region":{"$contains":"U"}}}
example-put-app-notifications-json-notifyid-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X PUT \
  'http://localhost:4342/PROSE_FIX_MOEK3D80/notifications.json/notif1' \
  -H 'Content-Type: application/json' \
  --data "{\"message\":\"hello subscribers\"}"
Output:
{
  "result": "success",
  "serverProcessingTime": 0,
  "cacheHitRate": 0.689280868385346,
  "cacheEvictionRate": 0,
  "cacheSize": 215,
  "cacheLimit": 1048576
}

PUT /:app/sessions.json restEndpoint

Create a new session (login).

Create a new session (login).

URL Parameters:

  • app - Application name (used for routing, actual app specified in body)

Request Body:


{
  "appIdOrName": "application name",
  "username": "user",
  "password": "pass"
}

Impersonation (admin/responsible users only):


{
  "appIdOrName": "application name",
  "username": "user to impersonate",
  "password": ""
}

Response:


{
  "result": "success",
  "version": 1,
  "data": {
    "sessionId": "guid-session-id",
    "appName": "application name",
    "appId": 1,
    "username": "user"
  }
}

Error Response:


{
  "result": "Authentication failed."
}

---

Users Endpoints

MethodPUT
Path/:app/sessions.json
Authtrue

Examples

example-rest-put-app-sessions-json-ex1 skipped (runnableIn: reference)
Code:
{
  "appIdOrName": "application name",
  "username": "user",
  "password": "pass"
}
example-rest-put-app-sessions-json-ex2 skipped (runnableIn: reference)
Code:
{
  "appIdOrName": "application name",
  "username": "user to impersonate",
  "password": ""
}
example-rest-put-app-sessions-json-ex3 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "version": 1,
  "data": {
    "sessionId": "guid-session-id",
    "appName": "application name",
    "appId": 1,
    "username": "user"
  }
}
example-put-app-sessions-json-real pass (runnableIn: shell)
Code:
curl -s \
  -X PUT \
  'http://localhost:4342/PROSE_LATE2_MOEKVZWH/sessions.json' \
  -H 'Content-Type: application/json' \
  --data '{"appIdOrName":"PROSE_LATE2_MOEKVZWH","username":"pfu","password":"pfp"}'
Output:
{
  "result": "success",
  "version": 1,
  "data": {
    "sessionId": "b34f61de-d071-46bc-9aa6-983b6236e4d1",
    "appName": "PROSE_LATE2_MOEKVZWH",
    "appId": 1,
    "username": "pfu"
  },
  "serverProcessingTime": 2,
  "cacheHitRate": 0.7266187050359713,
  "cacheEvictionRate": 0,
  "cacheSize": 63,
  "cacheLimit": 1048576
}

PUT /:app/topics.json restEndpoint

Create new topic(s) with tags and values.

Create new topic(s) with tags and values.

URL Parameters:

  • app - Application name

Query Parameters:

  • unique - If true, enforce uniqueness
  • allowDuplicateValues - If true, allow duplicate values

Request Body: Array of topic objects:


[
  {
    "text": "topic name",
    "tagName1": ["value1", "value2"],
    "tagName2": ["value3"]
  }
]

OR alternative format:


[
  {
    "topicText": "topic name",
    "tagText": "tag name",
    "valueText": "value"
  }
]

Response:


{
  "result": "success",
  "version": 1,
  "actions": {
    "add": {
      "data": [
        {
          "text": "topic name",
          "tags": [...]
        }
      ]
    }
  }
}

---

MethodPUT
Path/:app/topics.json
Authtrue

Examples

example-rest-put-app-topics-json-ex1 skipped (runnableIn: reference)
Code:
[
  {
    "text": "topic name",
    "tagName1": ["value1", "value2"],
    "tagName2": ["value3"]
  }
]
example-rest-put-app-topics-json-ex2 skipped (runnableIn: reference)
Code:
[
  {
    "topicText": "topic name",
    "tagText": "tag name",
    "valueText": "value"
  }
]
example-rest-put-app-topics-json-ex3 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "version": 1,
  "actions": {
    "add": {
      "data": [
        {
          "text": "topic name",
          "tags": [...]
        }
      ]
    }
  }
}
example-put-app-topics-json-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X PUT \
  'http://localhost:4342/PROSE_FIX_MOEK1HZR/topics.json' \
  -H 'Content-Type: application/json' \
  --data "[{\"text\":\"putExample\",\"tags\":[{\"text\":\"k\",\"values\":[{\"text\":\"v\"}]}]}]"
Output:
{
  "result": "success",
  "version": 1,
  "actions": {
    "add": {
      "data": [
        {
          "text": "putExample",
          "topicId": "01KQ2QK8BETZ3JMKBXDSYE49N8",
          "unique": false,
          "instance": 0,
          "cnt": 1,
          "creationTime": 1777134575981,
          "ts": 1777134575981,
          "tags": [
            {
              "tagId": "01KQ2QK8BETZ3JMKBXDSYE49N9",
              "text": "k",
              "tagType": "outbound",
              "topicId": "01KQ2QK8BF0H3NPYBHZYCRE93B",
              "parent": "01KQ2QK8BETZ3JMKBXDSYE49N8",
              "unique": false,
              "ts": 1777134575981,
              "owner": "pfu",
              "values": [
                {
                  "text": "v",
                  "valueId": "01KQ2QK8BETZ3JMKBXDSYE49NA",
                  "topicId": "01KQ2QK8BF0H3NPYBHZYCRE938",
                  "parent": "01KQ2QK8BETZ3JMKBXDSYE49N9",
                  "unique": false,
                  "ts": 1777134575981,
                  "owner": "pfu",
                  "acl": 0,
                  "cnt": 0,
                  "instance": 0,
                  "topicInstance": 0
                }
              ],
              "cnt": 1
            }
          ]
        }
      ]
    }
  },
  "serverProcessingTime": 6,
  "cacheHitRate": 0.36231884057971014,
  "cacheEvictionRate": 0,
  "cacheSize": 69,
  "cacheLimit": 1048576
}

PUT /:app/topics.json/:text restEndpoint

Add a tag/value to an existing topic by ID.

Add a tag/value to an existing topic by ID.

URL Parameters:

  • app - Application name
  • text - Numeric topic ID

Query Parameters:

  • unique - Enforce uniqueness
  • allowDuplicateValues - Allow duplicate values

Request Body:


{
  "tagText": "tag name",
  "valueText": "value text"
}

OR (to add just a value to an existing tag):


{
  "valueText": "value text"
}

Response:


{
  "result": "success",
  "actions": {
    "add": {
      "data": {
        "topics": [...]
      }
    }
  }
}

---

MethodPUT
Path/:app/topics.json/:text
Authtrue

Examples

example-rest-put-app-topics-json-text-ex1 skipped (runnableIn: reference)
Code:
{
  "tagText": "tag name",
  "valueText": "value text"
}
example-rest-put-app-topics-json-text-ex2 skipped (runnableIn: reference)
Code:
{
  "valueText": "value text"
}
example-rest-put-app-topics-json-text-ex3 skipped (runnableIn: reference)
Code:
{
  "result": "success",
  "actions": {
    "add": {
      "data": {
        "topics": [...]
      }
    }
  }
}
example-put-app-topics-json-text-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X PUT \
  'http://localhost:4342/PROSE_LATE_MOEKQDHB/topics.json/puttext' \
  -H 'Content-Type: application/json' \
  --data '{"tagText":"newtag","valueText":"newval"}'
Output:
Access denied

PUT /:app/users.json restEndpoint

Create a new user in an application.

Create a new user in an application.

Authorization: Requires responsible user of the app OR admin.

URL Parameters:

  • app - Application name (used for routing)

Request Body:


{
  "appName": "application name",
  "username": "newuser",
  "password": "password",
  "email": "[email protected]"
}

Response:


{
  "result": "success",
  "data": {
    "text": "user",
    "tags": [
      { "text": "appName", "values": [{ "text": "appname" }] },
      { "text": "username", "values": [{ "text": "newuser" }] },
      { "text": "userId", "values": [{ "text": "123" }] }
    ]
  }
}

---

MethodPUT
Path/:app/users.json
Authtrue

Examples

example-rest-put-app-users-json-ex1 skipped (runnableIn: reference)
Code:
{
  "appName": "application name",
  "username": "newuser",
  "password": "password",
  "email": "[email protected]"
}
example-put-app-users-json-real pass (runnableIn: shell)
Code:
curl -s \
  -u 'pfu:pfp' \
  -X PUT \
  'http://localhost:4342/PROSE_FIX_MOEK3D80/users.json' \
  -H 'Content-Type: application/json' \
  --data "{\"username\":\"newuser\",\"password\":\"newpass\",\"appName\":\"PROSE_FIX_MOEK3D80\"}"
Output:
{
  "result": "success",
  "data": {
    "text": "user",
    "tags": [
      {
        "text": "appName",
        "values": [
          {
            "text": "PROSE_FIX_MOEK3D80"
          }
        ]
      },
      {
        "text": "username",
        "values": [
          {
            "text": "newuser"
          }
        ]
      },
      {
        "text": "userId",
        "values": [
          {
            "text": "01KQ2QQQXV8BQYWA78ZG57GYHT"
          }
        ]
      }
    ]
  },
  "serverProcessingTime": 1,
  "cacheHitRate": 0.7126099706744868,
  "cacheEvictionRate": 0,
  "cacheSize": 215,
  "cacheLimit": 1048576
}