can-connect
Advanced tools
Comparing version 0.6.0-pre.12 to 0.6.0-pre.13
{ | ||
"name": "can-connect", | ||
"version": "0.6.0-pre.12", | ||
"version": "0.6.0-pre.13", | ||
"description": "Data connection middleware and utilities", | ||
@@ -11,6 +11,6 @@ "main": "can-connect.js", | ||
"can-event": "^3.0.0-pre.3", | ||
"can-observation": "^3.0.0-pre.0", | ||
"can-set": "^0.6.0-pre.3", | ||
"can-observation": "^3.0.0-pre.5", | ||
"can-set": "^0.6.0-pre.6", | ||
"can-stache": "^3.0.0-pre.8", | ||
"can-stache-bindings": "^3.0.0-pre.5", | ||
"can-stache-bindings": "^3.0.0-pre.9", | ||
"can-util": "^3.0.0-pre.28", | ||
@@ -21,3 +21,4 @@ "can-view-callbacks": "^3.0.0-pre.4", | ||
"steal-stache": "^3.0.0-pre.1", | ||
"when": "^3.7.3" | ||
"when": "^3.7.3", | ||
"can-define": "^0.7.17" | ||
}, | ||
@@ -29,3 +30,2 @@ "repository": { | ||
"devDependencies": { | ||
"can-define": "^0.7.7", | ||
"can-fixture": "^0.1.0", | ||
@@ -100,2 +100,3 @@ "can-wait": "^0.2.0", | ||
"./can/map/map": "./dist/cjs/can/map/map", | ||
"./can/ref/ref": "./dist/cjs/can/ref/ref", | ||
"./can/tag/tag": "./dist/cjs/can/tag/tag" | ||
@@ -102,0 +103,0 @@ }, |
578
readme.md
@@ -8,578 +8,2 @@ # can-connect | ||
It currently can: | ||
Load data: | ||
- [can-connect/data/url/url] - Persist data to restful or other types of services. | ||
- [can-connect/data/parse/parse] - Extract response data into a format needed for other extensions. | ||
Convert data into special types: | ||
- [can-connect/constructor/constructor] - Create instances of a constructor function or list type. | ||
- [can-connect/constructor/store/store] - Create only a single instance for a given id or a single list for a set. | ||
Real time: | ||
- [can-connect/real-time/real-time] - Update lists and instances with server side events. | ||
Caching strategies: | ||
- [can-connect/fall-through-cache/fall-through-cache] - Respond with data from the [connection.cacheConnection] and | ||
then update the response with data from the `raw CRUD Methods`. | ||
- [can-connect/data/inline-cache/inline-cache] - Use an inline cache for initial ajax requests. | ||
- [can-connect/cache-requests/cache-requests] - Save response data and use it for future requests. | ||
- [can-connect/data/combine-requests/combine-requests] - Combine overlapping or reduntant requests. | ||
Caching layers: | ||
- [can-connect/data/localstorage-cache/localstorage-cache] - LocalStorage caching connection. | ||
- [can-connect/data/memory-cache/memory-cache] - LocalStorage caching connection. | ||
The following modules glue certain methods together: | ||
- [can-connect/data/callbacks/callbacks] - Glues the result of the `raw CRUD Methods` to callbacks. | ||
- [can-connect/data/callbacks-cache/callbacks-cache] - Calls [connection.cacheConnection] methods whenever `raw CRUD methods` are called. | ||
The following modules are useful to CanJS specifically: | ||
- [can-connect/can/map/map] - Create instances of a special can.Map or can.List type. | ||
- [can-connect/can/super-map/super-map] - Create a connection for a can.Map or can.List that uses almost all the plugins. | ||
- [can-connect/can/model/model] - Inherit from a highly compatable [can.Model](http://canjs.com/docs/can.Model.html) implementation. | ||
- [can-connect/can/tag/tag] - Create a custom element that can load data into a template. | ||
## Overview | ||
The "can-connect" module exports a `connect` function that is used to assemble different | ||
behaviors and some options into a `connection`. For example, the following uses `connect` and | ||
the [can-connect/constructor/constructor] and [can-connect/data/url/url] behaviors to create a `todoConnection` | ||
connection: | ||
```js | ||
import connect from "can-connect"; | ||
import "can-connect/constructor/"; | ||
import "can-connect/data/url/"; | ||
var todoConnection = connect( | ||
["constructor","data-url"], | ||
{ | ||
url: "/services/todos" | ||
}); | ||
``` | ||
A connection typically provides the ability to | ||
create, read, update, or delete (CRUD) some data source. That data source is | ||
usually accessed through the "Instance Interface" methods: | ||
- [can-connect/connection.get] | ||
- [can-connect/connection.getList] | ||
- [can-connect/connection.save] | ||
- [can-connect/connection.destroy] | ||
For example, to get all todos from "GET /services/todos", we could write the following: | ||
``` | ||
todoConnection.getList({}).then(function(todos){ ... }); | ||
``` | ||
__Behaviors__, like [can-connect/constructor/constructor] and [can-connect/data/url/url] implement, | ||
extend, or require some set of [interfaces](#section_Interfaces). For example, data-url implements | ||
the "Data Interface" methods, and [can-connect/constructor/constructor] implements the | ||
"Instance Interface" methods. | ||
The `connect` method calls these behaviors in the right order to create a connection. For instance, | ||
the [can-connect/cache-requests/cache-requests] behavior must be applied after the [can-connect/data/url/url] | ||
connection. This is because [can-connect/cache-requests/cache-requests], overwrites [can-connect/data/url/url]'s | ||
[can-connect/connection.getListData] first check a cache for the data. Only if the data is not present, | ||
does it call [can-connect/data/url/url]'s [can-connect/connection.getListData]. So even if we write: | ||
``` | ||
connect(['cache-requests','data-url']) | ||
``` | ||
or | ||
``` | ||
connect(['data-url','cache-requests']) | ||
``` | ||
... our connection will be built in the right order! | ||
A __connection__ is just an object with each behavior object on its prototype chain and | ||
its options object at the end of the prototype chain. | ||
## Use | ||
This section covers how to install can-connect and then the basics of its use. | ||
### Install | ||
Use npm to install `can-connect`: | ||
``` | ||
> npm install can-connect --save | ||
``` | ||
Then, depending on your module loader, you'll do one of the following: | ||
#### StealJS | ||
Import can-connect and its behaviors like: | ||
``` | ||
import connect from "can-connect"; | ||
import "can-connect/data/url/" | ||
``` | ||
#### Browserify | ||
`require` can-connect and its behaviors like: | ||
``` | ||
var connect = require("can-connect"); | ||
import("can-connect/data/url/url"); | ||
``` | ||
#### AMD | ||
Configure a package to can-connect and its dependency can-set: | ||
``` | ||
require.config({ | ||
packages: [{ | ||
name: 'can-connect', | ||
location: 'node_modules/can-connect/dist/amd', | ||
main: 'can-connect' | ||
},{ | ||
name: 'can-set', | ||
location: 'node_modules/can-connect/node_modules/can-set/dist/amd', | ||
main: 'src/set' | ||
}] | ||
}); | ||
``` | ||
Then use `define` to load can-connect and its behaviors like: | ||
``` | ||
define(["can-connect","can-connect/data/url/url"], function(connect){ | ||
}); | ||
``` | ||
### Basic connection | ||
To use `can-connect`, it's typically best to start out with the most basic | ||
behaviors: [can-connect/data/url/url] and [can-connect/constructor/constructor]. [can-connect/data/url/url] | ||
connects the "Data Interface" to a restful service. [can-connect/constructor/constructor] adds | ||
an "Instance Interface" that can create, read, update and delete (CRUD) typed data | ||
using the lower-level "Data Interface". | ||
By `typed` data we mean data that is more than just plain JavaScript objects. For | ||
example, we might to create `todo` objects with an `isComplete` method: | ||
``` | ||
var Todo = function(props){ | ||
Object.assign(this, props); | ||
}; | ||
Todo.prototype.isComplete = function(){ | ||
return this.status === "complete"; | ||
}; | ||
``` | ||
And, we might want a special list type with `completed` and `active` methods: | ||
``` | ||
var TodoList = function(todos){ | ||
[].push.apply(this, todos); | ||
}; | ||
TodoList.prototype = Object.create(Array.prototype); | ||
TodoList.prototype.completed = function(){ | ||
return this.filter(function(todo){ | ||
return todo.status === "complete"; | ||
}); | ||
}; | ||
TodoList.prototype.active = function(){ | ||
return this.filter(function(todo){ | ||
return todo.status !== "complete"; | ||
}); | ||
}; | ||
``` | ||
We can create a connection that connects a restful "/api/todos" | ||
service to `Todo` instances and `TodoList` lists like: | ||
``` | ||
var todoConnection = connect(["constructor","data-url"],{ | ||
url: "/api/todos", | ||
list: function(listData, set){ | ||
return new TodoList(listData.data); | ||
}, | ||
instance: function(props) { | ||
return new Todo(props); | ||
} | ||
}); | ||
``` | ||
And then use that connection to get a `TodoList` of `Todo`s: | ||
``` | ||
todoConnection.getList({}).then(function(todos){ | ||
var todosEl = document.getElementById("todos-list"); | ||
todosEl.innerHTML = "<h2>Active</h2>"+ | ||
render(todos.active())+ | ||
"<h2>Complete</h2>"+ | ||
render(todos.completed()); | ||
}); | ||
var render = function(todos) { | ||
return "<ul>"+todos.map(function(todo){ | ||
return "<li>"+todo.name+ | ||
"<input type='checkbox' "+ | ||
(todo.isComplete() ? "checked" : "")+"/></li>"; | ||
}).join("")+"</ul>"; | ||
}; | ||
``` | ||
The following demo shows the result: | ||
@demo can-connect/docs/demos/basics.html | ||
This connection also lets you create, update, and destroy a Todo instance as follows: | ||
``` | ||
var todo = new Todo({ | ||
name: "take out trash" | ||
}) | ||
// POSTs to /api/todos name=take out trash | ||
// server returns {id: 5} | ||
todoConnection.save( todo ).then(function(todo){ | ||
todo.id //-> 5 | ||
todo.name = 'take out garbage' | ||
// PUTs to /api/todos/5 name=take out garbage | ||
// server returns {id: 5, "take out garbage"} | ||
todoConnection.save( todo ).then( function(todo){ | ||
// DELETEs to /api/todos/5 | ||
// server returns {} | ||
todoConnection.destroy( todo ).then( function(todo){ | ||
}); | ||
}); | ||
}); | ||
``` | ||
### Configure behaviors | ||
Whenever `connect` creates a connection, it always adds the [can-connect/base/base] | ||
behavior. This behavior defines configurable options that are used by almost | ||
every other behavior. For example, if your data uses an `_id` property | ||
to uniquely identify todos, you | ||
can specify this with [can-connect/base/base.idProp] like: | ||
``` | ||
var todoConnection = connect(["constructor","data-url"],{ | ||
url: "/api/todos", | ||
idProp: "_id" | ||
}); | ||
``` | ||
Other behaviors list their configurable options in their own docs page. | ||
### Overwrite behaviors | ||
If configurable options are not enough, you can overwrite any behavior with your own behavior. | ||
For example, the `constructor`'s [can-connect/constructor/constructor.updatedInstance] behavior | ||
sets the instance's properties to match the result of [can-connect/connection.updateData]. But if | ||
the `PUT /api/todos/5 name=take out garbage` request returned `{}`, the following would result in | ||
a todo with only an `id` property: | ||
``` | ||
var todo = new Todo({id: 5, name: "take out garbage"}) | ||
// PUTs to /api/todos/5 name=take out garbage | ||
// server returns {} | ||
todoConnection.save( todo ).then( function(todo){ | ||
todo.id //-> 5 | ||
todo.name //-> undefined | ||
}); | ||
``` | ||
The following overwrites the behavior of `updateData`: | ||
``` | ||
var mergeDataBehavior = { | ||
updateData: function(instance, data){ | ||
Object.assign(instance, data); | ||
} | ||
} | ||
var todoConnection = connect([ | ||
"constructor", | ||
"data-url", | ||
mergeDataBehavior | ||
],{ | ||
url: "/api/todos" | ||
}); | ||
``` | ||
You can add your own behavior that overwrite all base behaviors by adding | ||
it to the end of the behaviors list. | ||
### CanJS use | ||
If you are using CanJS, you can either: | ||
- use the [can-connect/can/map/map] behavior that overwrites | ||
many methods and settings to work with `can.Map` and `can.List`. | ||
- use the [can-connect/can/super-map/super-map] helper to create a connection that bundles "can/map" and | ||
many of the other extensions. | ||
Using [can-connect/can/map/map] to create a connection looks like: | ||
```js | ||
var Todo = can.Map.extend({ ... }); | ||
Todo.List = can.List.extend({Map: Todo},{}); | ||
var todoConnection = connect([ | ||
require("can-connect/data/url/url"), | ||
require("can-connect/can/map/map"), | ||
require("can-connect/constructor/constructor"), | ||
require("can-connect/constructor/store/store") | ||
],{ | ||
Map: Todo, | ||
url: "/todos" | ||
}); | ||
``` | ||
When you bind on a `Todo` instance or `Todo.List` list, they will automatically call | ||
[can-connect/constructor-store.addInstanceReference] and [can-connect/constructor-store.addListReference]. | ||
Using [can-connect/can/super-map/super-map] to create a connection looks like: | ||
``` | ||
var Todo = can.Map.extend({ ... }); | ||
Todo.List = can.List.extend({Map: Todo},{}); | ||
var todoConnection = superMap({ | ||
Map: Todo, | ||
url: "/todos" | ||
}); | ||
``` | ||
### ReactJS use | ||
Help us create a special ReactJS behavior that integrates | ||
a connection with React's observable life-cycle. Read more [here](#section_Otheruse). | ||
### Angular use | ||
Help us create a special AngularJS behavior that integrates | ||
a connection with Angular's observable life-cycle. Read more [here](#section_Otheruse). | ||
### Backbone use | ||
Help us create a special BackboneJS behavior that integrates | ||
a connection with Backbone's observable life-cycle. Read more [here](#section_Otheruse). | ||
### Other use | ||
Integrating `can-connect` with your framework is typically pretty easy. In general, | ||
the pattern involves creating a behavior that integrates with your framework's | ||
observable instances. The [can-connect/can/map/map] | ||
behavior can serve as a good guide. You'll typically want to implement the following | ||
in your behavior: | ||
`.instance` - Creates the appropriate observable object type. | ||
`.list` - Creates the appropriate observable array type. | ||
`.serializeInstance` - Return a plain object out of the observable object type. | ||
`.serializeList` - Return a plain array out of the observable array type. | ||
`.createdInstance` - Update an instance with data returned from `createData`. | ||
`.updatedInstance` - Update an instance with data returned from `updateData`. | ||
`.destroyedInstance` - Update an instance with data returned from `destroyData`. | ||
`.updatedList` - Update a list with raw data. | ||
And, in most frameworks you know when a particular observable is being used, typically | ||
observed, and when it can be discarded. In those places, you should call: | ||
[can-connect/constructor-store.addInstanceReference] - Call when an instance is being used. | ||
[can-connect/constructor-store.deleteInstanceReference] - Call when an instance is no longer being used. | ||
[can-connect/constructor-store.addListReference] - Call when a list is being used. | ||
[can-connect/constructor-store.deleteListReference] - Called when a list is no longer being used. | ||
## Interfaces | ||
The following is a list of the most important interface methods and properties implemented | ||
or consumed by the core behaviors. | ||
### Identifiers | ||
`.id( props | instance ) -> String` - Returns a unique identifier for the instance or raw data. | ||
`.idProp -> String="id"` - The name of the unique identifier property. | ||
`.listSet(list) -> set` - Returns the set a list represents. | ||
`.listSetProp -> String="__listSet"` - The property on a List that contains its set. | ||
Implemented by [can-connect/base/base]. | ||
### Instance Interface | ||
The following methods operate on instances and lists. | ||
#### CRUD methods: | ||
`.getList(set) -> Promise<List>` - retrieve a list of instances. | ||
`.getList(set) -> Promise<Instance>` - retrieve a single instance. | ||
`.save(instance) -> Promise<Instance>` - creates or updates an instance. | ||
`.destroy(instance) -> Promise<Instance>` - destroys an instance. | ||
Implemented by [can-connect/constructor/constructor]. Overwritten by [can-connect/constructor/store/store]. | ||
#### Instance callbacks | ||
`.createdInstance(instance, props)` - An instance is created. | ||
`.updatedInstance(instance, props)` - An instance is updated. | ||
`.destroyedInstance(instance, props)` - An instance is destroyed. | ||
`.updatedList(list, updatedListData, set)` - A list has been updated. | ||
Implemented by [can-connect/constructor/constructor]. Overwritten by [data-connect/real-time], | ||
[can-connect/constructor/callbacks-once]. | ||
#### Hydrators and Serializers | ||
`.instance(props) -> Instance` - Creates an instance given raw data. | ||
`.list({data: Array<Instance>}) -> List` - Creates a list given an array of instances. | ||
`.hydrateInstance(props) -> Instance` - Provides an instance given raw data. | ||
`.hydrateList({ListData}, set) -> List` - Provides a list given raw data. | ||
`.hydratedInstance(instance)` - Called whenever an instance is created in memory. | ||
`.hydratedList(list, set)` - Called whenever a list is created in memory. | ||
`.serializeInstance(instance) -> Object` - Returns the serialized form of an instance. | ||
`.serializeList(list) -> Array<Object>` - Returns the serialized form of a list and its instances. | ||
Implemented by [can-connect/constructor/constructor]. Overwritten by [can-connect/constructor/store/store], | ||
[can-connect/fall-through-cache/fall-through-cache]. | ||
### Data Interface | ||
The raw-data connection methods. | ||
#### CRUD methods | ||
`.getListData(set) -> Promise<ListData>` - Retrieves list data. | ||
`.updateListData(listData[, set]) -> Promise<ListData>` - Update a list's data. | ||
`.getSets() -> Promise<Array<Set>>` - Returns the sets available to the connection. | ||
`.getData(params) -> Promise<Object>` - Retrieves data for a particular item. | ||
`.createData(props, cid) -> Promise<props>` - Creates instance data given the serialized form of the data. | ||
A client ID is passed of the | ||
instance that is being created. | ||
`.updateData(props) -> Promise<props>` - Updates instance data given the | ||
serialized form of the data. | ||
`.destroyData(props) -> Promise<props>` - Destroys an instance given the seralized | ||
form of the data. | ||
`.clear() -> Promise` - Clears all data in the connection. | ||
Implemented by [can-connect/data/url/url], | ||
[can-connect/data/localstorage-cache/localstorage-cache], [can-connect/data/memory-cache/memory-cache]. | ||
Overwritten by [can-connect/cache-requests/cache-requests], [can-connect/data/combine-requests/combine-requests/combine-requests], | ||
[can-connect/data/inline-cache/inline-cache], [can-connect/fall-through-cache/fall-through-cache]. | ||
Consumed by [can-connect/constructor/constructor]. | ||
#### Data Callbacks | ||
`.gotListData(listData, set) -> ListaData` - List data is retrieved. | ||
`.gotData( props, params) -> props` - Instance data is retreived. | ||
`.createdData( props, params, cid) -> props` - An instance's data is created. | ||
`.updatedData( props, params) -> props` - An instance's data is updated. | ||
`.destroyedData( props, params) -> props` - An instance's data is destroyed. | ||
Implemented by [can-connect/data/callbacks/callbacks]. Overwritten by [can-connect/data/callbacks-cache/callbacks-cache], | ||
[can-connect/real-time/real-time]. | ||
#### Response parsers | ||
`.parseListData(*) -> ListData` - Given the response of getListData, return the right object format. | ||
`.parseInstanceData(*) -> props` - Given the response of getData, createData, updateData, and destroyData, | ||
return the right object format. | ||
Implemented by [can-connect/data/parse/parse]. | ||
#### Store Interface | ||
`.addInstanceReference(instance)` - Signal that memory-unsafe actions can be performed on the instance. | ||
`.deleteInstanceReference(instance)` - Signal that memory-unsafe actions should be removed. | ||
`.addListReference(list)` - Signal that memory-unsafe actions can be performed on the list. | ||
`.deleteListReference(list)` - Signal that memory-unsafe actions should be removed. | ||
Implemented by [can-connect/constructor/store/store]. | ||
#### Real-time Methods | ||
`createInstance( props ) -> Promise<instance>` - Inform the connection an instance has been created. | ||
`updateInstance( props ) -> Promise<instance>` - Inform the connection an instance has been updated. | ||
`destroyInstance( props ) -> Promise<instance>` - Inform the connection an instance has been destroyed. | ||
Implemented by [can-connect/real-time/real-time]. | ||
## Creating Behaviors | ||
To create your own behavior, call `connect.behavior` with the name of your behavior and a function that | ||
returns an object that defines the hooks you want to overwrite or provide: | ||
```js | ||
connect.behavior("my-behavior", function(baseBehavior){ | ||
return { | ||
// Hooks here | ||
}; | ||
}) | ||
``` | ||
For example, creating a simple localStorage behavior might look like: | ||
```js | ||
connect.behavior("localstorage", function(baseBehavior){ | ||
return { | ||
getData: function(params){ | ||
var id = this.id(params); | ||
return new Promise(function(resolve){ | ||
var data = localStorage.getItem(baseBehavior.name+"/"+id); | ||
resolve( JSON.parse(data) ) | ||
}); | ||
}, | ||
createData: function(props){ | ||
var id = localStorage.getItem(baseBehavior.name+"-ID") || "0"; | ||
var nextId = ++JSON.parse( id ); | ||
localStorage.setItem(baseBehavior.name+"-ID"), nextId); | ||
var id = this.idProp; | ||
return new Promise(function(resolve){ | ||
props[id] = nextId; | ||
localStorage.setItem(baseBehavior.name+"/"+nextId, props); | ||
resolve( props ) | ||
}); | ||
}, | ||
updateData: function(){ ... }, | ||
destroyData: function(){ ...} | ||
}; | ||
}) | ||
``` | ||
# can-fixture | ||
# can-fixture | ||
For more information, please checkout [CanJS's can-connect docs](http://canjs.github.io/canjs/doc/can-connect.html) |
@@ -17,3 +17,3 @@ | ||
* | ||
* @signature `cacheRequests( baseConnction )` | ||
* @signature `cacheRequests( baseConnection )` | ||
* | ||
@@ -20,0 +20,0 @@ * Overwrites [can-connect/cache-requests/cache-requests.getListData] to use set logic to |
@@ -11,3 +11,23 @@ @module {function} can-connect | ||
@signature `connect(behaviors, options)` | ||
Goes through every behavior and assembles them into a final | ||
connection. | ||
```js | ||
var connect = require("can-connect"); | ||
var todosConnection = connect([ | ||
require("can-connect/data/url/url"), | ||
require("can-connect/data/constructor/constructor") | ||
],{ | ||
url: "/api/todos" | ||
}); | ||
``` | ||
@param {Array<can-connect/Behavior>} behaviors An array of | ||
behaviors that will be used to compose the final connection. | ||
@param {Object} options an object of configuration | ||
options. | ||
@body | ||
@@ -199,3 +219,3 @@ | ||
@demo can-connect/docs/demos/basics.html | ||
@demo demos/can-connect/basics.html | ||
@@ -202,0 +222,0 @@ This connection also lets you create, update, and destroy a Todo instance as follows: |
@@ -232,3 +232,3 @@ "use strict"; | ||
}); | ||
list.__listSet = set; | ||
@@ -366,3 +366,3 @@ return list; | ||
/** | ||
* @function CanMap.getList getList | ||
* @function can-connect/can/map/map.getList getList | ||
* @parent can-connect/can/map/map.map-static | ||
@@ -382,3 +382,7 @@ * | ||
* ``` | ||
* var Todo = CanMap.extend({}); | ||
* var Todo = DefineMap.extend({ | ||
* id: "number", | ||
* complete: "boolean", | ||
* name: "string" | ||
* }); | ||
* | ||
@@ -405,6 +409,6 @@ * connect([ | ||
/** | ||
* @function CanMap.getList getList | ||
* @function can-connect/can/map/map.findAll findAll | ||
* @parent can-connect/can/map/map.map-static | ||
* | ||
* Alias of [CanMap.getList]. You should use `.getList()`. | ||
* Alias of [can-connect/can/map/map.getList]. You should use `.getList()`. | ||
*/ | ||
@@ -417,3 +421,3 @@ findAll: function (base, connection) { | ||
/** | ||
* @function CanMap.get get | ||
* @function can-connect/can/map/map.get get | ||
* @parent can-connect/can/map/map.map-static | ||
@@ -426,3 +430,3 @@ * | ||
* @param {Object} [params] | ||
* @return {Promise<CanMap>} | ||
* @return {Promise<Map>} | ||
* | ||
@@ -434,3 +438,7 @@ * @body | ||
* ```js | ||
* var Todo = CanMap.extend({}); | ||
* var Todo = DefineMap.extend({ | ||
* id: "number", | ||
* complete: "boolean", | ||
* name: "string" | ||
* }); | ||
* | ||
@@ -458,6 +466,6 @@ * connect([ | ||
/** | ||
* @function CanMap.findOne findOne | ||
* @function can-connect/can/map/map.findOne findOne | ||
* @parent can-connect/can/map/map.map-static | ||
* | ||
* Alias of [CanMap.get]. You should use `.get()`. | ||
* Alias of [can-connect/can/map/map.get]. You should use `.get()`. | ||
*/ | ||
@@ -501,3 +509,3 @@ findOne: function (base, connection) { | ||
/** | ||
* @function CanMap.prototype.isNew isNew | ||
* @function can-connect/can/map/map.prototype.isNew isNew | ||
* @parent can-connect/can/map/map.map | ||
@@ -522,3 +530,3 @@ * | ||
/** | ||
* @function CanMap.prototype.isSaving isSaving | ||
* @function can-connect/can/map/map.prototype.isSaving isSaving | ||
* @parent can-connect/can/map/map.map | ||
@@ -541,3 +549,3 @@ * | ||
/** | ||
* @function CanMap.prototype.isDestroying isDestroying | ||
* @function can-connect/can/map/map.prototype.isDestroying isDestroying | ||
* @parent can-connect/can/map/map.map | ||
@@ -547,7 +555,15 @@ * | ||
* | ||
* @signature `map.isSaving()` | ||
* @signature `map.isDestroying()` | ||
* | ||
* Returns `true` if .destroy() has been called, but has not resolved yet. | ||
* Observes if the promise returned by `.destroy()` has completed. This is | ||
* often used in template like: | ||
* | ||
* @return {Boolean} | ||
* ``` | ||
* <button ($click)="todo.destroy()" | ||
* {{#todo.isDestroying}}disabled{{/todo.isDestroying}}> | ||
* X | ||
* </button> | ||
* ``` | ||
* | ||
* @return {Boolean} `true` if `.destroy()` has been called but is not resolved yet. | ||
*/ | ||
@@ -561,3 +577,3 @@ return function () { | ||
/** | ||
* @function CanMap.prototype.save save | ||
* @function can-connect/can/map/map.prototype.save save | ||
* @parent can-connect/can/map/map.map | ||
@@ -580,3 +596,7 @@ * | ||
* ``` | ||
* var Todo = CanMap.extend({}); | ||
* var Todo = DefineMap.extend({ | ||
* id: "number", | ||
* complete: "boolean", | ||
* name: "string" | ||
* }); | ||
* | ||
@@ -604,3 +624,3 @@ * connect([ | ||
/** | ||
* @function CanMap.prototype.destroy destroy | ||
* @function can-connect/can/map/map.prototype.destroy destroy | ||
* @parent can-connect/can/map/map.map | ||
@@ -621,3 +641,7 @@ * | ||
* ``` | ||
* var Todo = CanMap.extend({}); | ||
* var Todo = DefineMap.extend({ | ||
* id: "number", | ||
* complete: "boolean", | ||
* name: "string" | ||
* }); | ||
* | ||
@@ -624,0 +648,0 @@ * connect([ |
@@ -5,2 +5,3 @@ var connect = require("can-connect"); | ||
var canMap = require("../map/"); | ||
var canRef = require("../ref/"); | ||
var constructorStore = require("../../constructor/store/"); | ||
@@ -18,2 +19,3 @@ var dataCallbacks = require("../../data/callbacks/"); | ||
var $ = require("jquery"); | ||
@@ -26,2 +28,3 @@ | ||
canMap, | ||
canRef, | ||
constructorStore, | ||
@@ -28,0 +31,0 @@ dataCallbacks, |
@@ -54,3 +54,3 @@ var assign = require("can-util/js/assign/assign"); | ||
"constructor","constructor/store","can/map", | ||
"constructor","constructor/store","can/map","can/ref", | ||
"fall-through-cache","data/inline-cache", | ||
@@ -57,0 +57,0 @@ |
@@ -114,2 +114,7 @@ | ||
* A WeakReferenceMap that contains instances being created by their `._cid` property. | ||
* | ||
* @type {can-connect/helpers/weak-reference-map} | ||
* | ||
* The `cidStore` is used to temporarily hold references to instances by [can-util/js/cid/cid] that don't | ||
* yet have an id which are in the process of being created. | ||
*/ | ||
@@ -558,4 +563,6 @@ cidStore: new WeakReferenceMap(), | ||
* | ||
* @signature `` | ||
* @signature `connection.isNew(instance)` | ||
* | ||
* Checks that the instance has an [can-connect/base/base.id]. | ||
* | ||
* @param {Object} instance The instance to test. | ||
@@ -562,0 +569,0 @@ * @return {Boolean} `true` if the instance has not been persisted. |
@@ -84,11 +84,20 @@ /** | ||
var sortedSetJSON = require("can-connect/helpers/sorted-set-json"); | ||
var canEvent = require("can-event"); | ||
var assign = require("can-util/js/assign/assign"); | ||
// shared across all connections | ||
var pendingRequests = 0; | ||
var noRequestsTimer = null; | ||
var requests = { | ||
increment: function(connection){ | ||
pendingRequests++; | ||
clearTimeout(noRequestsTimer); | ||
}, | ||
decrement: function(connection){ | ||
pendingRequests--; | ||
if(pendingRequests === 0) { | ||
noRequestsTimer = setTimeout(function(){ | ||
requests.dispatch("end"); | ||
},10); | ||
} | ||
}, | ||
@@ -99,3 +108,5 @@ count: function(){ | ||
}; | ||
assign(requests, canEvent); | ||
var constructorStore = connect.behavior("constructor/store",function(baseConnect){ | ||
@@ -105,12 +116,34 @@ | ||
/** | ||
* @property {WeakReferenceMap} can-connect/constructor/store/store.instanceStore instanceStore | ||
* @property {can-connect/helpers/weak-reference-map} can-connect/constructor/store/store.instanceStore instanceStore | ||
* @parent can-connect/constructor/store/store.stores | ||
* | ||
* A store of instances mapped by [can-connect/base/base.id]. | ||
* | ||
* @type {can-connect/helpers/weak-reference-map} | ||
* | ||
* Stores instances by their [can-connect/base/base.id] which have had | ||
* [can-connect/constructor/store/store.addInstanceReference] called more | ||
* times than [can-connect/constructor/store/store.deleteInstanceReference]. | ||
* | ||
* ```js | ||
* connection.addInstanceReference(todo5); | ||
* connection.instanceStore.get("5") //-> todo5 | ||
* ``` | ||
*/ | ||
instanceStore: new WeakReferenceMap(), | ||
/** | ||
* @property {WeakReferenceMap} can-connect/constructor/store/store.listStore listStore | ||
* @property {can-connect/helpers/weak-reference-map} can-connect/constructor/store/store.listStore listStore | ||
* @parent can-connect/constructor/store/store.stores | ||
* A store of lists mapped by [can-connect/base/base.listSet]. | ||
* | ||
* @type {can-connect/helpers/weak-reference-map} | ||
* | ||
* Stores lists by their [can-connect/base/base.listSet] which have had | ||
* [can-connect/constructor/store/store.addListReference] called more | ||
* times than [can-connect/constructor/store/store.deleteListReference]. | ||
* | ||
* ```js | ||
* connection.addInstanceReference(allTodos,{}); | ||
* connection.instanceStore.get({}) //-> allTodos | ||
* ``` | ||
*/ | ||
@@ -397,3 +430,4 @@ listStore: new WeakReferenceMap(), | ||
* | ||
* No matter what, [can-connect/constructor/store/store.hydratedInstance] is called. | ||
* @param {Object} props The raw data used to create an instance. | ||
* @return {Instance} A typed instance created or updated from `props`. | ||
*/ | ||
@@ -446,3 +480,3 @@ // Overwrites hydrateInstance so it looks in the store and calls hydratedInstance. | ||
* | ||
* @signature `connection.hydrateList(props)` | ||
* @signature `connection.hydrateList( listData, set )` | ||
* | ||
@@ -454,3 +488,5 @@ * Overwrites the base `hydrateList` so that if a matching list is | ||
* | ||
* No matter what, [can-connect/constructor/store/store.hydratedList] is called. | ||
* @param {can-connect.listData} listData List data to hyrate into a list type. | ||
* @param {can-set/Set} set The set that represents the data in `listData`. | ||
* @return {List} A list from either the store or a newly created instance. | ||
*/ | ||
@@ -478,2 +514,10 @@ hydrateList: function(listData, set){ | ||
* | ||
* @signature `connection.getList( set )` | ||
* | ||
* Increments the request counter so these instances will be stored | ||
* and then decrements it after the request is complete. | ||
* | ||
* | ||
* @param {can-set/Set} set Params used to specify which list to retrieve. | ||
* @return {Promise<instance>} The promise returned by the base connection's [can-connect/connection.getList]. | ||
*/ | ||
@@ -499,2 +543,11 @@ getList: function(params) { | ||
* store until the response resolves. | ||
* | ||
* @signature `connection.get( params )` | ||
* | ||
* Increments the request counter so this instance will be stored | ||
* and then decrements it after the request is complete. | ||
* | ||
* | ||
* @param {Object} params Params used to specify which instance to retrieve. | ||
* @return {Promise<instance>} The promise returned by the base connection's [can-connect/connection.get]. | ||
*/ | ||
@@ -522,2 +575,17 @@ get: function(params) { | ||
* | ||
* @signature `connection.save( instance )` | ||
* | ||
* Increments the request counter so this instance will be stored | ||
* and then decrements it after the request is complete. | ||
* | ||
* ``` | ||
* var promise = connection.save(todo5); | ||
* connection.instanceStore.get("5") //-> todo5 | ||
* promise.then(function(){ | ||
* connection.instanceStore.has("5") //-> false | ||
* }) | ||
* ``` | ||
* | ||
* @param {Object} instance An typed instance. | ||
* @return {Promise<instance>} The promise returned by the base connection's [can-connect/connection.save]. | ||
*/ | ||
@@ -552,2 +620,18 @@ save: function(instance) { | ||
* store until the response resolves. | ||
* | ||
* @signature `connection.destroy( instance )` | ||
* | ||
* Increments the request counter so this instance will be stored | ||
* and then decrements it after the request is complete. | ||
* | ||
* ``` | ||
* var promise = connection.destroy(todo5); | ||
* connection.instanceStore.get("5") //-> todo5 | ||
* promise.then(function(){ | ||
* connection.instanceStore.has("5") //-> false | ||
* }) | ||
* ``` | ||
* | ||
* @param {Object} instance An typed instance. | ||
* @return {Promise<instance>} The promise returned by the base connection's [can-connect/connection.destroy]. | ||
*/ | ||
@@ -554,0 +638,0 @@ destroy: function(instance) { |
@@ -201,3 +201,14 @@ | ||
* @option {Number} Defaults to `1` which means that only requests made within the same | ||
* "thread of execution" will be combined. | ||
* "thread of execution" will be combined. Increasing this number will mean | ||
* that requests are going to be delayed that length of time in case other requests | ||
* are made. Generally speaking, there's no good reason to increase the amount of time. | ||
* | ||
* ``` | ||
* connect([ | ||
* require("can-connect/data/combine-requests/combine-requests"), | ||
* ... | ||
* ],{ | ||
* time: 100 | ||
* }) | ||
* ``` | ||
*/ | ||
@@ -204,0 +215,0 @@ time:1, |
@@ -197,2 +197,20 @@ /** | ||
* | ||
* Removes all instances and lists being stored in memory. | ||
* | ||
* ``` | ||
* var cacheConnection = connect([ | ||
* require("can-connect/data/memory-cache/memory-cache") | ||
* ],{}); | ||
* | ||
* cacheConnection.updateInstance({id: 5, name: "justin"}); | ||
* | ||
* cacheConnection.getData({id: 5}).then(function(data){ | ||
* data //-> {id: 5, name: "justin"} | ||
* cacheConnection.clear(); | ||
* cacheConnection.getData({id: 5}).catch(function(err){ | ||
* err -> {message: "no data", error: 404} | ||
* }); | ||
* }); | ||
* ``` | ||
* | ||
*/ | ||
@@ -199,0 +217,0 @@ clear: function(){ |
@@ -76,2 +76,4 @@ | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.getListData] for more information. | ||
*/ | ||
@@ -88,2 +90,4 @@ ["getListData", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.updateListData] for more information. | ||
*/ | ||
@@ -100,2 +104,4 @@ "updateListData", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.getSets] for more information. | ||
*/ | ||
@@ -112,2 +118,4 @@ "getSets", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.clear] for more information. | ||
*/ | ||
@@ -124,2 +132,4 @@ "clear", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.getData] for more information. | ||
*/ | ||
@@ -136,2 +146,4 @@ "getData", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.createData] for more information. | ||
*/ | ||
@@ -148,2 +160,4 @@ "createData", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.updateData] for more information. | ||
*/ | ||
@@ -160,2 +174,4 @@ "updateData", | ||
* shares this connection's [can-connect/data/worker/worker.name]. | ||
* | ||
* See [can-connect/connection.destroyData] for more information. | ||
*/ | ||
@@ -162,0 +178,0 @@ "destroyData"].forEach(function(name){ |
@module can-connect/data/worker/worker | ||
@parent can-connect.behaviors | ||
@group can-connect/data/worker/worker.identifiers Identifiers | ||
@group can-connect/data/worker/worker.identifiers Options | ||
@group can-connect/data/worker/worker.data Data Methods | ||
@@ -5,0 +5,0 @@ |
@@ -56,3 +56,3 @@ /** | ||
* | ||
* @demo can-connect/src/fall-through-cache/fall-through-cache.html | ||
* @demo ../../demos/can-connect/fall-through-cache.html | ||
* | ||
@@ -59,0 +59,0 @@ * Clicking |
@@ -69,3 +69,3 @@ /** | ||
* | ||
* @demo can-connect/src/real-time/real-time.html | ||
* @demo ../../demos/can-connect/real-time.html | ||
* | ||
@@ -296,4 +296,10 @@ * This example creates a `todoList` function and `todoItem` function | ||
* | ||
* @param {Object} props | ||
* @param {Object} params | ||
* @signature `connection.destroyedData(props, params)` | ||
* | ||
* Gets the instance for this request. Then tests if the instance | ||
* is in any list in the [can-connect/constructor/store/store.listStore]. If | ||
* it is, removes the instance from the list. | ||
* | ||
* @param {Object} props The properties of the destroyed instance. | ||
* @param {Object} [params] The parameters used to destroy the data. | ||
*/ | ||
@@ -300,0 +306,0 @@ destroyedData: function(props, params){ |
8
11447
433223
15
9
+ Addedcan-define@^0.7.17
+ Addedcan-define@0.7.29(transitive)
Updatedcan-observation@^3.0.0-pre.5
Updatedcan-set@^0.6.0-pre.6