Ddoc Lab

Ddoc Lab is highly specialized IDE for building CouchDB design documents and ordinary docs. Ddoc Lab provides extensive import, include, edit and export capabilities for JSON docs of any structure, especially for CouchDB design docs.

Each Ddoc Lab project is a single JSON document of type:"ddlab", containing all parts of a resulting JSON doc, and all necessary meta to build it. 

Ddoc Lab is comfortable for both authoring/editing source code and building a target from externally imported sources.

Project settings

Ddoc Lab project settings dialog

Ddoc Lab project settings dialog

Ddoc Lab blank-starts with an empty untitled project. Red button  in the app UI opens project settings modal.

If you are going to export your doc, provide CouchDB bucket URL and doc name. If you defined Couch bucket as a full URL, you can try to import existing ddoc, if any.

You can also provide login and password for a remote Couch, and select a CloudWall encryption key, to keep credentials protected.

You should choose whether export replaces or extends an existing target doc. Merging is useful when you build a single ddoc from two or more Doc Lab projects.

JSON branches and files

Branch is a piece of target JSON doc with a reference, pointing to exact place where in the build a branch should land. Resulting CouchDB document is a JSON, consisting of regular nodes and, optionally, file attachments.

Left column is a list of branches, to add more branches use links at the bottom of the column.

Central part is code editor, with tabs above.

Top bar is for actions.

to Couch  button builds and exports project as a CouchDB doc.

JSON  builds and shows the result document as a json text. 

Files as .tar generates tar with all attachments, json branches are dropped.

Rebuild resolves all external sources and tries to build the project. Possible errors are shown in a popup.

Basically, Ddoc Lab manages a set of named branches and glues them into a single JSON during build process. Supported branch types are:

Each branch may become a JSON part or a file attachment, difference is only in naming. A branch named .views.test.map will become JSON fragment, but same branch renamed into /assets/map.js will build into file attachment. 

Branch settings

Branch settings dialog

Branch settings dialog

Button at the top right of the code editor opens branch settings dialog. For most of types it looks more or less same, however there are some contextual differences.

Branch type is fixed at the moment of creation and can not be changed later. Branch type is shown in the dialog header and defines behavior of code editor and validator.

Branch id. At the right side of branch type there is light-gray full node identifier, used for external linking. Copy-pasting it into another proj‘s branch, Linked to field, will import current branch to another project.

Branch name, which is also mount path, defines where the branch should be placed inside target doc, if the branch isn’t a so called ‘fragment’. For fragments branch name is only used for referencing and navigation.

Mime type is only applicable to attachments, and sets content_type property of an _attachment object member. Changing mime does not change branch type and editor behavior.

Linked to field defines external source, from where data should be retrieved. See more in ‘External resources inclusion section’.

Fragment mode builds a branch, but does not put it into a result json doc. Fragments are used for inlining into other branches.

Skip includes disables parsing and expanding of include tokens. See section ’Code inlining‘ for more details.

Additional parser control enables custom post-processor. If option is on, the editor control panel at right top has >_ additional button, that switches editor between data and post-processor code. Post-processor is a javascript function, taking branch content with resolved includes as an argument, and returning new content instead.

Result is a binary string control indicates, that result should be processed as a binary, not as a text. Allows creating blobs from strings, ie render text to png and store it as an attachment.

Stash result as a .resolved item property enforces Ddoc Lab to store a result of full resolution of a particular branch. Replacing .data tail to .resolved in Branch id will import resolved branch.

There are several additional type-specific options, they are mostly about compression and are quiet obvious.

Code inlining

Example of real inlining in view, working to show this page. Highlighted parts are substituted.

Example of real inlining in view, working to show this page. Highlighted parts are substituted.

The idea is taken from C #include directive. Specially formatted include tokens are expanded by preprocessor into real content each token points to.

For example, if you have a branch /js/myfunction.js, the token {{/js/myfunction.js}} in any other branch’s source expands into full text of myfunction.js on build.

The feature is extremely useful for gluing snippets of reused code for environments, that better not use require(), ie views.

Inlining is useful for building bundles of libs or data of any sort. Custom post-processor may even turn bundle into binary format, ie tarball or pdf.

Ddoc Lab controls dependencies and knows all dependent members for any branch. Unresolvable dependencies break build process. Button at the top right panel of a code editor shows popup with all dependencies and impacts.

External resources inclusion

Ddoc Lab can take branch code from external source. Available sources are local documents, external http requests and queries to local DB. To retrieve external source and put result in a project as a branch source, open Settings dialog and provide a path into Linked to field.

Available path formats are:

  • http:/​/any.path retrieves a resource.
  • local://doc_id reads a doc from current local DB and, optionally, gets specified node.
  • doc://dbName/doc_id reads a doc from another, non-current, local DB.
  • query://ddoc/viewName {params} queries local DB. Available params are basically PouchDB query options.

If result is a JSON, syntax doc://someDocId node.in.the.doc (space separated) selects particular node of an imported doc. Also works with http requests.

Custom post-processors

Every non-blob branch may have an individual custom post-processor, which is enabled by turning on Additional parser option of a branch. Editor top right panel button  switches between branch source and post-processor code.

Post-processor code is a sync javascript function, that receives branch object, and must return a string, which is, possibly, parsed to a destination format and applied to a resulting JSON. 

Post-processor function also ‘sees’ entire app runtime through this object. For example, full list of branches is available as this.data.doc.items array. 

Post-processor editor has button, allowing to run a function instantly and see the result, or error message.

Build and publish

Build and publish stages are separate, because there can exist docs that build, but are not intended to be published. Good example is a set of libs, that changes rarely and intended to be included into other ddoc.

Build phase

During a build, Ddoc Lab fetches all external links, preprocesses each branch resolving include directives, post-processes branches, resolves includes again and then mounts all branches into the resulting JSON.

Publishing phase

Export to Couch may run only after successful build. For publishing new build Ddoc Lab first loads target doc, if any.

If the current project settings enforce target doc full replacement, newly built JSON is saved exactly as it was built.

If settings allow merge, newly built JSON only overlays existing, keeping branches and attaches, unrelated to current project, intact.