{"id":25092817,"url":"https://github.com/biril/backbone-faux-server","last_synced_at":"2025-04-13T07:43:55.952Z","repository":{"id":5292239,"uuid":"6472874","full_name":"biril/backbone-faux-server","owner":"biril","description":"A framework for mocking up server-side persistence / processing for Backbone.js","archived":false,"fork":false,"pushed_at":"2024-08-20T05:59:08.000Z","size":768,"stargazers_count":54,"open_issues_count":3,"forks_count":11,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-06T22:37:30.268Z","etag":null,"topics":["backbone","backbonejs","mock","persistence","test"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/biril.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-10-31T11:29:49.000Z","updated_at":"2024-08-20T05:59:12.000Z","dependencies_parsed_at":"2024-09-26T04:10:35.050Z","dependency_job_id":null,"html_url":"https://github.com/biril/backbone-faux-server","commit_stats":{"total_commits":228,"total_committers":3,"mean_commits":76.0,"dds":0.01754385964912286,"last_synced_commit":"b80719a29f4d11804cb8551d7b21038f5f33c2f5"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biril%2Fbackbone-faux-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biril%2Fbackbone-faux-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biril%2Fbackbone-faux-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biril%2Fbackbone-faux-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/biril","download_url":"https://codeload.github.com/biril/backbone-faux-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238861156,"owners_count":19542909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backbone","backbonejs","mock","persistence","test"],"created_at":"2025-02-07T14:34:57.165Z","updated_at":"2025-02-14T15:09:53.826Z","avatar_url":"https://github.com/biril.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Backbone Faux Server\n====================\n\n[![Build Status](https://travis-ci.org/biril/backbone-faux-server.png)](https://travis-ci.org/biril/backbone-faux-server)\n[![NPM version](https://badge.fury.io/js/backbone-faux-server.png)](http://badge.fury.io/js/backbone-faux-server)\n[![Bower version](https://badge.fury.io/bo/backbone-faux-server.png)](http://badge.fury.io/bo/backbone-faux-server)\n\nA framework for mocking up server-side persistence / processing for\n[Backbone.js](https://github.com/documentcloud/backbone)\n\nDefine any number of routes that map `\u003cmodel-URL, sync-method\u003e` pairs to custom handlers.\nFaux-server overrides (is a drop-in replacement of) Backbone's native sync so that whenever a Model\n(or Collection) is synced and its URL along with the sync method form a pair that matches a defined\nroute, the route's handler is invoked. Implement handlers to test the expected behaviour of your\napp, work with dummy data, support persistence using local-storage, etc. When \u0026 if you choose to\nmove to a real server, switching back to Backbone's native, ajax-based sync is as simple as\n`fauxServer.enable(false)`.\n\nBackbone faux server (henceforth 'BFS') grew out of the author's need to quickly flesh out Backbone\nprototype apps without having to fiddle with a server, a DB, or anything else that would require\nmore than a JS script.\n[Similar solutions](https://github.com/jashkenas/backbone/wiki/Extensions%2C-Plugins%2C-Resources#storage)\nexist for this but they deviate from or obscure Backbone's opinion of Model URLs, REST and their\ninterdependence. Additionally, BFS doesn't implement some specific persistence scheme but only\nprovides hooks for your own custom processing / persistence scheme, _per_ HTTP verb, _per_ resource\n(Model or Collection URL). Functionality written this way, may be ported to the server-side in a\nstraightforward manner.\n\n\nSet up\n------\n\nTo get Backbone Faux Server\n\n* install with bower, `bower install backbone-faux-server`,\n* install with npm, `npm install backbone-faux-server` or\n* just include [`backbone-faux-server.js`](https://raw.github.com/biril/backbone-faux-server/master/backbone-faux-server.js)\n    in your project.\n\nBFS may be used as an exported global, a CommonJS module or an AMD module depending on the current\nenvironment:\n\n* In projects targetting _browsers, without an AMD module loader_, include backbone-faux-server.js\n    after backbone.js:\n\n    ```html\n    ...\n    \u003cscript type=\"text/javascript\" src=\"backbone.js\"\u003e\u003c/script\u003e\n    \u003cscript type=\"text/javascript\" src=\"backbone-faux-server.js\"\u003e\u003c/script\u003e\n    ...\n    ```\n\n    This will export the `fauxServer` global:\n\n    ```javascript\n    console.log(\"fauxServer version: \" + fauxServer.getVersion());\n    ```\n\n    The project also includes a relevant\n    [example app](https://github.com/biril/backbone-faux-server/tree/master/examples/books) where\n    BFS is included through a `\u003cscript\u003e` tag and treated as a global.\n\n* `require` when working _with CommonJS_ (e.g. Node). Assuming BFS is `npm install`ed:\n\n    ```javascript\n    var fauxServer = require(\"backbone-faux-server\");\n    console.log(\"fauxServer version: \" + fauxServer.getVersion());\n    ```\n\n    (see [the Caveats section](#caveats--wtf) for issues related to `npm install`ing Backbone along\n    with BFS)\n\n* Or list as a dependency when working _with an AMD loader_ (e.g. RequireJS):\n\n    ```javascript\n    // Your module\n    define([\"backbone-faux-server\"], function (fauxServer) {\n        console.log(\"fauxServer version: \" + fauxServer.getVersion());\n    });\n    ```\n\n    Note that the AMD definition of BFS depends on `backbone` and `underscore` so some loader\n    setup will be required. For non-AMD compliant versions of Backbone (\u003c 1.1.1) or Undescore\n    (\u003c 1.6.0), [James Burke's amdjs forks](https://github.com/amdjs) may be used instead, along\n    with the necessary paths configuration\n\n    ```javascript\n    require.config({\n        baseUrl: \"myapp/\",\n        paths: {\n            \"underscore\": \"mylibs/underscore\",\n            \"backbone\": \"mylibs/backbone\"\n        }\n    });\n    ```\n\n    or you may prefer to just [shim them](http://requirejs.org/docs/api.html#config-shim).\n\n    The project also includes a relevant\n    [example app](https://github.com/biril/backbone-faux-server/tree/master/examples/books-AMD)\n    where BFS is treated as an AMD module.\n\n\nUsage\n-----\n\nDefine Backbone Models and Collections as you normally would:\n\n```javascript\nvar Book = Backbone.Model.extend({\n    defaults: {\n        title: \"Unknown title\",\n        author: \"Unknown author\"\n    }\n});\nvar Books = Backbone.Collection.extend({\n    model: Book,\n    url: \"library-app/books\"\n});\n```\n\nNote that the `url` property is used, as it would in any scenario involving a remote resource.\n\nContinue by defining routes, to handle Model syncing as needed. Every route defines a mapping from\na Model(or Collection)-URL \u0026 sync-method (an HTTP verb (POST, GET, PUT, PATCH, DELETE)) to some\nspecific handler (callback):\n\n`\u003cmodel-URL, sync-method\u003e → handler`\n\nFor example, to handle the creation of a Book (`Books.create(..)`), define a route that maps the\n`\u003c\"library-app/books\", \"POST\"\u003e` pair to a handler, like so:\n\n```javascript\nfauxServer.addRoute(\"createBook\", \"library-app/books\", \"POST\", function (context) {\n    // Every handler receives a 'context' parameter. Use context.data (a hash of\n    //  Book attributes) to create the Book entry in your persistence layer.\n    //  Return attributes of created Book. Something along the lines of:\n    context.data.id = newId(); // You'll probably want to assign an id to the new book\n    books.push(context.data);  // Save to persistence layer\n    return context.data;\n});\n```\n\nThe \"createBook\" parameter simply defines a name for the route. The URL parameter,\n\"library-app/books\", is pretty straightforward in the preceding example - it's the URL of the Books\nCollection. Note however that the URL may (and usually will) be specified as a matching expression,\nsimilarly to [Backbone routes](http://backbonejs.org/#Router-routes): URL-expressions may contain\nparameter parts, `:param`, which match a single URL component between slashes; and splat parts\n`*splat`, which can match any number of URL components. Optional parts are denoted using\nparentheses. The values captured by params and splats will be passed as extra parameters to the\ngiven handler method. Regular expressions may also be used, in which case all values captured by\nreg-exp capturing groups will be passed as extra parameters to the handler method.\n\nDefine more routes to handle updating, reading and deleting Models. The `addRoutes` method is used\nbelow to define routes to handle all actions (create, read, update and delete) for the preceding\nBook example:\n\n```javascript\nfauxServer.addRoutes({\n    createBook: {\n        urlExp: \"library-app/books\",\n        httpMethod: \"POST\",\n        handler: function (context) {\n            // Create book using attributes in context.data\n            // Save to persistence layer\n            // Return attributes of newly created book\n        }\n    },\n    readBooks: {\n        urlExp: \"library-app/books\",\n        httpMethod: \"GET\",\n        handler: function (context) {\n            // Return array of stored book attributes\n        }\n    },\n    readBook: {\n        urlExp: \"library-app/books/:id\",\n        httpMethod: \"GET\",\n        handler: function (context, bookId) {\n            // Return attributes of stored book with id 'bookId'\n        }\n    },\n    updateBook: {\n        urlExp: \"library-app/books/:id\",\n        httpMethod: \"PUT\",\n        handler: function (context, bookId) {\n            // Update stored book with id 'bookId', using attributes in context.data\n            // Return updated attributes\n        }\n    },\n    deleteBook: {\n        urlExp: \"library-app/books/:id\",\n        httpMethod: \"DELETE\",\n        handler: function (context, bookId) {\n            // Delete stored book of id 'bookId'\n        }\n    }\n}\n```\n\nRoute names can be useful for querying and / or removing earlier defined routes. However, this is\noften unnecessary and route names may be skipped in most declarations. (They're mandatory as keys\nwhen passing a hash of routes to `addRoutes`.) Coming back to the earlier \"createBook\" example,\nthe route name may be skipped like so:\n\n```javascript\nfauxServer.addRoute(\"library-app/books\", \"POST\", function (context) {\n    // Create book ..\n});\n```\n\nMoreover, faux-server exposes `get`, `post`, `put`, `del` and `patch` methods as shortcuts for\ncalling `addRoute` with a specific `httpMethod`. Thus, the preceding POST-route addition may be\nrewritten as\n\n```javascript\nfauxServer.post(\"library-app/books\", function (context) {\n    // Create book ..\n});\n```\n\nThus, an alternative, more compact syntax for the preceding `addRoutes` example would be:\n\n```javascript\nfauxServer\n    .post(\"library-app/books\", function (context) {\n        // Create book using attributes in context.data\n        // Save to persistence layer\n        // Return attributes of newly created book\n\n    }).get(\"library-app/books\", function (context) {\n        // Return array of stored book attributes\n\n    }).get(\"library-app/books/:id\", function (context, bookId) {\n        // Return attributes of stored book with id 'bookId'\n\n    }).put(\"library-app/books/:id\", function (context, bookId) {\n        // Update stored book with id 'bookId', using attributes in context.data\n        // Return updated attributes\n\n    }).del(\"library-app/books/:id\", function (context, bookId) {\n        // Delete stored book of id 'bookId'\n    });\n}\n```\n\n\nTesting / Contributing\n----------------------\n\nThe QUnit test suite may be run in a browser (test/index.html) or on the command line, by running\n`make test` or `npm test`. The command line version runs on Node and depends on\n[node-qunit](https://github.com/kof/node-qunit) (`npm install` to fetch it before testing). A\n[coverage report](http://biril.github.io/backbone-faux-server/lcov-report/backbone-faux-server/backbone-faux-server.js.html)\nis also available.\n\nContributions are obviously appreciated. Please commit your changes on the `dev` branch - not\n`master`. `dev` is always ahead, contains the latest state of the project and is periodically\nmerged back to `master` with the appropriate version bump. In lieu of a formal styleguide, take\ncare to maintain the existing coding style. Please make sure your changes test out green prior to\npull requests.\n\n\nReference\n---------\n\nThe following list, while not exhaustive, includes all essential parts of the BFS API. The omitted\nbits are there facilitate fancier stuff you probably won't ever need. Further insight may be gained\nby taking a look at\n[the examples](https://github.com/biril/backbone-faux-server/tree/master/examples),\n[the test suite](https://github.com/biril/backbone-faux-server/tree/master/test) and - of course -\n[the source](https://github.com/biril/backbone-faux-server/blob/master/backbone-faux-server.js).\nFor the latter, an [annotated version](http://biril.github.io/backbone-faux-server/) is also\nmaintained.\n\n### Methods\n\nAll methods return the faux-server instance and may be chained, unless otherwise noted.\n\n#### addRoute ([name, ]urlExp[, httpMethod]\u0026#91;, handler\u0026#93;)\n\nAdd a route to the faux-server. Every route defines a mapping from a Model(or Collection)-URL \u0026\nsync-method (an HTTP verb (POST, GET, PUT, PATCH or DELETE)) to some specific handler (callback):\n\n`\u003cmodel-URL, sync-method\u003e → handler`\n\nWhenever a Model is created, read, updated or deleted, its URL and the the sync method being\nused are tested against defined routes in order to find a handler for creating, reading,\nupdating or deleting this Model. The same applies to reading Collections: Whenever a Collection is\nread, its URL (and the 'read' method) will be tested against defined routes in order to find a\nhandler for reading it. When a match for the `\u003cmodel-URL, sync-method\u003e` pair is not found among\ndefined routes, the native sync is invoked (this behaviour may be overridden - see\n`fauxServer.setDefaultHandler`). Later routes take precedence over earlier routes so in\nconfigurations where multiple routes match, the one most recently defined will be used.\n\n* `name`: Name of this route. Optional. A named route may be queried and / or removed by its name\n    (see `getRoute` / `removeRoute`) and will replace an earlier defined route of same name.\n* `urlExp`: An expression against which, Model(or Collection)-URLs will be tested. This is\n    syntactically and functionally analogous to\n    [Backbone routes](http://backbonejs.org/#Router-routes): `urlExp`s may contain parameter parts,\n    `:param`, which match a single URL component between slashes; and splat parts `*splat`, which\n    can match any number of URL components. Parentheses may also be used to denote optional parts.\n    The values captured by params and splats will be passed as parameters to the given handler\n    method. Regular expressions may also be used, in which case all values captured by\n    reg-exp capturing groups will be passed as parameters to the given handler method. Note that\n    `:param`s are required to begin with a letter or underscore - those that don't are treated as\n    a fixed part of the URL. The expression `http://example.com:8080` contains _no_ `:param` parts.\n* `httpMethod`: The sync method, (an HTTP verb (POST, GET, PUT, PATCH or DELETE)), that should\n    trigger the route's handler. Both the URL-expression and the method should match for the\n    handler to be invoked. `httpMethod` may also be set to '*' or omitted to create a\n    match-all-methods handler: One that will be invoked whenever `urlExp` matches the model's (or\n    collection's) URL _regardless_ of method. In the scope of a match-all-methods handler, the HTTP\n    method currently being handled may be acquired by querying the `context` parameter for\n    `context.httpMethod`. Note that when `Backbone.emulateHTTP` is set to true or `emulateHTTP` is\n    passed as an inline option during sync, 'create', 'update', 'patch' and 'delete' will all be\n    mapped to POST. In this case `context.httpMethod` will be set to POST and the true HTTP method\n    being handled may be acquired by querying `context.httpMethodOverride`.\n* `handler`: The handler to be invoked when both route's URL-expression and route's method match. A\n    do-nothing handler will be used if one is not provided. The handler's expected signature is\n\n    `function (context, [param1, [param2, ...]])`\n\n    where `context` contains properties `data`, `httpMethod`, `httpMethodOverride`, `route` and\n    `param1`, `param2`, ... are parameters derived by matching the `urlExp` to the Model\n    (or Collection) URL. Specifically, about `context` properties:\n\n    * `context.data`: Attributes of the Model (or Collection) being processed. Valid only on\n       'create' (POST), 'update' (PUT) or 'patch' (PATCH). In the specific case of PATCH,\n       `context.data` may only contain a _subset_ of Model's attributes.\n    * `context.httpMethod`: The HTTP Method (POST, GET, PUT, PATCH or DELETE) that is currently\n       being handled.\n    * `context.url`: The URL that is currently being handled.\n    * `context.httpMethodOverride`: The true HTTP method (POST, GET, PUT, PATCH or DELETE) that is\n       currently being handled when `Backbone.emulateHTTP` is set to true. The equivalent of\n       [Backbone's](http://backbonejs.org/#Sync-emulateHTTP) `X-HTTP-Method-Override` header.\n    * `context.route`: The route that is currently being handled.\n\n    On success, the handler should return created Model attributes after handling a POST and updated\n    Model attributes after handling a PUT or PATCH. Return Model attributes after handling a GET or\n    an array of Model attributes after handling a GET that refers to a collection. Note that only\n    attributes that have been changed on the server (and should be updated on the client) need to be\n    included in returned hashes. Return nothing after handling a DELETE. On failure, the handler\n    should return a string (presumably a custom error message, an HTTP status code that indicates\n    failure, etc).\n\n#### \u0026lt;httpMethod\u0026gt; ([name, ]urlExp[, handler])\n\n`get`, `post`, `put`, `del` and `patch` methods which act as shortcuts for calling `addRoute`\nwith a specific `httpMethod`. See `addRoute` above for parameter descriptions and further details.\n\n#### addRoutes (routes)\n\nAdd multiple routes to the faux-server.\n\n* `routes`: A hash or array of routes to add. Each route is itself a hash with `name`, `urlExp`,\n    `httpMethod` and `handler` attributes. As is the case with `addRoute`, the only attribute whose\n    presence is mandatory is `urlExp`. Note that when passing a hash of routes, its keys are\n    treated as route names and the `name` attribute should be omitted.\n\n#### removeRoute (name)\n\nRemove the route of given name.\n\n* `name`: Name of route to remove.\n\n#### removeRoutes ()\n\nRemove all defined routes.\n\n#### getRoute (name)\n\nGet route of given name.\n\n* `name`: Name of route to acquire.\n* returns: Route of given name or null if no such route exists. Note that the returned route is a\n    copy and cannot be modified to alter faux-server's behaviour.\n\n#### setDefaultHandler ([handler])\n\nSet a handler to be invoked when no route is matched to the current `\u003cmodel-URL, sync-method\u003e`\npair. This will override the default behaviour of invoking the native sync.\n\n* `handler`: A handler to be invoked when no route is found that matches a given\n    `\u003cmodel-URL, sync-method\u003e` pair. Omit the parameter to reset to the default behaviour. See\n    `addRoute` for handler's signature and semantics. Note that a default-handler isn't part of a\n    route, so the `context.route` parameter will not be valid.\n\n#### setLatency (min[, max])\n\nSet server's emulated latency (zero by default)\n\n* `min`: Server's emulated latency in ms. Interpreted as the minimum of a range when a `max` value\n    is provided. Omitting will set to 0. In place of a fixed minimum, a function may also be\n    given that returns a latency. The function will be invoked per handled route, with the same\n    parameters as those passed to the relevant route handler (`context`, etc).\n\n* `max`: Maximum server latency in ms. Specifying this will cause syncing to occur with a random\n    latency in the [min, max] range. When `max` is given, `min` should be a fixed number.\n\n#### setTransportFactory (transportFactory)\n\nSet server's transport factory\n\n* `transportFactory`: A factory function with signature\n\n    `function (syncOptions, syncContext)`\n\n    invoked _per sync_ (with sync's relevant options and context) to create a new transport.\n\nTransports are deferred-like objects implementing a `resolve` / `reject` / `promise` interface. A\nsuccessful sync will invoke `transport.resolve` while a failed one will invoke `transport.reject`.\nThe sync method will always return `transport.promise()`.\n\nSee [the Transport section](#transports) for further details.\n\n#### enable ([shouldEnable])\n\nEnable or disable the faux-server. When disabled, syncing is performed by the native Backbone sync\nmethod. Handy for easily toggling between mock / real server.\n\n* `shouldEnable`: Indicates whether to enable or disable. Set to true or omit to enable the\n    faux-server, set to false to disable.\n\n#### getVersion ()\n\nGet the faux-server version\n\n#### noConflict ()\n\nRun in no-conflict mode, setting the global `fauxServer` variable to to its previous value. Only\nuseful when working in a browser environment without a module-loader as this is the only case\nwhere `fauxServer` is exposed globally. Returns a reference to the faux-server.\n\n\nTransports\n----------\n\nBackbone is built on minimum assumptions regarding the communication layer and/or persistence\nstrategy applications will make use of. Although, more often that not, this is jQuery's `ajax`\nfunction, you may choose to [use a modified ajax function](http://backbonejs.org/#Sync-ajax) or\n[bypass the sync method](http://backbonejs.org/#Sync) altogether (this is in fact how BFS works).\nBackbone will, generally speaking, abstract this away so that applications may be written on top of\na normalized layer.\n\nHaving said that, specific choices in the method of communication / persistence can affect how\napplication code is written in certain ways. As an example consider the case of chaining a `then`\ncall after sync:\n\n```javascript\naModel.save().then(function () {\n    // .. continue after successfully saving the model ..\n});\n```\n\nThis works under the assumption that Backbone's `sync` returns a\n[promise](http://promises-aplus.github.io/promises-spec), which is the case when\nthe underlying ajax function - the communication layer - does so. Which holds true specifically\nfor [jQuery's `ajax`](http://api.jquery.com/jQuery.ajax) but not necessarily for other\ncommunication layers and/or persistence strategies.\n\nAs BFS is itself such a strategy, one that completely bypasses the communication layer, there may\nbe cases where application code assumes and makes use of functionality which will not be available\nwhen the app is run on a faux server. A common problematic example is implementations which rely on\nthe creation of `jqXHR` objects when Models are synced: BFS `sync` will attempt to return a jQuery\npromise when that's feasible (when `Backbone.$` is found to be the jQuery object at runtime) or\njust return undefined otherwise - never will it return an actual `jqXHR`. You can compensate for\nthat by implementing a custom 'transport'.\n\nTransports are a BFS abstraction intended as a means of mocking the aspects (the API) of an\napplication-specific communication layer. It may be helpful to think of the `jqXHR` object as a\nconcrete example of a transport - or, to be precise, a transport's promise.\n\nTransports are deferred-like objects implementing a `resolve` / `reject` / `promise` interface. BFS\nwill instantiate a new transport on every sync, and return its promise by invoking\n`transport.promise`. When the sync is successful, i.e. when the relevant handler returns a\nnon-string value, `transport.resolve` will be called with the handler's returned result. When the\nsync fails, i.e. when the relevant handler returns a string result, `transport.reject` will be\ncalled with the handler's result. It is the transport's responsibility to subsequently call the\ngiven success or error callbacks.\n\nTo define a custom transport, to be instantiated on every invocation of `sync`, call\n[`fauxServer.setTransportFactory`](#settransportfactory-transportfactory) providing a\ntransport-factory function. Implement your custom transport-factory function so that\n\n* it instantiates and returns a `transport` object with `resolve` / `reject` and `promise` methods.\n   A deferred object is an obvious choice for this (see\n   [jQuery's $.Deferred](http://api.jquery.com/category/deferred-object) or\n   [Q's Q.defer](https://github.com/kriskowal/q#using-deferreds)) but any object with the\n   aforementioned methods is adequate.\n* `transport.resolve` invokes the sync's success callback, `options.success`.\n* `transport.reject` invokes the sync's error callback, `options.error`.\n* `transport.promise` returns an object featuring all properties and methods your implementation\n   requires on the object returned when `sync`ing (`fetch`ing, `save`ing, etc). Think of it as a\n   mocked `jqXHR`.\n\nAs a reference, this is (a somewhat simplified version of) the default BFS transport-factory:\n\n```javascript\n// Transport-factory function, invoked _per sync_ (with the relevant options / context)\n//  to instantiate a new transport\nfunction (syncOptions, syncContext) {\n    // If an underlying ajax lib is defined for Backbone and it features a\n    //  Deferred method (which is precisely the case when Backbone.$ = jQuery)\n    //  then create and return a deferred object as transport\n    if (Backbone.$ \u0026\u0026 Backbone.$.Deferred) {\n        var deferred = Backbone.$.Deferred();\n        deferred.then(syncOptions.success, syncOptions.error);\n        return deferred;\n    }\n\n    // Otherwise create a poor-man's deferred - an object that implements a\n    //  promise/resolve/reject interface without actual promise semantics:\n    //  resolve and reject just delegate to success and error callbacks while\n    //  promise() returns undefined. This is a good enough transport\n    return {\n        promise: function () {},\n        resolve: function (value) { syncOptions.success(value); },\n        reject: function (reason) { syncOptions.error(reason); }\n    };\n}\n```\n\n\nCaveats / WTF\n-------------\n\n* When developing for Node, using npm for dependency management, be sure to `npm install backbone`\n    _before_ `npm install`ing BFS. The opposite will cause BFS to fail due to Node's\n    [module caching caveats](http://nodejs.org/api/modules.html#modules_module_caching_caveats).\n* `npm install`ing with the `--dev` switch will fail due to node-qunit\n    [quirk](https://github.com/kof/node-qunit/issues/41). As a solution, `npm install qunit` before\n    installing other devDependencies.\n* The current version of BFS is tested against BB v1.1.2. It's generally compatible with 1.x\n    revisions but _not_ 0.9.x revisions.\n    ([BFS v0.7.0](https://github.com/biril/backbone-faux-server/releases/tag/v0.7.0) is the last\n    known good version for BB \u0026lt;= v0.9.10).\n\n\nLicense\n-------\n\nLicensed and freely distributed under the MIT License (LICENSE.txt).\n\nCopyright (c) 2012-2014 Alex Lambiris\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiril%2Fbackbone-faux-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbiril%2Fbackbone-faux-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiril%2Fbackbone-faux-server/lists"}