README.md 10.8 KB
Newer Older
Tristan Cavelier's avatar
Tristan Cavelier committed
1
## Javascript Input/Output
Tristan Cavelier's avatar
Tristan Cavelier committed
2 3 4 5

**jIO is a client-side JavaScript library to manage documents across multiple
  storages.**

Tristan Cavelier's avatar
Tristan Cavelier committed
6
### Getting Started
Tristan Cavelier's avatar
Tristan Cavelier committed
7

8
To set up jIO you should include jio.js, dependencies and the connectors for the storages
9
you want to use in the HTML page header (note that more dependencies may be required
Tristan Cavelier's avatar
Tristan Cavelier committed
10 11
depending on type of storages being used):

12 13 14 15 16
```html
<!-- jio + dependency -->
<script src="sha256.amd.js"></script>
<script src="rsvp-custom.js"></script>
<script src="jio.js"></script>
Tristan Cavelier's avatar
Tristan Cavelier committed
17

18 19
<!-- jio storage libraries -->
<script src="localstorage.js"></script>
Tristan Cavelier's avatar
Tristan Cavelier committed
20

21 22
<script ...>
```
Tristan Cavelier's avatar
Tristan Cavelier committed
23

24
Then create your jIO instance like this:
Tristan Cavelier's avatar
Tristan Cavelier committed
25

26 27 28 29 30 31 32 33
```javascript
// create a new jio (type = localStorage)
var jio_instance = jIO.createJIO({
  "type": "local",
  "username": "your_username",
  "application_name": "your_application_name"
});
```
Tristan Cavelier's avatar
Tristan Cavelier committed
34

Tristan Cavelier's avatar
Tristan Cavelier committed
35
### Documents and Methods
Tristan Cavelier's avatar
Tristan Cavelier committed
36

37
Documents are JSON strings that contain *metadata* (properties, like a filename)
Tristan Cavelier's avatar
Tristan Cavelier committed
38
and *attachments* (optional content, for example *image.jpg*).
Tristan Cavelier's avatar
Tristan Cavelier committed
39

Tristan Cavelier's avatar
Tristan Cavelier committed
40
jIO exposes the following methods to *create*, *read*, *update* and *delete* documents
Tristan Cavelier's avatar
Tristan Cavelier committed
41 42 43
(for more information, including revision management and available options for
each method, please refer to the documentation):

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
```javascript
// create and store new document
jio_instance.post({"title": "some title"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "result": "success",
    //   "id": "404aef5e-22cc-4a64-a292-37776c6464a3" // Generated id
    //   ...
    // }
  });

// create or update an existing document
jio_instance.put({"_id": "my_document", "title": "New Title"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "result": "success",
    //   "id": "my_document",
    //   ...
    // }
  });

// add an attachement to a document
jio_instance.putAttachment({"_id": "my_document", "_attachment": "its_attachment",
                            "_data": "abc", "_mimetype": "text/plain"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "result": "success",
    //   "id": "my_document",
    //   "attachment": "its_attachment"
    //   ...
    // }
  });

// read a document
jio_instance.get({"_id": "my_document"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "data": {
    //     "_id": "my_document",
    //     "title": "New Title",
    //     "_attachments": {
    //       "its_attachment": {
    //         "length": 3,
    //         "digest": "sha256-ba7816bf8f1cfea414140de5dae2223b0361a396177a9cb410ff61f2015ad",
    //         "content_type": "text/plain"
    //       }
    //     }
    //   },
    //   ...
    // }
  });

// read an attachement
jio_instance.getAttachment({"_id": "my_document", "_attachment": "its_attachment"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "data": Blob, // contains the attachment data + content type
    //   ...
    // }
  });

// delete a document and its attachment(s)
jio_instance.remove({"_id": "my_document"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "result": "success",
    //   "id": "my_document"
    // }
  });

// delete an attachement
jio_instance.removeAttachment({"_id": "my_document", "_attachment": "its_attachment"}).
  then(function (response) {
    // console.log(response);
    // {
    //   "result": "success",
    //   "id": "my_document",
    //   "attachment": "its_attachment"
    // }
  });

// get all documents
jio_instance.allDocs().then(function (response) {
  // console.log(response);
  // {
  //   "data": {
  //     "total_rows": 1,
  //     "rows": [{
  //       "id": "my_document",
  //       "value": {}
  //     }]
  //   }
  // }
});
```
Tristan Cavelier's avatar
Tristan Cavelier committed
145

Tristan Cavelier's avatar
Tristan Cavelier committed
146

Tristan Cavelier's avatar
Tristan Cavelier committed
147
### Example
Tristan Cavelier's avatar
Tristan Cavelier committed
148 149

This is an example of how to store a video file with one attachment in local
Tristan Cavelier's avatar
Tristan Cavelier committed
150
storage. Note that attachments should be added after document creation.
Tristan Cavelier's avatar
Tristan Cavelier committed
151

