App runtime

This doc reflects only CloudWall API. To make apps work you also need jQuery.my API and, possibly, full system manifest list to reuse system components. To search this doc just press Ctrl-F or ⌘-F.  

this.app runtime obj

Object is available from inside of any app during its runtime. All init, bind, check, css, manifest and style functions can find runtime methods at this.app.

Property app is created in the manifest when you author it in Manifest Editor. When manifest is not yet initialized as ready-to-run application, app contains no methods — only application related properties — name, title, icon and so on.  They are marked with ❆ sign.

When manifest is prepared to be run as application, app object is extended with several methods, related to the particular app instance.

this.app {}

app.author ❄

App author name and id.

app.born

App start moment timestamp.

app.domid

HTML DOM unique id of app’s <div> container.

app.ico ❄

App icon as string containing dataURL of an image.

app.initurl

Start URL of an app instance.

app.maskstate ❄

Object or array, which is mask for reflecting app state to URL string. Application data field is masked using cw.lib.mask method with this mask. Result is encoded with cw.lib.tourl64 and reflected to URL hash.

It’s important to keep total length of state object less then 1500 bytes (browser limits the length of URL) — so do not reflect strings of uncontrolled length to appstate.

app.name ❄

Application name as reflected in URL hash.

app.nodetitle ❄

String mask for reflecting app state to browser tab’s title. References the property of app’s data, which must be observed time to time by system and put into tab title app app list right column.

app.nodecmd ❄

This property is set only if app is an editor. String mask that references the property of app’s data, which is filled with command, that editor must exec on document.

Possible list of commands that editor can exec over this or that doc types is set when you author an app with Manifest Editor.

Again: it is not the command by itself, it’s the dot-reference of property, where app can find command it was called with, during runtime.

app.nodedoc ❄

This property is set only if app is an editor. String mask that references the branch of app’s data, which is filled with document, that editor must process.

Before editor starts, system loads document that editor must process. It must be mounted somewhere on the app internal data tree. this.app.nodedoc references the node, where this particular app assumes to find doc to edit.

app.state

Current encoded app state as you see in the browser URL string after last slash.

app.timeout ❄

App max timeframe to start, in milliseconds. If app’s promise didn’t resolved during timeframe, app start is aborted and app is killed.

app.title ❄

Application title as it is shown in doc lists and start menu.

app.updated

Timestamp system last checked if app state was updated.

app.url

Current full app url.

app.width ❄

Array of suitable widths of an app container. System choose one when starts or layouts application to fit app and side panes into screen area.

// End of this.app properties

app.busy( bool )

Makes app busy or ready for interaction. ‘Busy’ is not more then semi-transparent overlay in front of app’s <div>. It prevents app from interaction with user, but have no other impact on app runtime.

app.close( next, force ) ⚑

Closes app. Param next is url to open next. force boolean commands to make no check if doc being edited is unsaved.

Returns Promise. Resolved with app data when app successfully closed, or rejected with reason if app termination failed.

app.isActive(), app.isEditor()

Return if app is active and if app is an editor.

app.layout()

Forces system to rearrange panels and app layout.

app.local( key, val )

Puts or gets key/value in localStorage. val can be object, string or whatever that can be converted to json (no functions and regexps). 

If val is undefined last saved value is returned. If val is null key is removed from storage and its last value returned.

Storages for each app manifest are independent, but all instances of one app manifest running from any DB see one bundle of keys. Feature is useful for storing trigger-like app states like is app started first time or did user accepted terms.

app.modal( arg, width ) ⚑

Popups modal dialog. If no arg or true passed, closes opened modal and rejects its promise. To open modal argument must be a string, an object or jQuery object with image.

String passed. String is assumed to valid HTML and is rendered in modal. Second arg, passed sets default width of a container, HTML rendered in.

jQuery image passed. Opens modal with image, good for viewing full versions of previews. Width restricts modal width, default is 820.

Object passed. In this case modal is initialized with jQuery.my form. If form fails to init, modal promise is rejected immediately. Modal with form inside is called in this way:

Manifest can be an object with $.my manifest or string pointer to named manifest. Next example will open standard confirm dialog with ‘Proceed’ text on Ok button.

To close modal, the manifest running inside must trigger commit event to resolve modal’s promise with form data, or trigger cancel event to reject promise. Event can be triggered on any DOM element inside the form — it bubbles.

app.run( url )

Starts other app by URL.

app.watch ⚐

Object that is EventEmitter, which is notified when app goes active, inactive or is sentenced to close.

this.db runtime obj

Object is available from inside of any app during its runtime. All init, bind, check, css, manifest and style functions can find runtime db methods at this.db.

Most of them are very similar to global cw.db() methods with slight differences, related to app runtime mode. Methods, that have no cw.db() prototype or behave different, are marked with ⁙ sign.

cw.db() proxies

Read more in cw.db section.

this.db.actions( type )

Returns object, that represents doctype to doc action to app mapping. Called without arguments returns all type to app mapping tree.

this.db.app( appName )

Finds application manifest by app name. Searches first in DB appcache, then in appcache of system DB, then in system cache.

this.db.del( docid ) ⚑

Deletes doc by docid.

this.db.find ( filter ) ⚑

Finds and caches docs using filter function. Promise resolved with array of docs. Very slow in Chrome and Opera.

this.db.form( manId )

Returns manifest by qualified component id like cw.Post.Editor.Cropper. This method is just proxy to cw.form().

this.db.hide( docId )

