@automerge/automerge-repo 2.0.0-collectionsync-alpha.1 → 2.0.1

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.
Files changed (203) hide show
  1. package/README.md +8 -8
  2. package/dist/AutomergeUrl.d.ts +17 -5
  3. package/dist/AutomergeUrl.d.ts.map +1 -1
  4. package/dist/AutomergeUrl.js +71 -24
  5. package/dist/DocHandle.d.ts +33 -41
  6. package/dist/DocHandle.d.ts.map +1 -1
  7. package/dist/DocHandle.js +105 -66
  8. package/dist/FindProgress.d.ts +30 -0
  9. package/dist/FindProgress.d.ts.map +1 -0
  10. package/dist/FindProgress.js +1 -0
  11. package/dist/RemoteHeadsSubscriptions.d.ts +4 -5
  12. package/dist/RemoteHeadsSubscriptions.d.ts.map +1 -1
  13. package/dist/RemoteHeadsSubscriptions.js +4 -1
  14. package/dist/Repo.d.ts +24 -5
  15. package/dist/Repo.d.ts.map +1 -1
  16. package/dist/Repo.js +355 -169
  17. package/dist/helpers/abortable.d.ts +36 -0
  18. package/dist/helpers/abortable.d.ts.map +1 -0
  19. package/dist/helpers/abortable.js +47 -0
  20. package/dist/helpers/arraysAreEqual.d.ts.map +1 -1
  21. package/dist/helpers/bufferFromHex.d.ts +3 -0
  22. package/dist/helpers/bufferFromHex.d.ts.map +1 -0
  23. package/dist/helpers/bufferFromHex.js +13 -0
  24. package/dist/helpers/debounce.d.ts.map +1 -1
  25. package/dist/helpers/eventPromise.d.ts.map +1 -1
  26. package/dist/helpers/headsAreSame.d.ts +2 -2
  27. package/dist/helpers/headsAreSame.d.ts.map +1 -1
  28. package/dist/helpers/mergeArrays.d.ts +1 -1
  29. package/dist/helpers/mergeArrays.d.ts.map +1 -1
  30. package/dist/helpers/pause.d.ts.map +1 -1
  31. package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
  32. package/dist/helpers/tests/network-adapter-tests.js +13 -13
  33. package/dist/helpers/tests/storage-adapter-tests.d.ts.map +1 -1
  34. package/dist/helpers/tests/storage-adapter-tests.js +6 -9
  35. package/dist/helpers/throttle.d.ts.map +1 -1
  36. package/dist/helpers/withTimeout.d.ts.map +1 -1
  37. package/dist/index.d.ts +35 -7
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +37 -6
  40. package/dist/network/NetworkSubsystem.d.ts +0 -1
  41. package/dist/network/NetworkSubsystem.d.ts.map +1 -1
  42. package/dist/network/NetworkSubsystem.js +0 -3
  43. package/dist/network/messages.d.ts +1 -7
  44. package/dist/network/messages.d.ts.map +1 -1
  45. package/dist/network/messages.js +1 -2
  46. package/dist/storage/StorageAdapter.d.ts +0 -9
  47. package/dist/storage/StorageAdapter.d.ts.map +1 -1
  48. package/dist/storage/StorageAdapter.js +0 -33
  49. package/dist/storage/StorageSubsystem.d.ts +6 -2
  50. package/dist/storage/StorageSubsystem.d.ts.map +1 -1
  51. package/dist/storage/StorageSubsystem.js +131 -37
  52. package/dist/storage/keyHash.d.ts +1 -1
  53. package/dist/storage/keyHash.d.ts.map +1 -1
  54. package/dist/synchronizer/CollectionSynchronizer.d.ts +3 -4
  55. package/dist/synchronizer/CollectionSynchronizer.d.ts.map +1 -1
  56. package/dist/synchronizer/CollectionSynchronizer.js +32 -26
  57. package/dist/synchronizer/DocSynchronizer.d.ts +8 -8
  58. package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
  59. package/dist/synchronizer/DocSynchronizer.js +205 -79
  60. package/dist/types.d.ts +4 -1
  61. package/dist/types.d.ts.map +1 -1
  62. package/fuzz/fuzz.ts +3 -3
  63. package/package.json +4 -5
  64. package/src/AutomergeUrl.ts +101 -26
  65. package/src/DocHandle.ts +158 -77
  66. package/src/FindProgress.ts +48 -0
  67. package/src/RemoteHeadsSubscriptions.ts +11 -9
  68. package/src/Repo.ts +465 -180
  69. package/src/helpers/abortable.ts +62 -0
  70. package/src/helpers/bufferFromHex.ts +14 -0
  71. package/src/helpers/headsAreSame.ts +2 -2
  72. package/src/helpers/tests/network-adapter-tests.ts +14 -13
  73. package/src/helpers/tests/storage-adapter-tests.ts +13 -24
  74. package/src/index.ts +57 -38
  75. package/src/network/NetworkSubsystem.ts +0 -4
  76. package/src/network/messages.ts +2 -11
  77. package/src/storage/StorageAdapter.ts +0 -42
  78. package/src/storage/StorageSubsystem.ts +155 -45
  79. package/src/storage/keyHash.ts +1 -1
  80. package/src/synchronizer/CollectionSynchronizer.ts +42 -29
  81. package/src/synchronizer/DocSynchronizer.ts +263 -89
  82. package/src/types.ts +4 -1
  83. package/test/AutomergeUrl.test.ts +130 -0
  84. package/test/CollectionSynchronizer.test.ts +6 -8
  85. package/test/DocHandle.test.ts +161 -77
  86. package/test/DocSynchronizer.test.ts +11 -9
  87. package/test/RemoteHeadsSubscriptions.test.ts +1 -1
  88. package/test/Repo.test.ts +406 -341
  89. package/test/StorageSubsystem.test.ts +95 -20
  90. package/test/remoteHeads.test.ts +28 -13
  91. package/dist/CollectionHandle.d.ts +0 -14
  92. package/dist/CollectionHandle.d.ts.map +0 -1
  93. package/dist/CollectionHandle.js +0 -37
  94. package/dist/DocUrl.d.ts +0 -47
  95. package/dist/DocUrl.d.ts.map +0 -1
  96. package/dist/DocUrl.js +0 -72
  97. package/dist/EphemeralData.d.ts +0 -20
  98. package/dist/EphemeralData.d.ts.map +0 -1
  99. package/dist/EphemeralData.js +0 -1
  100. package/dist/ferigan.d.ts +0 -51
  101. package/dist/ferigan.d.ts.map +0 -1
  102. package/dist/ferigan.js +0 -98
  103. package/dist/src/DocHandle.d.ts +0 -182
  104. package/dist/src/DocHandle.d.ts.map +0 -1
  105. package/dist/src/DocHandle.js +0 -405
  106. package/dist/src/DocUrl.d.ts +0 -49
  107. package/dist/src/DocUrl.d.ts.map +0 -1
  108. package/dist/src/DocUrl.js +0 -72
  109. package/dist/src/EphemeralData.d.ts +0 -19
  110. package/dist/src/EphemeralData.d.ts.map +0 -1
  111. package/dist/src/EphemeralData.js +0 -1
  112. package/dist/src/Repo.d.ts +0 -74
  113. package/dist/src/Repo.d.ts.map +0 -1
  114. package/dist/src/Repo.js +0 -208
  115. package/dist/src/helpers/arraysAreEqual.d.ts +0 -2
  116. package/dist/src/helpers/arraysAreEqual.d.ts.map +0 -1
  117. package/dist/src/helpers/arraysAreEqual.js +0 -2
  118. package/dist/src/helpers/cbor.d.ts +0 -4
  119. package/dist/src/helpers/cbor.d.ts.map +0 -1
  120. package/dist/src/helpers/cbor.js +0 -8
  121. package/dist/src/helpers/eventPromise.d.ts +0 -11
  122. package/dist/src/helpers/eventPromise.d.ts.map +0 -1
  123. package/dist/src/helpers/eventPromise.js +0 -7
  124. package/dist/src/helpers/headsAreSame.d.ts +0 -2
  125. package/dist/src/helpers/headsAreSame.d.ts.map +0 -1
  126. package/dist/src/helpers/headsAreSame.js +0 -4
  127. package/dist/src/helpers/mergeArrays.d.ts +0 -2
  128. package/dist/src/helpers/mergeArrays.d.ts.map +0 -1
  129. package/dist/src/helpers/mergeArrays.js +0 -15
  130. package/dist/src/helpers/pause.d.ts +0 -6
  131. package/dist/src/helpers/pause.d.ts.map +0 -1
  132. package/dist/src/helpers/pause.js +0 -10
  133. package/dist/src/helpers/tests/network-adapter-tests.d.ts +0 -21
  134. package/dist/src/helpers/tests/network-adapter-tests.d.ts.map +0 -1
  135. package/dist/src/helpers/tests/network-adapter-tests.js +0 -122
  136. package/dist/src/helpers/withTimeout.d.ts +0 -12
  137. package/dist/src/helpers/withTimeout.d.ts.map +0 -1
  138. package/dist/src/helpers/withTimeout.js +0 -24
  139. package/dist/src/index.d.ts +0 -53
  140. package/dist/src/index.d.ts.map +0 -1
  141. package/dist/src/index.js +0 -40
  142. package/dist/src/network/NetworkAdapter.d.ts +0 -26
  143. package/dist/src/network/NetworkAdapter.d.ts.map +0 -1
  144. package/dist/src/network/NetworkAdapter.js +0 -4
  145. package/dist/src/network/NetworkSubsystem.d.ts +0 -23
  146. package/dist/src/network/NetworkSubsystem.d.ts.map +0 -1
  147. package/dist/src/network/NetworkSubsystem.js +0 -120
  148. package/dist/src/network/messages.d.ts +0 -85
  149. package/dist/src/network/messages.d.ts.map +0 -1
  150. package/dist/src/network/messages.js +0 -23
  151. package/dist/src/storage/StorageAdapter.d.ts +0 -14
  152. package/dist/src/storage/StorageAdapter.d.ts.map +0 -1
  153. package/dist/src/storage/StorageAdapter.js +0 -1
  154. package/dist/src/storage/StorageSubsystem.d.ts +0 -12
  155. package/dist/src/storage/StorageSubsystem.d.ts.map +0 -1
  156. package/dist/src/storage/StorageSubsystem.js +0 -145
  157. package/dist/src/synchronizer/CollectionSynchronizer.d.ts +0 -25
  158. package/dist/src/synchronizer/CollectionSynchronizer.d.ts.map +0 -1
  159. package/dist/src/synchronizer/CollectionSynchronizer.js +0 -106
  160. package/dist/src/synchronizer/DocSynchronizer.d.ts +0 -29
  161. package/dist/src/synchronizer/DocSynchronizer.d.ts.map +0 -1
  162. package/dist/src/synchronizer/DocSynchronizer.js +0 -263
  163. package/dist/src/synchronizer/Synchronizer.d.ts +0 -9
  164. package/dist/src/synchronizer/Synchronizer.d.ts.map +0 -1
  165. package/dist/src/synchronizer/Synchronizer.js +0 -2
  166. package/dist/src/types.d.ts +0 -16
  167. package/dist/src/types.d.ts.map +0 -1
  168. package/dist/src/types.js +0 -1
  169. package/dist/test/CollectionSynchronizer.test.d.ts +0 -2
  170. package/dist/test/CollectionSynchronizer.test.d.ts.map +0 -1
  171. package/dist/test/CollectionSynchronizer.test.js +0 -57
  172. package/dist/test/DocHandle.test.d.ts +0 -2
  173. package/dist/test/DocHandle.test.d.ts.map +0 -1
  174. package/dist/test/DocHandle.test.js +0 -238
  175. package/dist/test/DocSynchronizer.test.d.ts +0 -2
  176. package/dist/test/DocSynchronizer.test.d.ts.map +0 -1
  177. package/dist/test/DocSynchronizer.test.js +0 -111
  178. package/dist/test/Network.test.d.ts +0 -2
  179. package/dist/test/Network.test.d.ts.map +0 -1
  180. package/dist/test/Network.test.js +0 -11
  181. package/dist/test/Repo.test.d.ts +0 -2
  182. package/dist/test/Repo.test.d.ts.map +0 -1
  183. package/dist/test/Repo.test.js +0 -568
  184. package/dist/test/StorageSubsystem.test.d.ts +0 -2
  185. package/dist/test/StorageSubsystem.test.d.ts.map +0 -1
  186. package/dist/test/StorageSubsystem.test.js +0 -56
  187. package/dist/test/helpers/DummyNetworkAdapter.d.ts +0 -9
  188. package/dist/test/helpers/DummyNetworkAdapter.d.ts.map +0 -1
  189. package/dist/test/helpers/DummyNetworkAdapter.js +0 -15
  190. package/dist/test/helpers/DummyStorageAdapter.d.ts +0 -16
  191. package/dist/test/helpers/DummyStorageAdapter.d.ts.map +0 -1
  192. package/dist/test/helpers/DummyStorageAdapter.js +0 -33
  193. package/dist/test/helpers/generate-large-object.d.ts +0 -5
  194. package/dist/test/helpers/generate-large-object.d.ts.map +0 -1
  195. package/dist/test/helpers/generate-large-object.js +0 -9
  196. package/dist/test/helpers/getRandomItem.d.ts +0 -2
  197. package/dist/test/helpers/getRandomItem.d.ts.map +0 -1
  198. package/dist/test/helpers/getRandomItem.js +0 -4
  199. package/dist/test/types.d.ts +0 -4
  200. package/dist/test/types.d.ts.map +0 -1
  201. package/dist/test/types.js +0 -1
  202. package/src/CollectionHandle.ts +0 -54
  203. package/src/ferigan.ts +0 -184
