The Minimongo insert/update/remove handlers are now implemented as
standard method invocations over the wire, though the client and server
implementations remain separate code paths.
Return values from server-side methods now get sent back to the client
via a 'result' message, but that result isn't wired up to anything
client-side yet.
Server now informs client when outstanding subscriptions and methods
invocations are fully reflected in 'data' messages back to the client.
For now, high-level behavior is the same. When the transport
disconnects, client doesn't attempt to reuse previous session.
Server always establishes a new Live Data session with each connect.
Server does not support method reply cache, and won't honor a client's
attempt to reuse a previous Live Data session id.
* remove() removes all documents in collection (previously, had to
explicitly pass {} selector to MM).
* update() requires {multi: true} to update multiple documents.
Previously we defaulted to true, now multi defaults to false.
In Livedata and Minimongo, make falsey selectors match no documents,
instead of all documents. Same for {_id: undefined}. This is a
departure from most MongoDB drivers, but offers a safety belt around
selectors that are rarely useful and easy to accidentally create
programmatically.
For remove(), also protect against accidentally destroying an entire
collection when passing no args. To empty a collection, pass the
wildcard selector explicitly: foo.remove({});
For find(), keep the standard mongo behavior of returning all documents
when no selector is passed in by explicitly checking arguments.length.
This change also makes typical read cases cleaner, allowing:
x = foo.findOne(Session.get('foo_id'));
instead of
x = Session.get('foo_id') && foo.findOne(Session.get('foo_id'));
The new Collection API separates query handles from result sets. It
allows template iterators to only redraw changed objects instead of
entire result sets. This implementation also sets the stage for
minimongo indexes and better invalidation performance.
collection.find() now returns a Collection.Query handle. To retrieve
results we provide these methods on Collection.Query:
Iterators (encouraged way to access results):
* query.forEach(function (obj) { ... });
* results = query.map(function (obj) { ... });
Cursor-based retrieval (iterators are built on fetch):
* docs = query.fetch(maxlen); // return next [maxlen] (all) docs.
* doc = query.get(skip); // return next doc, skipping [skip] (0) docs.
Counter:
* length = query.count(); // number of results in query.
Live queries (replaces findLive):
* live_handle = query.observe({added: function (obj, idx) { ... },
removed: function (id, idx) { ... },
changed: function (obj, idx) { ... },
moved: function (obj, old_idx, new_idx) { ... }});
Convenience finders:
* doc = collection.findOne({color: 'red'});
* doc = collection.findOne(id_val);
On the client, calling forEach(), map(), fetch(), get(), or findOne()
inside an invalidation context will register a dependency on the entire
query result. Any change to any objects invalidates the context.
Calling count() inside an invalidation context will register a
dependency that only triggers if objects enter or leave the result set.
Calling observe() does not register a dependency.