Files
dolt/doc/js-tour.md
Erik Arvidsson e90bfcbd2a Switch to Yarn (#3092)
brew install yarn
2017-01-20 11:42:32 -08:00

4.1 KiB

A Short Tour of Noms for JavaScript

This is a short introduction to using Noms from JavaScript. It should only take a few minutes if you have some familiarity with JavaScript and Node.

During the tour, you can refer to the complete JavaScript SDK Reference for more information on anything you see.

Requirements

Start a Local Database

Let's create a local database to play with:

noms serve /tmp/noms-js-tour

Install Noms NPM Package

Leave the server running, and in a separate terminal:

mkdir noms-tour
cd noms-tour
echo '{"name":"noms-tour","version":"0.0.1"}' > package.json
yarn add @attic/noms

Then launch Node so that we can have a play:

node

Database

To get started with Noms, first create a Database:

const noms = require('@attic/noms');

const db = noms.DatabaseSpec.parse('http://localhost:8000').database();

See Spelling in Noms for more information on database spec strings.

Dataset

Datasets are the main interface you'll use to work with Noms. A dataset is just a named value in the database that you can update:

let ds = db.getDataset('people');

// prints: null
ds.head().then(console.log);

let data = new noms.List([
  noms.newStruct('', {
  	given: 'Rickon',
  	male: true,
  }),
  noms.newStruct('', {
  	given: 'Bran',
  	male: true,
  }),
  noms.newStruct('', {
  	given: 'Arya',
  	male: false,
  }),
  noms.newStruct('', {
  	given: 'Sansa',
  	male: false,
  }),
]);

// prints:
// List<struct  {
//   given: String
//   male: Bool
// }>
console.log(data.type.describe());

db.commit(ds, data).
  then(r => ds = r);

Now we can explore the data:

// prints: Rickon
ds.head().
  then(commit => commit.value.get(0)).
  then(v => console.log(v.given));

You can also see this on the command-line. In a new (third) terminal:

> noms ds http://localhost:8000
people

> noms show http://localhost:8000::people
struct Commit {
  parents: Set<Ref<Cycle<0>>>
  value: Value
}({
  parents: {},
  value: [
     {
      given: "Rickon",
      male: true,
    },
...

Let's add some more data. Back in Node:

data.append(noms.newStruct('', {
  given: 'Jon',
  family: 'Snow',
  male: true,
})).then(d => data = d);

// prints:
// List<struct  {
//   family: String
//   given: String
//   male: Bool
// } | struct  {
//   given: String
//   male: Bool
// }>
console.log(data.type.describe());

db.commit(ds, data).
  then(r => ds = r);

Datasets are versioned. When you commit a new value, you aren't overwriting the old value, but adding to a historical log of values.

function printCommit(commit) {
  console.log('list', commit.value.hash.toString(),
      'length:', commit.value.length);
  if (commit.parents.isEmpty()) {
    return;
  }
  commit.parents.first().
    then(r => r.targetValue(db)).
    then(printCommit);
}

// Prints:
// list sha1-eba46d10a2d1d10eb9f115c7b8df8c45653b430e length: 5
// list sha1-9cf762c697b10a2868957b6c4ea30de36608ac08 length: 4
ds.head().then(printCommit);

Values

Noms supports a variety of datatypes. The following table summarizes the JavaScript datatype(s) used to represent each Noms datatype.

Noms Type JavaScript Type
Boolean boolean
Number number
String string
Blob noms.Blob
Set noms.Set
List noms.List
Map noms.Map
Ref noms.Ref
Struct noms.Struct

In most cases, the Noms JavaScript library will automatically convert between JavaScript types and Noms types. For example:

// Writes a noms value of type:
// Struct<foo: String, num: Number, list: List<String|Number>>
store.writeValue(newStruct('', {
  foo: "bar",
  num: 42,
  list: new List("a", "b", 4, 8),
}));

Sometimes it's nice to explicitly control the type. You can do that by calling new Struct directy and passing a Type for the first parameter.