These are the approximate spec changes that would happen. See IDBObservers.webidl for the WebIDL file.
A transaction has list of pending observers to create (with the options & callback function), and a list of changes per object store (with the operation type, key, and optional value).
When the observe method is called on a transaction, the given options, callback, and the transaction's object stores are given a unique id and are stored in a pending_observer_construction
list as an Observer
. This id is given to the observer control, which is returned. When the transaction is completed successfuly, the Observer is added to the domain-specific list of observers. If the transaction is not completed successfuly, this does not happen.
Every change would record an entry in the change_list
for the given object store.
When a transaction successfully completes, send the change_list
changes to all observers that have objects stores touched by the completed transaction. When sending the changes to each observer, all changes to objects stores not observed by the observer are filtered out.
The transactions given to the observers have one behavior difference - they cannot be used by an observer. This probably means we'll need to give them a new type - perhaps 'snapshot' or 'readonly-snapshot'.
An exception is thrown in the following cases (and in the following order):
.observe
on a database that is closed..observe
on a 'versionchange' transaction..observe
on a transaction that is finished..observe
on a trThese are the approximate spec changes that would happen. See IDBObservers.webidl for the WebIDL file.
The following extra 'hidden variables' will be kept track of in the spec inside of IDBTransaction:
pending_observer_construction
- a list of {uuid string, options map, callback function} tuples.change_list
- a per-object-store list of { operation string, optional key IDBKeyRange, optional value object}. The could be done as a map of object store name to the given list.
When the observe method is called on a transaction, the given options, callback, and the transaction's object stores are given a unique id and are stored in a pending_observer_construction
list as an Observer
. This id is given to the observer control, which is returned. When the transaction is completed successfuly, the Observer is added to the domain-specific list of observers. If the transaction is not completed successfuly, this does not happen.
Every change would record an entry in the change_list
for the given object store.
When a transaction successfully completes, send the change_list
changes to all observers that have objects stores touched by the completed transaction. When sending the changes to each observer, all changes to objects stores not observed by the observer are filtered out.
The transactions given to the observers have one behavior difference - they cannot be used by an observer. This probably means we'll need to give them a new type - perhaps 'snapshot' or 'readonly-snapshot'.
Non-idl-possible exceptions are thrown in the following cases (and in the following order):
.observe
on a database that is closed..observe
on a 'versionchange' transaction..observe
on a transaction that is finished..observe
on a transaction that is not active..observe
on a 'snapshot' type transaction (or whatever we call it - a transaction given in an observer callback)..unobserve
on a database connection that isn't being observed.
This is a possible future feature, referenced in the main Explainer.
Whenever a change succeeds in a transaction, it adds it to a culled_change_list
for the given object store in the following manner:
(Note: putAll
and addAll
operations could be seperated into individual put and add changes.)
Append the add operation, key and value, on end of operations list.
- Iterate backwards in the
culled_change_list
and look for any 'add', 'put' or 'delete' change with an intersecting key. - If a put is reached, delete that entry from the list.
- If an add is reached, replace the value of the add with the new put value and return.
- If a delete is reached, then append the new put at the end of operations and return.
- If the end of the list is reached, then append the new put at the end of operations and return.
- Iterate backwards in the
culled_change_list
and look for any 'add', 'put' or 'delete' change with an intersecting key. - If a put is reached, delete that entry from the list.
- If an add is reached, delete that entry from the list.
- If a delete is reached, modify the reached delete to be a union of it's current range and the new delete range.
- If we reach the end of the operations list and the new delete was never combined with an older delete, append the delete to the list of operations.
- Clear the
culled_change_list
for that object store. - Add a 'clear' operation to list.ansaction that is not active.
.observe
on a 'snapshot' type transaction (or whatever we call it - a transaction given in an observer callback)..observe
invalid optionsoperations
is not specified- `operations' is empty
operations
contains unknown operation types (not 'add', 'put', 'clear', or 'delete')ranges
contains object stores not in the observing transaction.unobserve
on a database connection that isn't being observed.