@automerge/automerge-repo 0.1.1-alpha.0 → 0.1.3-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2019-2023, Ink & Switch LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/README.md CHANGED
@@ -9,31 +9,28 @@ deciding which peers to connect to or when to write data out to storage.
9
9
 
10
10
  Other packages in this monorepo include:
11
11
 
12
- - [@automerge/automerge-repo-demo-counter](/packages/@automerge/automerge-repo-demo-counter/): A React-based demonstration
12
+ - [@automerge/automerge-repo-demo-counter](/packages/automerge-repo-demo-counter/): A React-based demonstration
13
13
  application.
14
- - [@automerge/automerge-repo-react-hooks](/packages/@automerge/automerge-repo-react-hooks/): Example hooks for use with
14
+ - [@automerge/automerge-repo-react-hooks](/packages/automerge-repo-react-hooks/): Example hooks for use with
15
15
  React.
16
- - [@automerge/automerge-repo-sync-server](/packages/@automerge/automerge-repo-sync-server/): A small synchronization
16
+ - [@automerge/automerge-repo-sync-server](/packages/automerge-repo-sync-server/): A small synchronization
17
17
  server that facilitates asynchronous communication between peers
18
18
 
19
19
  #### Storage adapters
20
20
 
21
- - [automerge-repo-storage-localforage](/packages/automerge-repo-storage-localforage/): A storage
21
+ - [@automerge/automerge-repo-storage-localforage](/packages/automerge-repo-storage-localforage/): A storage
22
22
  adapter to persist data in a browser
23
- - [automerge-repo-storage-nodefs](/packages/automerge-repo-storage-nodefs/): A storage adapter to
23
+ - [@automerge/automerge-repo-storage-nodefs](/packages/automerge-repo-storage-nodefs/): A storage adapter to
24
24
  write changes to the filesystem
25
25
 
26
26
  #### Network adapters
27
27
 
28
- - [automerge-repo-network-websocket](/packages/automerge-repo-network-websocket/): Network adapters
28
+ - [@automerge/automerge-repo-network-websocket](/packages/automerge-repo-network-websocket/): Network adapters
29
29
  for both sides of a client/server configuration over websocket
