PageRenderTime 53ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/labs/architecture-examples/backbone.xmpp/js/lib/backbone.xmpp.storage.js

https://github.com/1manStartup/todomvc
JavaScript | 140 lines | 91 code | 23 blank | 26 comment | 13 complexity | 8e49f90c967ba225e82b64da9f5e8b48 MD5 | raw file
  1. // Backbone XMPP PubSub Storage v0.3
  2. // (c) 2012 Yiorgis Gozadinos.
  3. // Backbone.xmpp is distributed under the MIT license.
  4. // http://github.com/ggozad/Backbone.xmpp
  5. // A simple module to replace **Backbone.sync** with *XMPP PubSub*-based
  6. // persistence.
  7. (function ($, _, Backbone, Strophe) {
  8. // A PubSub node acting as storage.
  9. // Create it with the `id` the node has on the XMPP server,
  10. // and a Strophe `connection`.
  11. var PubSubStorage = function(id, connection, payloadFormat) {
  12. this.id = id;
  13. this.connection = connection;
  14. this.payloadFormat = payloadFormat || 'json';
  15. };
  16. // Attach methods to **PubSubStorage**.
  17. _.extend(PubSubStorage.prototype, {
  18. // **create** publishes to the node the model in JSON format.
  19. //Resolves by setting the `id` on the item and returning it.
  20. create: function(model) {
  21. var d = $.Deferred(), res = {};
  22. this._publish(this.id, model)
  23. .done(function (id) {
  24. res[model.idAttribute] = id;
  25. d.resolve(res);
  26. })
  27. .fail(d.reject);
  28. return d.promise();
  29. },
  30. // **update** a model by re-publishing it on the node.
  31. // Resolves with no result as under no circumstances the server will change any attributes.
  32. update: function(model) {
  33. var d = $.Deferred();
  34. this._publish(this.id, model, model.id)
  35. .done(function () { d.resolve(); })
  36. .fail(d.reject);
  37. return d.promise();
  38. },
  39. // **getItem** retrieves a model from the node by `id`.
  40. // Resolves by returning the attributes of the model that are different and their values.
  41. getItem: function(model) {
  42. var d = $.Deferred(), that = this;
  43. this.connection.PubSub.items(this.id, {item_ids: [model.id]})
  44. .done(function (item) {
  45. var updated = {},
  46. attrs = that.parseItem(item);
  47. _.each(attrs, function (value, key) {
  48. if (model.get(key) !== value) updated[key] = value;
  49. });
  50. d.resolve(updated);
  51. })
  52. .fail(d.reject);
  53. return d.promise();
  54. },
  55. // **getItems** retrieves all models from the node.
  56. // Resolves by returning a list of all its models in JSON format.
  57. getItems: function(options) {
  58. var d = $.Deferred(), that = this;
  59. this.connection.PubSub.items(this.id, options)
  60. .done(function (data) {
  61. var attrs,
  62. items = data.rsm ? data.items : data;
  63. d.resolve(_.map(items, function (item) {
  64. attrs = that.parseItem($('entry', item));
  65. attrs.id = $(item).attr('id');
  66. return attrs;
  67. }), data.rsm);
  68. })
  69. .fail(d.reject);
  70. return d.promise();
  71. },
  72. // **destroy** deletes the item correcsponding to the `model` from the node.
  73. // Resolves by returning the `iq` response.
  74. destroy: function(model) {
  75. return this.connection.PubSub.deleteItem(this.id, model.id);
  76. },
  77. // Publish in particular format
  78. _publish: function(node, model, item_id) {
  79. if (this.payloadFormat === 'atom') {
  80. return this.connection.PubSub.publishAtom(node, model.toJSON(), item_id);
  81. }
  82. else {
  83. var entry = $build('entry').t(JSON.stringify(model.toJSON())).tree();
  84. return this.connection.PubSub.publish(node, entry, item_id);
  85. }
  86. },
  87. parseItem: function(item) {
  88. if (this.payloadFormat === 'atom') {
  89. return this.connection.PubSub._AtomToJson(item);
  90. }
  91. else {
  92. return JSON.parse($(item).text());
  93. }
  94. }
  95. });
  96. // **xmppAsync** is the replacement for **sync**. It delegates sync operations
  97. // to the model or collection's `node` property, which should be an instance
  98. // of **PubSubStorage**.
  99. Backbone.xmppSync = function(method, model, options) {
  100. var p,
  101. node = model.node || (model.collection && model.collection.node);
  102. options = options || {};
  103. // If there is no node, fail directly, somebody did not read the docs.
  104. if (!node) return $.Deferred().reject().promise();
  105. switch (method) {
  106. case "read": p = typeof model.id !== 'undefined' ? node.getItem(model) : node.getItems(options); break;
  107. case "create": p = node.create(model); break;
  108. case "update": p = node.update(model); break;
  109. case "delete": p = node.destroy(model); break;
  110. }
  111. // Fallback for old-style callbacks.
  112. if (options.success) p.done(options.success);
  113. if (options.error) p.fail(options.error);
  114. return p;
  115. };
  116. this.PubSubStorage = PubSubStorage;
  117. })(this.jQuery, this._, this.Backbone, this.Strophe);