Automerge adheres to Semantic Versioning for assigning version numbers. However, any feature that is not documented or labelled as "experimental" may change without warning in a minor release.
All notable changes to Automerge will be documented in this file, which is based on Keep a Changelog.
- Changed: The data format for storing/transmitting changes (as returned by
Automerge.getChanges()
) and documents (as returned byAutomerge.save()
) have changed. They now use a binary encoding that is much more compact than the old JSON format. This is a breaking change, but we will provide an upgrade tool to migrate any existing Automerge docs to the new format. - Changed:
Automerge.applyChanges()
now returns a two-element array, where the first element is the updated document, and the second element is a patch describing the changes that have been made (including any conflicts that have arisen). This simplifies applications that need to update some other state, such as a user interface, to reflect changes in a document. - Changed #339:
Automerge.Connection
,Automerge.DocSet
, andAutomerge.WatchableDoc
have been removed, and replaced with a new Automerge sync protocol that is implemented by the functionsAutomerge.generateSyncMessage()
andAutomerge.receiveSyncMessage()
. (@ept, @pvh, @orionz, @alexjg, @jeffa5) - Changed: The frontend/backend protocol (change requests generated by
Frontend.change()
and patches returned byBackend.applyChanges()
) has changed. The new format will be documented separately. - Removed: The undo/redo feature is removed for now. The original implementation was a bit of a hack, and we decided not to support the hack for 1.0. Instead, we will bring back a better-designed version of this feature in the future.
- Changed: Actor IDs are now required to consist only of lowercase hexadecimal digits (UUIDs can still be used, but the hyphens need to be removed).
- Changed:
Automerge.getConflicts()
now returns all conflicting values, including the value chosen as default resolution. - Changed: Multiple references to the same object in an Automerge document are no longer allowed. In other words, the document is now required to be a tree, not a DAG.
- Changed: We no longer assume that the backend state is immutable, giving us greater freedom
to implement the backend in a way that maximises performance. (Frontend state and Automerge
documents remain immutable as before.) This restricts certain usage patterns: for example, if
you update a document, you cannot then take a reference to the document state before that
update and update or query it. If you want to be able to continue referencing an old document
state, you can copy it using
Automerge.clone()
. - Removed:
Automerge.diff
andBackend.merge
, because they depended on the assumption of an immutable backend. We hope to bring back a better implementation ofAutomerge.diff
in the future. - Changed: Dependencies between changes are now expressed by referencing the hashes of
dependencies, rather than their actorId and sequence number. APIs have changed accordingly:
Backend.getMissingDeps
now returns a list of hashes rather than a vector clock; the second argument ofBackend.getChanges()
is now also a list of hashes. This change also affects network sync protocols, e.g. based onAutomerge.Connection
, which need to now exchange hashes rather than vector clocks. - Removed:
Automerge.getMissingDeps()
; useBackend.getMissingDeps()
instead. - Removed:
Backend.getMissingChanges()
; useBackend.getChanges()
instead. - Removed:
Backend.getChangesForActor()
since it does not fit with a hash chaining approach. - Added:
Frontend.getLastLocalChange()
returns the binary encoding of the last change made by the local actor, andBackend.getHeads()
returns the latest change hashes in the current document state. - Changed:
Backend.applyLocalChange()
now returns an array of three values: the updated backend state, the patch to apply to the frontend, and the binary encoding of the change. - Added #308: Experimental
Automerge.Observable
API allows an application to receive a callback whenever a document (or some object within a document) changes (@ept)
0.14.2 — 2021-01-12
- Fixed #301: Handling out-of-bounds argument in
Array.slice()
(@pierreprinetti) - Fixed #261: Support calling
Array.indexOf()
with an object (@philschatz)
0.14.1 — 2020-05-25
- Fixed #249: Corrected TypeScript declaration for
Automerge.Table.rows
(@lauritzsh) - Fixed #252: Corrected TypeScript declaration for
WatchableDoc
(@vincentcapicotto) - Fixed #258: Changes whose dependencies are missing are now preserved when saving and reloading a document (@KarenSarmiento, @ept)
- Changed #260: If you try to assign an object that is already in an Automerge document, you now get a more descriptive error message (@johannesjo, @ept)
0.14.0 — 2020-03-25
- Removed #236: Undocumented
Automerge.Table
API that allowed rows to be added by providing an array of values. Now rows must be given as an object (@HerbCaudill) - Removed #241: Constructor of
Automerge.Table
no longer takes an array of columns, and thecolumns
property ofAutomerge.Table
is also removed (@ept) - Changed #242: Rows of
Automerge.Table
now automatically get anid
property containing the primary key of that row (@ept) - Removed #243:
Automerge.Table
objects no longer have aset()
method. Useadd()
orremove()
instead (@ept) - Removed support for Node 8, which is no longer being maintained
- Added #194, #238:
Automerge.Text
objects may now contain objects as well as strings; new methodText.toSpans()
that concatenates characters while leaving objects unchanged (@pvh, @ept, @nornagon)
0.13.0 — 2020-02-24
- Added #232: New API
Automerge.getAllChanges()
returns all changes (@ept) - Fixed #230:
Text.deleteAt
allows zero characters to be deleted (@skokenes) - Fixed #219:
canUndo
is false immediately afterAutomerge.from
(@ept) - Fixed [#215]: Adjust TypeScript definition of
Freeze<T>
(@jeffpeterson)
0.12.1 — 2019-08-22
- Fixed #184: Corrected TypeScript type definition for
Automerge.DocSet
(@HerbCaudill) - Fixed #174: If
.filter()
,.find()
or similar methods are used inside a change callback, the objects they return can now be mutated (@ept, @airhorns) - Fixed #199:
Automerge.Text.toString()
now returns the unadulterated text (@Gozala) - Added #210: New method
DocSet.removeDoc()
(@brentkeller)
0.12.0 — 2019-08-07
- Changed #183:
Frontend.from()
now accepts initialization options (@HerbCaudill, @ept) - Changed #180: Mutation methods on
Automerge.Text
are now available without having to assign the object to a document (@ept) - Added #181: Can now specify an initial value when creating
Automerge.Text
objects (@Gozala, @ept) - Fixed #202: Stack overflow error when making large changes (@HerbCaudill, @ept)
0.11.0 — 2019-07-13
- Added #127: New
Automerge.from
function creates a new document and initializes it with an initial state given as an argument (@HerbCaudill, @ept) - Added #155: Type definitions now allow TypeScript applications to use Automerge with static type-checking (@HerbCaudill, @airhorns, @aslakhellesoy, @ept)
- Changed #177: Automerge documents are no longer made immutable with
Object.freeze
by default, due to the performance cost. Use the{freeze: true}
option to continue using immutable objects. (@izuchukwu, @ept) - Fixed #165: Undo/redo now work when using separate frontend and backend (@ept)
0.10.1 — 2019-05-17
- Fixed #151: Exception "Duplicate list element ID" after a list element was added and removed again in the same change callback (@ept, @minhhien1996)
- Changed #163: Calling
JSON.stringify
on an Automerge document containingAutomerge.Text
,Automerge.Table
orAutomerge.Counter
now serializes those objects in a clean way, rather than dumping the object's internal properties (@ept)
0.10.0 — 2019-02-04
- Added #29: New
Automerge.Table
datatype provides an unordered collection of records, like a relational database (@ept) - Added #139: JavaScript Date objects are now supported in Automerge documents (@ept)
- Added #147: New
Automerge.Counter
datatype provides a CRDT counter (@ept) - Removed #148:
Automerge.inspect
has been removed (@ept) - Fixed #145: Exception "Duplicate list element ID" after reloading document from disk (@ept)
- Changed #150: Underscore-prefixed property names are now allowed in map objects;
doc.object._objectId
is nowAutomerge.getObjectId(doc.object)
,doc.object._conflicts.property
is nowAutomerge.getConflicts(doc.object, 'property')
, anddoc._actorId
is nowAutomerge.getActorId(doc)
. (@ept)
0.9.2 — 2018-11-05
- Fixed #128: Fixed crash when Text object was modified in the same change as another object (@CGNonofr)
- Fixed #129: Prevent application of duplicate requests in
applyLocalChange()
(@ept) - Changed #130: Frontend API no longer uses
Frontend.getRequests()
; instead, frontend change functions now return request objects directly (@ept)
0.9.1 — 2018-09-27
- Changed #126: Backend no longer needs to know the actorId of the local node (@ept)
- Changed #126: Frontend can now be initialized without actorId, as long as you call
setActorId
before you make the first change (@ept) - Changed #120: Undo and redo must now be initiated by the frontend, not the backend (@ept)
- Fixed #120: Fixed bug that would cause sequence numbers to be reused in some concurrent executions (@ept)
- Fixed #125: Exceptions now throw Error objects rather than plain strings (@wincent)
0.9.0 — 2018-09-18
- Added #112: Added
Automerge.undo()
andAutomerge.redo()
(@ept) - Added #118: Introduced new Frontend and Backend APIs, and refactored existing APIs to use them; this allows some of the work to be moved to a background thread, and provides better modularisation (@ept)
- Removed Removed the experimental Immutable.js-compatible API (
Automerge.initImmutable()
), a casualty of the refactoring in #118 (@ept)
0.8.0 — 2018-08-02
- Added #106: New
doc._get(UUID)
method allows looking up an object by its_objectId
inside anAutomerge.change()
callback (@mattkrick) - Added #109: Export
OpSet.getMissingChanges
on the Automerge object (@mattkrick) - Added #111: New
Automerge.emptyChange()
allows a "change" record to be created without actually changing the document (@ept) - Changed #110: Require that the change message in
Automerge.change()
must be a string (@ept) - Changed #111: If
Automerge.change()
does not modify the document, the function now returns the original document object untouched (@ept)
0.7.11 — 2018-06-26
- Fixed #97:
delete
operator no longer throws an exception if the property doesn't exist (@salzhrani, @EthanRBrown) - Fixed #104: Fix an error when loading the webpack-packaged version of Automerge in Node.js (@ept)
0.7.10 — 2018-06-12
- Added #93: Allow the UUID implementation to be replaced for testing purposes (@kpruden)
- Added #74: Automerge.diff() now includes the path from the root to the modified object (@ept)
0.7.9 — 2018-05-25
- Fixed #90: Compatibility with Node 10 (@aslakhellesoy)
0.7.8 — 2018-05-15
0.7.7 — 2018-04-24
- Changed #87: Remove babel-polyfill from transpiled library (@EthanRBrown)
0.7.4, 0.7.5, 0.7.6 — 2018-04-19
- Version bump to fix a build tooling issue
0.7.3 — 2018-04-19
- Changed #85: Publish Babel-transpiled code to npm to improve compatibility (@EthanRBrown)
0.7.2 — 2018-04-17
- Changed #83: Changed
_objectId
property on Automerge map objects to be non-enumerable (@EthanRBrown, @ept) - Changed #84: Changed
_conflicts
,_state
, and_actorId
to be non-enumerable properties (@ept) - Fixed #77: Fixed exception when a list element is inserted and updated in the same change callback (@mmcgrana, @ept)
- Fixed #78: Better error message when trying to use an unsupported datatype (@ept)
0.7.1 — 2018-02-26
- Fixed #69:
Automerge.load
generates random actorId if none specified (@saranrapjs) - Fixed #64:
Automerge.applyChanges()
allows changes to be applied out-of-order (@jimpick, @ept)
0.7.0 — 2018-01-15
- Added #62: Initial support for Immutable.js API compatibility (read-only for now) (@ept, @jeffpeterson)
- Added #45: Added experimental APIs
Automerge.getMissingDeps
,Automerge.getChangesForActor
, andAutomerge.WatchableDoc
to support integration with dat hypercore (@pvh, @ept) - Added #46: Automerge list objects now also have a
_conflicts
property that records concurrent assignments to the same list index, just like map objects have had all along (@ept) - Changed #60:
splice
in anAutomerge.change()
callback returns an array of deleted elements (to match behaviour ofArray#splice
). (@aslakhellesoy) - Fixed #57: Tests now work on operating systems with case-sensitive filesystems (@mmmm1998)
0.6.0 — 2017-12-13
- Added #44: New APIs
Automerge.getChanges
andAutomerge.applyChanges
to provide more flexibility for network protocol layer (@ept) - Added #41: New
Automerge.Text
datatype, which is more efficient than a list for character-by-character editing of text (@ept) - Added #40: Lists are now backed by a new indexed skip list data structure, which is faster (@ept)
- Changed #38: To save memory,
Automerge.getHistory
now builds snapshots of past states only when requested, rather than remembering them by default (@ept)
0.5.0 — 2017-09-19
- Added #37: Added
Automerge.diff
to find the differences between to Automerge documents (@ept) - Added #37: Added support for incremental cache maintenance, bringing a 20x speedup for a 1,000-element list (@ept)
- Added #36: Added
Automerge.Connection
andAutomerge.DocSet
classes to support peer-to-peer network protocols (@ept, @pvh) - Changed: Renamed
Automerge.changeset
toAutomerge.change
(@ept)
0.4.3 — 2017-08-16
- Fixed #34: Fixed a bug that caused list elements to sometimes disappear (@aslakhellesoy, @ept)
- Fixed #32: Fixed a test failure in recent Node.js versions (@aslakhellesoy)
0.4.2 — 2017-06-29
- Added: Set up Karma to run tests in web browsers (@ept)
- Added: Set up Webpack to produce bundled JavaScript file for web browsers (@ept)
0.4.1 — 2017-06-26
- Changed:
Automerge.getHistory
API now uses the object cache, which should be faster (@ept)
0.4.0 — 2017-06-23
- Changed: Automerge documents are now just regular JavaScript objects, and Proxy is used only
within
Automerge.changeset
callbacks. Previously everything used Proxy. (@ept) - Changed: #30: Made
_objectId
an enumerable property, so that it is visible by default (@ept) - Changed: Support all standard JavaScript array methods and iterators on list proxy object (@ept)
0.3.0 — 2017-06-13
- First public release.