152 153 154 155 156 157 158
```javascript
// create a new localStorage
var jio_instance = jIO.createJIO({
  "type": "local",
  "username": "user",
  "application_name": "app"
});
Tristan Cavelier's avatar
Tristan Cavelier committed
159

160 161 162
var my_video_blob = new Blob([my_video_binary_string], {
  "type": "video/ogg"
});
Tristan Cavelier's avatar
Tristan Cavelier committed
163

164 165 166 167 168 169 170 171
// post the document
jio_instance.post({
  "_id"         : "myVideo",
  "title"       : "My Video",
  "format"      : ["video/ogg", "vorbis", "HD"],
  "language"    : "en",
  "description" : "Images Compilation"
}).then(function (response) {
Tristan Cavelier's avatar
Tristan Cavelier committed
172

173 174 175 176 177 178
  // add video attachment
  return jio_instance.putAttachment({
    "_id": "myVideo",
    "_attachment": "video.ogv",
    "_data": my_video_blob,
  });
Tristan Cavelier's avatar
Tristan Cavelier committed
179

180
}).then(function (response) {
Tristan Cavelier's avatar
Tristan Cavelier committed
181

182
  alert('Video Stored');
Tristan Cavelier's avatar
Tristan Cavelier committed
183

184
}, function (err) {
Tristan Cavelier's avatar
Tristan Cavelier committed
185

186 187 188 189 190
  if (err.method === "post") {
    alert('Error when posting the document description');
  } else {
    alert('Error when attaching the video');
  }
Tristan Cavelier's avatar
Tristan Cavelier committed
191

192
}, function (progression) {
Tristan Cavelier's avatar
Tristan Cavelier committed
193

194
  console.log(progression);
Tristan Cavelier's avatar
Tristan Cavelier committed
195

196 197
});
```
Tristan Cavelier's avatar
Tristan Cavelier committed
198

Tristan Cavelier's avatar
Tristan Cavelier committed
199
### Storage Locations
Tristan Cavelier's avatar
Tristan Cavelier committed
200 201 202 203 204 205 206

jIO allows to build "storage trees" consisting of connectors to multiple
storages (webDav, xWiki, S3, localStorage) and use type-storages to add features
like revision management or indices to a child storage (sub_storage).

The following storages are currently supported:

Tristan Cavelier's avatar
Tristan Cavelier committed
207
- LocalStorage (browser local storage)
Tristan Cavelier's avatar
Tristan Cavelier committed
208

209 210 211 212 213 214 215
```javascript
// initialize a local storage
var jio_instance = jIO.createJIO({
  "type" : "local",
  "username" : "me"
});
```
Tristan Cavelier's avatar
Tristan Cavelier committed
216