@@ -1,33 +0,0 @@
1
- export class DummyStorageAdapter {
2
- #data = {}
3
- #keyToString(key) {
4
- return key.join(".")
5
- }
6
- #stringToKey(key) {
7
- return key.split(".")
8
- }
9
- async loadRange(keyPrefix) {
10
- const range = Object.entries(this.#data)
11
- .filter(([key, _]) => key.startsWith(this.#keyToString(keyPrefix)))
12
- .map(([key, data]) => ({ key: this.#stringToKey(key), data }))
13
- return Promise.resolve(range)
14
- }
15
- async removeRange(keyPrefix) {
16
- Object.entries(this.#data)
17
- .filter(([key, _]) => key.startsWith(this.#keyToString(keyPrefix)))
18
- .forEach(([key, _]) => delete this.#data[key])
19
- }
20
- async load(key) {
21
- return new Promise(resolve => resolve(this.#data[this.#keyToString(key)]))
22
- }
23
- async save(key, binary) {
24
- this.#data[this.#keyToString(key)] = binary
25
- return Promise.resolve()
26
- }
27
- async remove(key) {
28
- delete this.#data[this.#keyToString(key)]
29
- }
30
- keys() {
31
- return Object.keys(this.#data)
32
- }
33
- }
@@ -1,5 +0,0 @@
1
- export type LargeObject = {
2
- [key: string]: number
3
- }
4
- export declare function generateLargeObject(size: number): LargeObject
5
- //# sourceMappingURL=generate-large-object.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-large-object.d.ts","sourceRoot":"","sources":["../../../test/helpers/generate-large-object.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AAEnD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAU7D"}
@@ -1,9 +0,0 @@
1
- export function generateLargeObject(size) {
2
- const largeObject = {}
3
- for (let i = 0; i < size; i++) {
4
- const key = `key${i}`
5
- const value = Math.random()
6
- largeObject[key] = value
7
- }
8
- return largeObject
9
- }
@@ -1,2 +0,0 @@
1
- export declare const getRandomItem: <T>(obj: T[]) => T
2
- //# sourceMappingURL=getRandomItem.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getRandomItem.d.ts","sourceRoot":"","sources":["../../../test/helpers/getRandomItem.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,oBAGzB,CAAA"}
@@ -1,4 +0,0 @@
1
- export const getRandomItem = obj => {
2
- const index = Math.floor(Math.random() * obj.length)
3
- return obj[index]
4
- }
@@ -1,4 +0,0 @@
1
- export interface TestDoc {
2
- foo: string
3
- }
4
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../test/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;CACZ"}
@@ -1 +0,0 @@
1
- export {}
@@ -1,54 +0,0 @@
1
- import { EventEmitter } from "eventemitter3"
2
- import { Ferigan, Index } from "./ferigan.js"
3
- import { AutomergeUrl, DocumentId } from "./types.js"
4
- import { next as A } from "@automerge/automerge"
5
- import { parseAutomergeUrl } from "./AutomergeUrl.js"
6
-
7
- export type CollectionHandleEvents = {
8
- doc_added: (url: AutomergeUrl) => void
9
- }
10
-
11
- export class CollectionHandle extends EventEmitter<CollectionHandleEvents> {
12
- //#index: Index
13
- #beelay: A.beelay.Beelay
14
- //#ferigan: Ferigan
15
- #rootId: DocumentId
16
- #rootUrl: AutomergeUrl
17
- #entries: AutomergeUrl[] = []
18
-
19
- get index(): Index {
20
- return {
21
- rootUrl: this.#rootUrl,
22
- entries: this.#entries,
23
- }
24
- }
25
-
26
- constructor(
27
- belay: A.beelay.Beelay,
28
- rootUrl: AutomergeUrl,
29
- entries: AutomergeUrl[]
30
- ) {
31
- super()
32
- this.#rootUrl = rootUrl
33
- this.#rootId = parseAutomergeUrl(rootUrl).documentId
34
- this.#beelay = belay
35
- this.#entries = entries
36
-
37
- //this.#ferigan.on("indexChanged", ({indexUrl, change}) => {
38
- //if (indexUrl != this.#index.rootUrl) {
39
- //return
40
- //}
41
-
42
- //if (change.type === "add") {
43
- //this.#index.entries.push(change.url)
44
- //this.emit("doc_added", change.url as AutomergeUrl)
45
- //}
46
- //})
47
- }
48
-
49
- add(url: AutomergeUrl): void {
50
- this.#entries.push(url)
51
- let docId = parseAutomergeUrl(url).documentId
52
- this.#beelay.addLink({ from: this.#rootId, to: docId })
53
- }
54
- }
package/src/ferigan.ts DELETED
@@ -1,184 +0,0 @@
1
- import { EventEmitter } from "eventemitter3"
2
- import { MessageContents, RepoMessage } from "./network/messages.js"
3
- import { AutomergeUrl } from "./types.js"
4
- import { Repo } from "./Repo.js"
5
-
6
- const URL_RE = /automerge:([\w\d+/=]+)(?:\?([\w\d+/=&]*))*/
7
-
8
- export interface Ferigan extends EventEmitter<FeriganEvents> {
9
- receiveMessage(message: RepoMessage): Promise<void>
10
- load(
11
- doc: ChangeLogId,
12
- since: ChangeHash[]
13
- ): AsyncIterableIterator<Progress<ChangeLog | undefined>>
14
- loadCollection(
15
- doc: ChangeLogId
16
- ): AsyncIterableIterator<Progress<Index | undefined>>
17
- append(
18
- doc: ChangeLogId,
19
- parents: ChangeHash[],
20
- changes: Uint8Array
21
- ): Promise<void>
22
- replace(
23
- doc: ChangeLogId,
24
- start: ChangeHash,
25
- end: ChangeHash,
26
- changes: Uint8Array
27
- ): Promise<void>
28
- }
29
-
30
- export function makeFerigan(repo: Repo): Ferigan {
31
- function fakeProgress<T>(): AsyncIterableIterator<Progress<T>> {
32
- return (async function*() {
33
- yield { type: "synchronizing_index" }
34
- })()
35
- }
36
- class FakeFerigan extends EventEmitter<FeriganEvents> {
37
- #repo: Repo
38
-
39
- constructor(repo: Repo) {
40
- super()
41
- this.#repo = repo
42
- }
43
-
44
- async receiveMessage(message: RepoMessage): Promise<void> { }
45
- load(
46
- doc: ChangeLogId
47
- ): AsyncIterableIterator<Progress<ChangeLog | undefined>> {
48
- return fakeProgress()
49
- }
50
- async *loadCollection(
51
- doc: ChangeLogId
52
- ): AsyncIterableIterator<Progress<Index | undefined>> {
53
- yield { type: "synchronizing_index" }
54
-
55
- const index: Index = { rootUrl: doc as AutomergeUrl, entries: [] }
56
-
57
- function findLinks(
58
- obj: unknown
59
- ): { url: string }[] {
60
- const links: { url: string; }[] = []
61
-
62
- const traverse = (value: unknown): void => {
63
- if (typeof value === "string") {
64
- const url = parseUrl(value)
65
- if (url != null) {
66
- links.push(url)
67
- }
68
- } else if (Array.isArray(value)) {
69
- value.forEach(traverse)
70
- } else if (typeof value === "object" && value !== null) {
71
- Object.values(value).forEach(traverse)
72
- }
73
- }
74
-
75
- traverse(obj)
76
- return links
77
- }
78
-
79
- const indexDoc = this.#repo.find(doc as AutomergeUrl)
80
- const handlesToProcess = [indexDoc]
81
-
82
- while (handlesToProcess.length > 0) {
83
- const handle = handlesToProcess.pop()
84
- if (!handle) {
85
- continue
86
- }
87
-
88
- const doc = await handle.doc()
89
- if (!doc) {
90
- continue
91
- }
92
-
93
- handle.on("change", change => {
94
- for (const patch of change.patches) {
95
- if (patch.action === "splice") {
96
- const possibleUrl = parseUrl(patch.value)
97
- if (possibleUrl != null) {
98
- this.emit("indexChanged", {
99
- indexUrl: indexDoc.url,
100
- change: {
101
- type: "add",
102
- url: possibleUrl.url,
103
- }
104
- })
105
- }
106
- }
107
- }
108
- })
109
-
110
- const links = findLinks(doc)
111
- for (const { url: urlStr } of links) {
112
- const url = urlStr as AutomergeUrl
113
- if (index.entries.some(entry => entry === url)) {
114
- continue
115
- }
116
- index.entries.push(url)
117
-
118
- const childHandle = this.#repo.find(url as AutomergeUrl)
119
- handlesToProcess.push(childHandle)
120
- }
121
- }
122
- yield { type: "done", value: index }
123
- }
124
- append(
125
- doc: ChangeLogId,
126
- parents: ChangeHash[],
127
- changes: Uint8Array
128
- ): Promise<void> {
129
- return Promise.resolve()
130
- }
131
- replace(
132
- doc: ChangeLogId,
133
- start: ChangeHash,
134
- end: ChangeHash,
135
- changes: Uint8Array
136
- ): Promise<void> {
137
- return Promise.resolve()
138
- }
139
- }
140
- return new FakeFerigan(repo)
141
- }
142
-
143
- interface FeriganEvents {
144
- message: (event: {message: MessageContents}) => void
145
- changed: (event: {changedLog: ChangeLogId}) => void
146
- indexChanged: (event: {indexUrl: ChangeLogId, change: IndexChange}) => void
147
- }
148
-
149
- type IndexChange = {
150
- type: "add"
151
- url: AutomergeUrl
152
- }
153
-
154
- type ChangeLogId = string
155
-
156
- type ChangeHash = string
157
-
158
- type ChangeLog = { start: ChangeHash; end: ChangeHash; changes: Uint8Array }
159
-
160
- export type Progress<T> =
161
- | { type: "synchronizing_index" }
162
- | {
163
- type: "synchronizing_docs"
164
- progress: number
165
- total: number
166
- }
167
- | { type: "done"; value: T }
168
-
169
- export type Index = {
170
- rootUrl: AutomergeUrl,
171
- entries: AutomergeUrl[],
172
- }
173
-
174
- function parseUrl(
175
- urlStr: string
176
- ): { url: AutomergeUrl } | undefined {
177
- const match = urlStr.match(URL_RE)
178
- if (!match) {
179
- return undefined
180
- }
181
- const url = new URL(match[0])
182
- const normalisedUrl = `automerge:${url.pathname}`
183
- return { url: normalisedUrl as AutomergeUrl }
184
- }