Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Autonomous Web Applications with Ember.js and Orbit.js

Autonomous Web Applications with Ember.js and Orbit.js

Introduction to Orbit.js and the integration library Ember-Orbit. Presented at Wicked Good Ember 2014.

Dan Gebhardt

June 17, 2014
Tweet

More Decks by Dan Gebhardt

Other Decks in Programming

Transcript

  1. Dan Gebhardt

    @dgeb
    Wicked Good Ember 2014
    AUTONOMOUS
    WEB APPLICATIONS

    WITH

    View Slide

  2. Dan Gebhardt

    @dgeb
    Wicked Good Ember 2014
    AUTONOMOUS
    WEB APPLICATIONS

    WITH

    View Slide

  3. View Slide

  4. WHAT'S NEXT
    FOR AMBITIOUS
    WEB APPLICATIONS?

    View Slide

  5. AUTONOMY

    View Slide

  6. AUTONOMY ?

    View Slide

  7. AUTONOMY?

    View Slide

  8. AUTONOMY

    View Slide

  9. OFFLINE SUPPORT

    View Slide

  10. NON-BLOCKING INTERFACES

    View Slide

  11. DATA SYNCHRONIZATION

    View Slide

  12. TRANSACTIONAL CONTEXTS

    View Slide

  13. UNDO / REDO

    View Slide

  14. View Slide

  15. PLAIN OLE’
    ==

    View Slide

  16. PRIMITIVES
    { }
    EVENTS

    View Slide

  17. PRIMITIVES
    { }
    EVENTS

    View Slide

  18. PRIMITIVES
    { }
    EVENTS
    TRANSFORMS

    View Slide

  19. SYNCHRONOUS
    EVENT HANDLING
    1
    2
    3
    4
    5
    6

    View Slide

  20. 1
    2
    3
    4
    5
    6
    7
    ???
    P
    P = Promise
    SYNCHRONOUS
    EVENT HANDLING

    View Slide

  21. PROMISE-AWARE
    EVENTS
    1
    2
    3
    4
    5
    6
    7
    8
    P
    P
    P
    P
    P = Promise
    Async Blocking

    View Slide

  22. PROMISE-AWARE
    EVENTS
    1
    2
    3
    ???
    4
    5
    6
    7
    P = Promise
    P
    P
    Async Non-Blocking

    View Slide

  23. PRIMARY INTERFACES
    { }
    REQUESTABLE
    TRANSFORMABLE

    View Slide

  24. REQUESTABLE
    find
    add
    remove
    update
    patch
    findLink
    addLink
    removeLink

    View Slide

  25. TRANSFORMABLE
    transform(operation)

    View Slide

  26. REQUEST FLOW
    << assistFind >>!
    _find()!
    << rescueFind >>!
    << didFind /didNotFind >>
    source.find(“planet”, “1”)

    View Slide

  27. REQUEST FLOW
    << assistFind >>!
    _find()!
    << rescueFind >>!
    << didFind /didNotFind >>
    source.find(“planet”, “1”)

    View Slide

  28. REQUEST FLOW
    << assistFind >>!
    _find()!
    << rescueFind >>!
    << didFind /didNotFind >>
    source.find(“planet”, “1”)

    View Slide

  29. REQUEST FLOW
    source.find(“planet”, “1”)
    << assistFind >>!
    _find()!
    << rescueFind >>!
    << didFind /didNotFind >>

    View Slide

  30. TRANSFORM FLOW
    source.transform(op)
    _transform()!
    << didTransform >>

    View Slide

  31. TRANSFORM FLOW
    source.transform(op)
    _transform()!
    << didTransform >>

    View Slide

  32. Orbit.Document
    Complete implementation of

    JSON Patch (RFC 6902):
    { }
    add
    remove
    replace
    move
    copy
    test
    ————
    transform
    retrieve

    View Slide

  33. TRANSFORMATIONS
    JSON Patch transformations:
    {"op":"remove","path":["planet","1389295329110.3"]}!
    {"op":"add","path":["planet","1389295895882.1"],"value":
    {"name":"Mercury","id":"1389295895882.1"}}!
    {"op":"remove","path":["planet","1389295895882.1"]}!
    {"op":"add","path":["planet","1389296188090.2"],"value":
    {"name":"Mercury","id":"1389296188090.2"}}!
    {"op":"add","path":["planet","1389296196274.3"],"value":
    {"name":"Venus","id":"1389296196274.3"}}!
    {"op":"add","path":["planet","1389296197897.4"],"value":
    {"name":"Earth","id":"1389296197897.4"}}!
    {"op":"add","path":["planet","1389296199041.5"],"value":
    {"name":"Mars","id":"1389296199041.5"}}!
    !

    View Slide

  34. CONNECTORS
    • TransformConnector for connecting a source and target.

    • Two connectors are needed for bi-directional syncs.

    • Connectors can be blocking or not
    • RequestConnector for coordinating requests to data

    View Slide

  35. COMMON LIBRARY

    View Slide

  36. ORBIT COMMON LIB

    SOURCES
    { }
    MEMORY

    View Slide

  37. { }
    MEMORY
    LOCAL STORAGE
    ORBIT COMMON LIB

    SOURCES

    View Slide

  38. { }
    MEMORY
    JSON API
    LOCAL STORAGE
    ORBIT COMMON LIB

    SOURCES

    View Slide

  39. { }
    MEMORY
    JSON API
    LOCAL STORAGE
    + MORE +
    ORBIT COMMON LIB

    SOURCES

    View Slide

  40. { }
    MODELS
    ORBIT COMMON LIB

    SCHEMA

    View Slide

  41. { }
    MODELS
    RELATIONSHIPS
    ORBIT COMMON LIB

    SCHEMA

    View Slide

  42. { }
    MODELS
    ID FIELDS
    RELATIONSHIPS
    ORBIT COMMON LIB

    SCHEMA

    View Slide

  43. { }
    MODELS
    ID FIELDS
    RELATIONSHIPS
    + MORE +
    ORBIT COMMON LIB

    SCHEMA

    View Slide

  44. View Slide

  45. Provides a loose wrapper around an OC.Source:
    App.LocalStorageSource = EO.Source.extend({!
    orbitSourceClass: OC.LocalStorageSource,!
    orbitSourceOptions: {!
    namespace: “myApp” // n.s. for localStorage!
    }!
    });
    EO.Source

    View Slide

  46. • Extends EO.Source

    • Maintains an identity map of model instances.

    • Familiar interfaces to access and request data.
    EO.Store

    View Slide

  47. EO.Store
    all
    filter
    retrieve
    !
    find
    add
    remove
    patch
    findLink
    addLink
    removeLink
    { }
    { }
    Synchronous Asynchronous

    View Slide

  48. • Defines schema with attributes and relationships

    • Backed directly by data in the source

    • Familiar interfaces to access and request data
    EO.Model

    View Slide

  49. Star = EO.Model.extend({!
    name: attr('string'),!
    planets: hasMany('planet', {inverse: 'sun'})!
    });!
    !
    Planet = EO.Model.extend({!
    name: attr('string'),!
    classification: attr('string'),!
    sun: hasOne('star', {inverse: 'planets'})!
    });
    EO.Model

    View Slide

  50. Star = EO.Model.extend({!
    name: attr('string'),!
    planets: hasMany('planet', {inverse: 'sun'})!
    });!
    !
    Planet = EO.Model.extend({!
    name: attr('string'),!
    classification: attr('string'),!
    sun: hasOne('star', {inverse: 'planets'})!
    });
    EO.Model

    View Slide

  51. EO.Model
    get
    set
    !
    remove
    patch
    findLink
    addLink
    removeLink
    { }
    { }
    Synchronous Asynchronous

    View Slide

  52. store.add(“planet”, {name: “Jupiter”}).then(!
    function(jupiter) {!
    jupiter.get(“moons”).pushObject(io);!
    jupiter.set(“classification”, “gas giant”);!
    }!
    );!
    !
    store.then(function() { // all requests resolve!
    console.log(io.get(“planet.name”)); // Jupiter!
    });!
    EO.Model

    View Slide

  53. URLS DRIVE APPLICATION STATE

    View Slide

  54. SOURCES DRIVE MODEL STATE

    View Slide

  55. AUTONOMOUS
    WEB APPLICATIONS

    WITH

    View Slide

  56. PLUGGABLE SOURCES
    IndexedDB
    LocalStorage

    View Slide

  57. EDITING CONTEXTS

    View Slide

  58. UNDO / REDO

    View Slide

  59. DATA SYNCHRONIZATION

    View Slide

  60. STATUS
    • orbit.js
    • Released January 9, 2014

    • v0.2.0

    • ember-orbit
    • Released June 17, 2014 (!!!)

    • v0.1.0

    View Slide

  61. TODOS
    • orbit.js
    • More sources

    • More synchronization strategies

    • ember-orbit
    • Fully encapsulate Orbit’s API

    • Improve ergonomics, esp. serialization & normalization

    View Slide

  62. COMING SOON
    orbitjs.com
    API docs and guides for Orbit and Ember-Orbit

    !
    Follow progress:

    Twitter: @orbitjs
    Github: https://github.com/orbitjs

    View Slide

  63. Wicked Good Ember 2014
    THANKS!
    @dgeb

    View Slide