Tristan Cavelier's avatar
Tristan Cavelier committed
217 218
- DAVStorage (connect to webDAV, more information on the
  [documentation](https://www.j-io.org/documentation/jio-documentation/))
Tristan Cavelier's avatar
Tristan Cavelier committed
219

220 221 222 223 224 225 226
```javascript
// initialize a webDAV storage (without authentication)
var jio_instance = jIO.createJIO({
  "type": "dav",
  "url": "http://my.dav.srv/uploads"
});
```
Tristan Cavelier's avatar
Tristan Cavelier committed
227

Tristan Cavelier's avatar
Tristan Cavelier committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
<!-- - xWiki storage (connect to xWiki) -->

<!--         // initialize a connection to xWiki -->
<!--         var jio_instance = jIO.createJIO({ -->
<!--           "type": "xwiki", -->
<!--           "xwikiurl": "http://my.site.com/xwiki", -->
<!--           "username": "me", -->
<!--           "password": "pwd" -->
<!--         }); -->

<!-- - S3 storage (connect to S3) -->

<!--         // initialize a connection to S3 storage -->
<!--         var jio_instance = jIO.createJIO({ -->
<!--           "type": "s3", -->
<!--           "AWSIdentifier": "AWS Identifier ID", -->
<!--           "password": "AWS Secret key", -->
<!--           "server": "Destination bucket" -->
<!--         }); -->

<!-- - IndexStorage (maintains indices of documents in a substorage) -->

<!--         // initialize an indexStorage (for a local storage) -->
<!--         var jio_instance = jIO.createJIO({ -->
<!--           "type": "indexed", -->
<!--           "sub_storage": { -->
<!--             "type": "local" // for instance -->
<!--             "username": "me" -->
<!--           }, -->
<!--           "indices": [{ -->
<!--             "id": "index_database.json", -->
<!--             "index": ["title", "author", "subject", "posted_date"] -->
<!--           }] -->
<!--         }); -->

<!-- - SplitStorage (simply split data into several parts): -->

<!--         // initialize a splitStorage -->
<!--         var jio_instance = jIO.createJIO({ -->
<!--           "type": "split", -->
<!--           "storage_list": [<storage description>, ...] -->
<!--         }); -->

<!-- - Revision Storage (add revision management to a substorage) -->

<!--         // initialize a revison storage on a local storage -->
<!--         // (revision-format 1-9ccd039de0674d935f3c6bae61afc9b7038d1df97d586507aa62336a02f9ee2a) -->
<!--         var jio_instance = jIO.createJIO({ -->
<!--           "type": "revision", -->
<!--           "sub_storage": { -->
<!--             "type": "local", -->
<!--             "username": "me" -->
<!--           } -->
<!--         }); -->

<!-- - Replicate Revision Storage (replicate documents across multiple storages) -->

<!--         // initialize a replicate revision storage (with local and webDAV as substorages) -->
<!--         var jio_instance = jIO.createJIO({ -->
<!--           "type": "replicaterevision", -->
<!--           "storage_list": [{ -->
<!--             "type": "revision", -->
<!--             "sub_storage": { -->
<!--               "type": "local", -->
<!--               "username": "me" -->
<!--             } -->
<!--            }, { -->
<!--             "type": "revision", -->
<!--             "sub_storage": { -->
<!--               "type" : "dav", -->
<!--               "auth_type": "basic", -->
<!--               "username" : "me", -->
<!--               "password" : "pwd", -->
<!--               "url" : "http://my.dav.srv/uploads" -->
<!--             } -->
<!--           }] -->
<!--         }); -->

- [And more!](https://www.j-io.org/documentation/jio-documentation#List of Available Storages)
Tristan Cavelier's avatar
Tristan Cavelier committed
307 308

For more information on the specific storages including guidelines on how to
Tristan Cavelier's avatar
Tristan Cavelier committed
309
create your own connector, please also refer to the [documentation](https://www.j-io.org/documentation/jio-documentation).
Tristan Cavelier's avatar
Tristan Cavelier committed
310

Tristan Cavelier's avatar
Tristan Cavelier committed
311
### jIO Query
Tristan Cavelier's avatar
Tristan Cavelier committed
312

Tristan Cavelier's avatar
Tristan Cavelier committed
313 314 315 316
jIO can use queries, which can be run in the allDocs() method to query document
lists. A sample query would look like this (note that not all storages support
allDocs and jio queries, and that pre-querying of documents on distant storages
should best be done server-side):
Tristan Cavelier's avatar
Tristan Cavelier committed
317

318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
```javascript
// run allDocs with query option on an existing jIO
jio_instance.allDocs({
  "query": '(fieldX: >= "string" AND fieldY: < "string")',
  // records to display ("from to")
  "limit": [0, 5],
  // sort by
  "sort_on": [[<string A>, 'descending']],
  // fields to return in response
  "select_list": [<string A>, <string B>]
}).then(function (response) {
  // console.log(response);
  // {
  //   "total_rows": 1,
  //   "rows": [{
  //     "id": <string>,
  //     "value": {
  //       <string A>: <string>,
  //       <string B>: <string>
  //     }
  //   }, { .. }]
  // }
});
```
Tristan Cavelier's avatar
Tristan Cavelier committed
342

Tristan Cavelier's avatar
Tristan Cavelier committed
343
To find out more about queries, please refer to the documentation.
Tristan Cavelier's avatar
Tristan Cavelier committed
344 345 346 347

### Task Management

jIO is running a task queue manager in the background which processes incoming
348
tasks according to a set of defined rules. To find out more including how to
Tristan Cavelier's avatar
Tristan Cavelier committed
349
define your own execution rules, please refer to the documentation.
Tristan Cavelier's avatar
Tristan Cavelier committed
350 351 352

### Conflict Management

353 354
As jIO allows to manage and share documents across multiple storage locactions,
conflicts may happen (i.e. multiple versions of a single document
Tristan Cavelier's avatar
Tristan Cavelier committed
355 356
existing in the storage tree). jIO manages conflicts by ensuring that every
version of a document is available on every storage and that conflicts are
Tristan Cavelier's avatar
Tristan Cavelier committed
357
accessible (and solvable) using the *conflicts: true* option when using the
358
related jIO methods. For more info on conflicts and available options, please
Tristan Cavelier's avatar
Tristan Cavelier committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
refer to the documentation.

### Crash-Proof

All tasks are managed inside the browser local storage so no data is lost, as
the task manager queue will persist through browser crashes and continues to run
when the page is reloaded after a browser crash.

### Authors

- Francois Billioud
- Tristan Cavelier
- Sven Franck

### Copyright and license

jIO is an open-source library and is licensed under the LGPL license. More
Tristan Cavelier's avatar
Tristan Cavelier committed
376 377
information on LGPL can be found
[here](http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License).