Marks doc as hidden. It means doc won’t be deleted from DB, but become nearly invisible for apps — excluded from queries results, doc lists and so on.

this.db.inram( docId )

Checks if doc was cached in RAM. Returns true if doc was loaded. See db.ram for more details.

this.db.isread( docId )

Checks if cached doc was read (opened) in current revision. See db.markread and db.hide.

this.db.markread( docId )

Marks cached document as read in current revision. 

this.db.name

String, DB id.

this.db.settings( arg ) ⚑

Promise only if arg provided, else immediately returns settings object for DB. This object contains info about DB creator and birth stamp, sync urls, apps pinned and so on.

Replication URLs are returned with passwords sealed.

this.db.query( func ) ⚐

Queries DB with CouchDB-style map function. Promise is resolved with an array of results — which is also in CouchDB style. Results are not cached in RAM by system. Quite slow in Chrome and Opera.

this.db.sync( arg )

If no arg provided, returns current status of replication (true or false). If boolean provided as arg, starts or stops DB replication.

this.db.users()

Returns DB users list in format {"user-userid":"userPicBase64dataURL",...}.

this.db.uuid()

Returns stamp-based new doc uuid.

this.db.att( docid ) ⁙

Return Att object if doc was already cached. Att object has 5 members:

Function name is dataimageurl or  blob. Result is _attachment object, augmented with data in appropriate format, and data itself.

Format of data returned depends on function name.
 .data returns base64 data ⚑,
 .image — base64 with prefix data:mime/type;base64,... attached ⚑,
 .url — dataURL, temporary session string reference to resource ⚑.
 .blob returns native DB format — binary Blob object ⚑.

⚒ Unlike global prototype contains counter and frees resource when all apps using resource are closed.

this.db.load( args ) ⚑ ⁙

Loads doc or docs and caches them. All necessary events are raised and watchers notified. There are several possible combinations of arguments and their types:

Promise is rejected on error with (errorMessage as String, errorObj as Object).

⚒ Unlike global cw.db().load() method, app runtime load marks app-caller as busy, if operation takes more than 200ms.

this.db.save( doc ) ⚑ ⁙

Saves (creates) doc. To create doc just save it without _rev, and, possibly, _id properties. If conflict occurs during save, modal for user intervention is shown. 

Promise is resolved with new doc, which is immediately reloaded after save and cached. 

If doc to save has no name or type fields, or is pre-encrypted (has CRYPTO  property) promise is rejected. 

⚒ Unlike global cw.db().save() method, app runtime decrypts saved docs, if they were encrypted. If doc to save has field crypto with valid keyId, doc is encrypted with the key before save. In this case promise is resolved with decrypted doc, but cache and DB store encrypted one.

⚒ App runtime marks app as busy while save takes place, if operation takes more than 200ms.

⚒ If doc we save is one opened in editor (not just doc, but active doc you edit), system generates new snapshot footprint to track if doc changes later. 

this.db.ram( arg )

Queries RAM cache. Argument can be _id, array of _ids or filter function. Method is not a promise and returns array of results immediately.

this.db.watch() ⚐⁙

Returns EventEmitter instance, which raises progress event when doc(s) of docType were just changed. If no docType provided, watcher called on any doc change.

Event listener receives a list of changed docs if app is active (visible), or on app activation. If app is inactive, doc list is stashed to deliver entire pile later when app gets focus.

This allows postponed redraw of inactive apps.  

this.files object

Manifest may have attached resources — which are just file attachments to DB doc. These resources are loaded in RAM when app starts first time and persist in RAM until last app instance close.

App instance can access these resources using this.files object, which resembles a lot standard CouchDB _attachments doc property.

Standard attachments object are extended with two properties — url and blob

url contains string with session URL of resource. It looks a little weird, like blob:http%3A//cloudwall.me/e8b3806a-92fa38218fbc, but can be put to src attribute of <img> for example — and image is shown. URLs of this type are suitable for ajax requests as ‘classic’ URLs. Main difference — requests to files in memory are blazing fast.

Read more about URL Object on MDN. 

blob contains Blob object with byte array of a resource file. It can be read in any suitable format.

Debugging

To enter Debug mode just press Tab key after PIN on start. Console now is full of messages.

$0 commands

Main consideration that might be used during debug is that any app has DOM shortcut. You can see an app state using simple console commands.  

var $app = $(".cw-app-active") gets DOM node of current active slot. This node has several data nodes and methods attached.

$app.data("app")

Returns ‘live’ slot object. It has several properties, most important are app and db — application runtimes.

$app.data("my")

Returns jQuery.my runtime. Runtime has several useful fields, for example $app.data("my").initial returns copy of data as they were when application started.

$app.my("data", obj)

If second argument is null, returns ‘live’ data object of active app. If second argument is object, it is superimposed over app data and app is redrawn.

Note: not the same as $app.data("my")!

$app.my("errors")

Returns snapshot of current app error state. If everything is ok, returns {} object, otherwise returns hierarchy of invalid controls’ DOM selectors. 

$app.my("valid") 

Returns boolean if app is in valid state.

$app.my("manifest")

Returns ‘live’ manifest object of active app.

$app.my("redraw")

Forces manifest to redraw. 

$app.my("ui", obj)

If second argument is null, returns ‘live’ unfolded and extended runtime ui object of active app manifest. If second argument is object, it is superimposed over manifest and app is redrawn.

Augmenting app during runtime is quiet tricky operation, it can damage or kill app, it’s like neurosurgery.