30
- - [automerge-repo-network-localfirstrelay](/packages/automerge-repo-network-localfirstrelay/): A
31
- network client that uses [@localfirst/relay](https://github.com/local-first-web/relay) to relay
32
- traffic between peers
33
- - [automerge-repo-network-messagechannel](/packages/automerge-repo-network-messagechannel/): A
30
+ - [@automerge/automerge-repo-network-messagechannel](/packages/automerge-repo-network-messagechannel/): A
34
31
  network adapter that uses the [MessageChannel
35
32
  API](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel) to communicate between tabs
36
- - [automerge-repo-network-broadcastchannel](/packages/automerge-repo-network-broadcastchannel/):
33
+ - [@automerge/automerge-repo-network-broadcastchannel](/packages/automerge-repo-network-broadcastchannel/):
37
34
  Likely only useful for experimentation, but allows simple (inefficient) tab-to-tab data
38
35
  synchronization
39
36
 
@@ -84,7 +81,7 @@ A `DocHandle` also emits these events:
84
81
  - `change({handle: DocHandle, doc: Doc<T>})`
85
82
  Called any time changes are created or received on the document. Request the `value()` from the
86
83
  handle.
87
- - `patch({handle: DocHandle, before: Doc, after: Doc, patches: Patch[]})`
84
+ - `patch({handle: DocHandle, patches: Patch[], patchInfo: PatchInfo})`
88
85
  Useful for manual increment maintenance of a video, most notably for text editors.
89
86
  - `delete`
90
87
  Called when the document is deleted locally.
@@ -139,7 +136,7 @@ yarn create vite
139
136
 
140
137
  cd hello-automerge-repo
141
138
  yarn
142
- yarn add @automerge/automerge automerge-repo automerge-repo-react-hooks automerge-repo-network-broadcastchannel automerge-repo-storage-localforage vite-plugin-wasm vite-plugin-top-level-await
139
+ yarn add @automerge/automerge @automerge/automerge-repo-react-hooks @automerge/automerge-repo-network-broadcastchannel @automerge/automerge-repo-storage-localforage vite-plugin-wasm vite-plugin-top-level-await
143
140
  ```
144
141
 
145
142
  Edit the `vite.config.ts`. (This is all need to work around packaging hiccups due to WASM. We look
@@ -47,8 +47,7 @@ export interface DocHandleDeletePayload<T> {
47
47
  export interface DocHandlePatchPayload<T> {
48
48
  handle: DocHandle<T>;
49
49
  patches: A.Patch[];
50
- before: A.Doc<T>;
51
- after: A.Doc<T>;
50
+ patchInfo: A.PatchInfo<T>;
52
51
  }
53
52
  export interface DocHandleEvents<T> {
54
53
  change: (payload: DocHandleChangePayload<T>) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,sBAAsB,CAAA;AAEzC,OAAO,YAAY,MAAM,eAAe,CAAA;AAgBxC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAG/D,iGAAiG;AACjG,qBAAa,SAAS,CAAC,CAAC,CAAE,EAAE;AAC1B,SAAQ,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;IAQ/B,UAAU,EAAE,UAAU;gBAAtB,UAAU,EAAE,UAAU,EAC7B,EAAE,KAAa,EAAE,YAAqB,EAAE,GAAE,gBAAqB;IAkHjE,IAAI,GAAG,sBAQN;IAwBD,OAAO,gBAA8B;IACrC,mBAAmB,gBACkC;IACrD,SAAS,gBAAgC;IAEzC;;OAEG;IACG,KAAK,CAAC,WAAW,GAAE,WAAW,EAAY;IAc1C,kBAAkB;IAIxB,yEAAyE;IACzE,IAAI,CAAC,MAAM,EAAE,UAAU;IAMvB,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAI5C,2EAA2E;IAC3E,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAM;IAehE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAM;IAelF,gFAAgF;IAChF,OAAO;IAIP,kEAAkE;IAClE,MAAM;CAGP;AAID,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;IACpB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;CACd;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IAClB,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAChB,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;CAChB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,MAAM,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAClD,MAAM,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;CACrD;AAMD,eAAO,MAAM,WAAW;;;;;;;CAOd,CAAA;AACV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAkBxE,eAAO,MAAM,KAAK;;;;;;;;;CASR,CAAA"}
1
+ {"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,sBAAsB,CAAA;AAEzC,OAAO,YAAY,MAAM,eAAe,CAAA;AAiBxC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/D,iGAAiG;AACjG,qBAAa,SAAS,CAAC,CAAC,CAAE,EAAE;AAC1B,SAAQ,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;IAQ/B,UAAU,EAAE,UAAU;gBAAtB,UAAU,EAAE,UAAU,EAC7B,EAAE,KAAa,EAAE,YAAqB,EAAE,GAAE,gBAAqB;IAqHjE,IAAI,GAAG,sBAQN;IAwBD,OAAO,gBAA8B;IACrC,mBAAmB,gBACkC;IACrD,SAAS,gBAAgC;IAEzC;;OAEG;IACG,KAAK,CAAC,WAAW,GAAE,WAAW,EAAY;IAc1C,kBAAkB;IAIxB,yEAAyE;IACzE,IAAI,CAAC,MAAM,EAAE,UAAU;IAMvB,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAI5C,2EAA2E;IAC3E,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAM;IAehE,QAAQ,CACN,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAM;IAgBlC,gFAAgF;IAChF,OAAO;IAIP,kEAAkE;IAClE,MAAM;CAGP;AAID,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;IACpB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;CACd;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IAClB,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,MAAM,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAClD,MAAM,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;CACrD;AAMD,eAAO,MAAM,WAAW;;;;;;;CAOd,CAAA;AACV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAkBxE,eAAO,MAAM,KAAK;;;;;;;;;CASR,CAAA"}
package/dist/DocHandle.js CHANGED
@@ -5,7 +5,7 @@ import { assign, createMachine, interpret, } from "xstate";
5
5
  import { waitFor } from "xstate/lib/waitFor.js";
6
6
  import { headsAreSame } from "./helpers/headsAreSame.js";
7
7
  import { pause } from "./helpers/pause.js";
8
- import { withTimeout, TimeoutError } from "./helpers/withTimeout.js";
8
+ import { TimeoutError, withTimeout } from "./helpers/withTimeout.js";
9
9
  /** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
10
10
  export class DocHandle//
11
11
  extends EventEmitter {
@@ -20,7 +20,7 @@ export class DocHandle//
20
20
  this.#log = debug(`automerge-repo:dochandle:${documentId.slice(0, 5)}`);
21
21
  // initial doc
22
22
  const doc = A.init({
23
- patchCallback: (patches, { before, after }) => this.emit("patch", { handle: this, patches, before, after }),
23
+ patchCallback: (patches, patchInfo) => this.emit("patch", { handle: this, patches, patchInfo }),
24
24
  });
25
25
  /**
26
26
  * Internally we use a state machine to orchestrate document loading and/or syncing, in order to
@@ -91,13 +91,6 @@ export class DocHandle//
91
91
  const { doc: oldDoc } = context;
92
92
  const { callback } = payload;
93
93
  const newDoc = callback(oldDoc);
94
- const docChanged = !headsAreSame(newDoc, oldDoc);
95
- if (docChanged) {
96
- this.emit("change", { handle: this, doc: newDoc });
97
- if (!this.isReady()) {
98
- this.#machine.send(REQUEST_COMPLETE);
99
- }
100
- }
101
94
  return { doc: newDoc };
102
95
  }),
103
96
  onDelete: assign(() => {
@@ -106,7 +99,18 @@ export class DocHandle//
106
99
  }),
107
100
  },
108
101
  }))
109
- .onTransition(({ value: state }, { type: event }) => this.#log(`${event} → ${state}`, this.#doc))
102
+ .onTransition(({ value: state, history, context }, event) => {
103
+ const oldDoc = history?.context?.doc;
104
+ const newDoc = context.doc;
105
+ const docChanged = newDoc && oldDoc && !headsAreSame(newDoc, oldDoc);
106
+ if (docChanged) {
107
+ this.emit("change", { handle: this, doc: newDoc });
108
+ if (!this.isReady()) {
109
+ this.#machine.send(REQUEST_COMPLETE);
110
+ }
111
+ }
112
+ this.#log(`${event} → ${state}`, this.#doc);
113
+ })
110
114
  .start();
111
115
  this.#machine.send(isNew ? CREATE : FIND);
112
116
  }
@@ -1,4 +1,4 @@
1
- import { type NetworkAdapter } from "../index.js";
1
+ import { type NetworkAdapter } from "../../index.js";
2
2
  /**
3
3
  * Runs a series of tests against a set of three peers, each represented by one or more instantiated
4
4
  * network adapters.
@@ -18,4 +18,4 @@ export type SetupFn = () => Promise<{
18
18
  teardown?: () => void;
19
19
  }>;
20
20
  export {};
21
- //# sourceMappingURL=adapter-tests.d.ts.map
21
+ //# sourceMappingURL=network-adapter-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network-adapter-tests.d.ts","sourceRoot":"","sources":["../../../src/helpers/tests/network-adapter-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAa,MAAM,gBAAgB,CAAA;AAK7E;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA2HrE;AAID,KAAK,OAAO,GAAG,cAAc,GAAG,cAAc,EAAE,CAAA;AAEhD,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}
@@ -1,5 +1,5 @@
1
- import { Repo } from "../index.js";
2
- import { eventPromise, eventPromises, } from "../helpers/eventPromise.js";
1
+ import { Repo } from "../../index.js";
2
+ import { eventPromise, eventPromises } from "../eventPromise.js";
3
3
  import { assert } from "chai";
4
4
  import { describe, it } from "mocha";
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { DocCollection } from "./DocCollection.js";
2
2
  export { DocHandle, HandleState } from "./DocHandle.js";
3
- export type { DocHandleChangePayload, DocHandleMessagePayload, DocHandlePatchPayload, } from "./DocHandle.js";
3
+ export type { DocHandleChangePayload, DocHandlePatchPayload, } from "./DocHandle.js";
4
4
  export { NetworkAdapter } from "./network/NetworkAdapter.js";
5
5
  export type { InboundMessagePayload, MessagePayload, OpenPayload, PeerCandidatePayload, PeerDisconnectedPayload, } from "./network/NetworkAdapter.js";
6
6
  export { NetworkSubsystem } from "./network/NetworkSubsystem.js";
@@ -9,5 +9,4 @@ export { StorageAdapter } from "./storage/StorageAdapter.js";
9
9
  export { StorageSubsystem } from "./storage/StorageSubsystem.js";
10
10
  export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
11
11
  export * from "./types.js";
12
- export * from "./test-utilities/adapter-tests.js";
13
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EACV,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,cAAc,YAAY,CAAA;AAC1B,cAAc,mCAAmC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,cAAc,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -7,4 +7,3 @@ export { StorageAdapter } from "./storage/StorageAdapter.js";
7
7
  export { StorageSubsystem } from "./storage/StorageSubsystem.js";
8
8
  export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
9
9
  export * from "./types.js";
10
- export * from "./test-utilities/adapter-tests.js";
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo",
3
- "version": "0.1.1-alpha.0",
3
+ "version": "0.1.3-alpha.0",
4
4
  "description": "A repository object to manage a collection of automerge documents",
5
- "repository": "https://github.com/pvh/automerge-repo",
5
+ "repository": "https://github.com/automerge/automerge-repo",
6
6
  "author": "Peter van Hardenberg <pvh@pvh.ca>",
7
7
  "license": "MIT",
8
8
  "private": false,
@@ -29,7 +29,7 @@
29
29
  "http-server": "^14.1.0"
30
30
  },
31
31
  "peerDependencies": {
32
- "@automerge/automerge": "^2.1.0-alpha.7"
32
+ "@automerge/automerge": "^2.1.0-alpha.8"
33
33
  },
34
34
  "dependencies": {
35
35
  "cbor-x": "^1.3.0",
@@ -61,5 +61,5 @@
61
61
  "publishConfig": {
62
62
  "access": "public"
63
63
  },
64
- "gitHead": "b48a3db6a87942398290bcb69a216680fd2f31ae"
64
+ "gitHead": "5b1959b8a7c1834e5dbbddbce9681f6208024377"
65
65
  }
package/src/DocHandle.ts CHANGED
@@ -16,8 +16,8 @@ import {
16
16
  import { waitFor } from "xstate/lib/waitFor.js"
17
17
  import { headsAreSame } from "./helpers/headsAreSame.js"
18
18
  import { pause } from "./helpers/pause.js"
19
+ import { TimeoutError, withTimeout } from "./helpers/withTimeout.js"
19
20
  import type { ChannelId, DocumentId, PeerId } from "./types.js"
20
- import { withTimeout, TimeoutError } from "./helpers/withTimeout.js"
21
21
 
22
22
  /** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
23
23
  export class DocHandle<T> //
@@ -38,8 +38,8 @@ export class DocHandle<T> //
38
38
 
39
39
  // initial doc
40
40
  const doc = A.init<T>({
41
- patchCallback: (patches, { before, after }) =>
42
- this.emit("patch", { handle: this, patches, before, after }),
41
+ patchCallback: (patches, patchInfo) =>
42
+ this.emit("patch", { handle: this, patches, patchInfo }),
43
43
  })
44
44
 
45
45
  /**
@@ -119,13 +119,6 @@ export class DocHandle<T> //
119
119
  const { callback } = payload
120
120
  const newDoc = callback(oldDoc)
121
121
 
122
- const docChanged = !headsAreSame(newDoc, oldDoc)
123
- if (docChanged) {
124
- this.emit("change", { handle: this, doc: newDoc })
125
- if (!this.isReady()) {
126
- this.#machine.send(REQUEST_COMPLETE)
127
- }
128
- }
129
122
  return { doc: newDoc }
130
123
  }),
131
124
  onDelete: assign(() => {
@@ -136,9 +129,19 @@ export class DocHandle<T> //
136
129
  }
137
130
  )
138
131
  )
139
- .onTransition(({ value: state }, { type: event }) =>
132
+ .onTransition(({ value: state, history, context }, event) => {
133
+ const oldDoc = history?.context?.doc
134
+ const newDoc = context.doc
135
+
136
+ const docChanged = newDoc && oldDoc && !headsAreSame(newDoc, oldDoc)
137
+ if (docChanged) {
138
+ this.emit("change", { handle: this, doc: newDoc })
139
+ if (!this.isReady()) {
140
+ this.#machine.send(REQUEST_COMPLETE)
141
+ }
142
+ }
140
143
  this.#log(`${event} → ${state}`, this.#doc)
141
- )
144
+ })
142
145
  .start()
143
146
 
144
147
  this.#machine.send(isNew ? CREATE : FIND)
@@ -230,7 +233,11 @@ export class DocHandle<T> //
230
233
  })
231
234
  }
232
235
 
233
- changeAt(heads: A.Heads, callback: A.ChangeFn<T>, options: A.ChangeOptions<T> = {}) {
236
+ changeAt(
237
+ heads: A.Heads,
238
+ callback: A.ChangeFn<T>,
239
+ options: A.ChangeOptions<T> = {}
240
+ ) {
234
241
  if (!this.isReady()) {
235
242
  throw new Error(
236
243
  `DocHandle#${this.documentId} is not ready. Check \`handle.isReady()\` before accessing the document.`
@@ -281,8 +288,7 @@ export interface DocHandleDeletePayload<T> {
281
288
  export interface DocHandlePatchPayload<T> {
282
289
  handle: DocHandle<T>
283
290
  patches: A.Patch[]
284
- before: A.Doc<T>
285
- after: A.Doc<T>
291
+ patchInfo: A.PatchInfo<T>
286
292
  }
287
293
 
288
294
  export interface DocHandleEvents<T> {
@@ -1,8 +1,5 @@
1
- import { PeerId, Repo, type NetworkAdapter, ChannelId } from "../index.js"
2
- import {
3
- eventPromise,
4
- eventPromises,
5
- } from "../helpers/eventPromise.js"
1
+ import { PeerId, Repo, type NetworkAdapter, ChannelId } from "../../index.js"
2
+ import { eventPromise, eventPromises } from "../eventPromise.js"
6
3
  import { assert } from "chai"
7
4
  import { describe, it } from "mocha"
8
5
 
@@ -143,7 +140,7 @@ export function runAdapterTests(_setup: SetupFn, title?: string): void {
143
140
  })
144
141
  }
145
142
 
146
- const NO_OP = () => { }
143
+ const NO_OP = () => {}
147
144
 
148
145
  type Network = NetworkAdapter | NetworkAdapter[]
149
146
 
package/src/index.ts CHANGED
@@ -2,7 +2,6 @@ export { DocCollection } from "./DocCollection.js"
2
2
  export { DocHandle, HandleState } from "./DocHandle.js"
3
3
  export type {
4
4
  DocHandleChangePayload,
5
- DocHandleMessagePayload,
6
5
  DocHandlePatchPayload,
7
6
  } from "./DocHandle.js"
8
7
  export { NetworkAdapter } from "./network/NetworkAdapter.js"
@@ -19,4 +18,3 @@ export { StorageAdapter } from "./storage/StorageAdapter.js"
19
18
  export { StorageSubsystem } from "./storage/StorageSubsystem.js"
20
19
  export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js"
21
20
  export * from "./types.js"
22
- export * from "./test-utilities/adapter-tests.js"
@@ -137,6 +137,24 @@ describe("DocHandle", () => {
137
137
  })
138
138
  })
139
139
 
140
+ it("should update the internal doc prior to emitting the change message", async () => {
141
+ const handle = new DocHandle<TestDoc>(TEST_ID, { isNew: true })
142
+
143
+ const p = new Promise<void>(resolve =>
144
+ handle.once("change", ({ handle, doc }) => {
145
+ assert.equal(handle.doc.foo, doc.foo)
146
+
147
+ resolve()
148
+ })
149
+ )
150
+
151
+ handle.change(doc => {
152
+ doc.foo = "baz"
153
+ })
154
+
155
+ return p
156
+ })
157
+
140
158
  it("should emit distinct change messages when consecutive changes happen", async () => {
141
159
  const handle = new DocHandle<TestDoc>(TEST_ID, { isNew: true })
142
160
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapter-tests.d.ts","sourceRoot":"","sources":["../../src/test-utilities/adapter-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAa,MAAM,aAAa,CAAA;AAQ1E;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA2HrE;AAID,KAAK,OAAO,GAAG,cAAc,GAAG,cAAc,EAAE,CAAA;AAEhD,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}