@automerge/automerge-repo 1.0.12 → 1.0.13
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/dist/AutomergeUrl.d.ts +45 -0
- package/dist/AutomergeUrl.d.ts.map +1 -0
- package/dist/AutomergeUrl.js +108 -0
- package/dist/DocHandle.js +1 -1
- package/dist/Repo.d.ts +5 -5
- package/dist/Repo.d.ts.map +1 -1
- package/dist/Repo.js +9 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/synchronizer/CollectionSynchronizer.js +1 -1
- package/dist/types.d.ts +20 -12
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/AutomergeUrl.ts +144 -0
- package/src/DocHandle.ts +1 -1
- package/src/Repo.ts +13 -25
- package/src/index.ts +1 -1
- package/src/synchronizer/CollectionSynchronizer.ts +1 -1
- package/src/types.ts +23 -11
- package/test/AutomergeUrl.test.ts +100 -0
- package/test/DocHandle.test.ts +1 -1
- package/test/DocSynchronizer.test.ts +1 -1
- package/test/Repo.test.ts +22 -6
- package/test/StorageSubsystem.test.ts +1 -1
- package/dist/DocUrl.d.ts +0 -39
- package/dist/DocUrl.d.ts.map +0 -1
- package/dist/DocUrl.js +0 -74
- package/src/DocUrl.ts +0 -96
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { LegacyDocumentId, AutomergeUrl, BinaryDocumentId, DocumentId, AnyDocumentId } from "./types.js";
|
|
2
|
+
export declare const urlPrefix = "automerge:";
|
|
3
|
+
/** Given an Automerge URL, returns the DocumentId in both base58check-encoded form and binary form */
|
|
4
|
+
export declare const parseAutomergeUrl: (url: AutomergeUrl) => {
|
|
5
|
+
/** unencoded DocumentId */
|
|
6
|
+
binaryDocumentId: BinaryDocumentId;
|
|
7
|
+
/** encoded DocumentId */
|
|
8
|
+
documentId: DocumentId;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Given a documentId in either binary or base58check-encoded form, returns an Automerge URL.
|
|
12
|
+
* Throws on invalid input.
|
|
13
|
+
*/
|
|
14
|
+
export declare const stringifyAutomergeUrl: (arg: UrlOptions | DocumentId | BinaryDocumentId) => AutomergeUrl;
|
|
15
|
+
/**
|
|
16
|
+
* Given a string, returns true if it is a valid Automerge URL. This function also acts as a type
|
|
17
|
+
* discriminator in Typescript.
|
|
18
|
+
*/
|
|
19
|
+
export declare const isValidAutomergeUrl: (str: string | undefined | null) => str is AutomergeUrl;
|
|
20
|
+
export declare const isValidDocumentId: (str: string) => str is DocumentId;
|
|
21
|
+
export declare const isValidUuid: (str: string) => str is LegacyDocumentId;
|
|
22
|
+
/**
|
|
23
|
+
* Returns a new Automerge URL with a random UUID documentId. Called by Repo.create(), and also used by tests.
|
|
24
|
+
*/
|
|
25
|
+
export declare const generateAutomergeUrl: () => AutomergeUrl;
|
|
26
|
+
export declare const documentIdToBinary: (docId: DocumentId) => BinaryDocumentId | undefined;
|
|
27
|
+
export declare const binaryToDocumentId: (docId: BinaryDocumentId) => DocumentId;
|
|
28
|
+
export declare const parseLegacyUUID: (str: string) => AutomergeUrl | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Given any valid expression of a document ID, returns a DocumentId in base58check-encoded form.
|
|
31
|
+
*
|
|
32
|
+
* Currently supports:
|
|
33
|
+
* - base58check-encoded DocumentId
|
|
34
|
+
* - Automerge URL
|
|
35
|
+
* - legacy UUID
|
|
36
|
+
* - binary DocumentId
|
|
37
|
+
*
|
|
38
|
+
* Throws on invalid input.
|
|
39
|
+
*/
|
|
40
|
+
export declare const interpretAsDocumentId: (id: AnyDocumentId) => DocumentId;
|
|
41
|
+
type UrlOptions = {
|
|
42
|
+
documentId: DocumentId | BinaryDocumentId;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=AutomergeUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutomergeUrl.d.ts","sourceRoot":"","sources":["../src/AutomergeUrl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAA;AAInB,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,QAAS,YAAY;IAQ/C,2BAA2B;;IAE3B,yBAAyB;;CAG5B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAC3B,UAAU,GAAG,UAAU,GAAG,gBAAgB,iBAoBhD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QACzB,MAAM,GAAG,SAAS,GAAG,IAAI,wBAU/B,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAS,MAAM,sBAQ5C,CAAA;AAED,eAAO,MAAM,WAAW,QAAS,MAAM,4BACnB,CAAA;AAEpB;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGvC,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAW,UAAU,iCACW,CAAA;AAE/D,eAAO,MAAM,kBAAkB,UAAW,gBAAgB,eACnB,CAAA;AAEvC,eAAO,MAAM,eAAe,QAAS,MAAM,6BAI1C,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,OAAQ,aAAa,eAqBtD,CAAA;AAID,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAA;CAC1C,CAAA"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as Uuid from "uuid";
|
|
2
|
+
import bs58check from "bs58check";
|
|
3
|
+
export const urlPrefix = "automerge:";
|
|
4
|
+
/** Given an Automerge URL, returns the DocumentId in both base58check-encoded form and binary form */
|
|
5
|
+
export const parseAutomergeUrl = (url) => {
|
|
6
|
+
const regex = new RegExp(`^${urlPrefix}(\\w+)$`);
|
|
7
|
+
const [_, docMatch] = url.match(regex) || [];
|
|
8
|
+
const documentId = docMatch;
|
|
9
|
+
const binaryDocumentId = documentIdToBinary(documentId);
|
|
10
|
+
if (!binaryDocumentId)
|
|
11
|
+
throw new Error("Invalid document URL: " + url);
|
|
12
|
+
return {
|
|
13
|
+
/** unencoded DocumentId */
|
|
14
|
+
binaryDocumentId,
|
|
15
|
+
/** encoded DocumentId */
|
|
16
|
+
documentId,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Given a documentId in either binary or base58check-encoded form, returns an Automerge URL.
|
|
21
|
+
* Throws on invalid input.
|
|
22
|
+
*/
|
|
23
|
+
export const stringifyAutomergeUrl = (arg) => {
|
|
24
|
+
let documentId = arg instanceof Uint8Array || typeof arg === "string"
|
|
25
|
+
? arg
|
|
26
|
+
: "documentId" in arg
|
|
27
|
+
? arg.documentId
|
|
28
|
+
: undefined;
|
|
29
|
+
const encodedDocumentId = documentId instanceof Uint8Array
|
|
30
|
+
? binaryToDocumentId(documentId)
|
|
31
|
+
: typeof documentId === "string"
|
|
32
|
+
? documentId
|
|
33
|
+
: undefined;
|
|
34
|
+
if (encodedDocumentId === undefined)
|
|
35
|
+
throw new Error("Invalid documentId: " + documentId);
|
|
36
|
+
return (urlPrefix + encodedDocumentId);
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Given a string, returns true if it is a valid Automerge URL. This function also acts as a type
|
|
40
|
+
* discriminator in Typescript.
|
|
41
|
+
*/
|
|
42
|
+
export const isValidAutomergeUrl = (str) => {
|
|
43
|
+
if (!str || !str.startsWith(urlPrefix))
|
|
44
|
+
return false;
|
|
45
|
+
const automergeUrl = str;
|
|
46
|
+
try {
|
|
47
|
+
const { documentId } = parseAutomergeUrl(automergeUrl);
|
|
48
|
+
return isValidDocumentId(documentId);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
export const isValidDocumentId = (str) => {
|
|
55
|
+
// try to decode from base58
|
|
56
|
+
const binaryDocumentID = documentIdToBinary(str);
|
|
57
|
+
if (binaryDocumentID === undefined)
|
|
58
|
+
return false; // invalid base58check encoding
|
|
59
|
+
// confirm that the document ID is a valid UUID
|
|
60
|
+
const documentId = Uuid.stringify(binaryDocumentID);
|
|
61
|
+
return Uuid.validate(documentId);
|
|
62
|
+
};
|
|
63
|
+
export const isValidUuid = (str) => Uuid.validate(str);
|
|
64
|
+
/**
|
|
65
|
+
* Returns a new Automerge URL with a random UUID documentId. Called by Repo.create(), and also used by tests.
|
|
66
|
+
*/
|
|
67
|
+
export const generateAutomergeUrl = () => {
|
|
68
|
+
const documentId = Uuid.v4(null, new Uint8Array(16));
|
|
69
|
+
return stringifyAutomergeUrl({ documentId });
|
|
70
|
+
};
|
|
71
|
+
export const documentIdToBinary = (docId) => bs58check.decodeUnsafe(docId);
|
|
72
|
+
export const binaryToDocumentId = (docId) => bs58check.encode(docId);
|
|
73
|
+
export const parseLegacyUUID = (str) => {
|
|
74
|
+
if (!Uuid.validate(str))
|
|
75
|
+
return undefined;
|
|
76
|
+
const documentId = Uuid.parse(str);
|
|
77
|
+
return stringifyAutomergeUrl({ documentId });
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Given any valid expression of a document ID, returns a DocumentId in base58check-encoded form.
|
|
81
|
+
*
|
|
82
|
+
* Currently supports:
|
|
83
|
+
* - base58check-encoded DocumentId
|
|
84
|
+
* - Automerge URL
|
|
85
|
+
* - legacy UUID
|
|
86
|
+
* - binary DocumentId
|
|
87
|
+
*
|
|
88
|
+
* Throws on invalid input.
|
|
89
|
+
*/
|
|
90
|
+
export const interpretAsDocumentId = (id) => {
|
|
91
|
+
// binary
|
|
92
|
+
if (id instanceof Uint8Array)
|
|
93
|
+
return binaryToDocumentId(id);
|
|
94
|
+
// url
|
|
95
|
+
if (isValidAutomergeUrl(id))
|
|
96
|
+
return parseAutomergeUrl(id).documentId;
|
|
97
|
+
// base58check
|
|
98
|
+
if (isValidDocumentId(id))
|
|
99
|
+
return id;
|
|
100
|
+
// legacy UUID
|
|
101
|
+
if (isValidUuid(id)) {
|
|
102
|
+
console.warn("Future versions will not support UUIDs as document IDs; use Automerge URLs instead.");
|
|
103
|
+
const binaryDocumentID = Uuid.parse(id);
|
|
104
|
+
return binaryToDocumentId(binaryDocumentID);
|
|
105
|
+
}
|
|
106
|
+
// none of the above
|
|
107
|
+
throw new Error(`Invalid AutomergeUrl: '${id}'`);
|
|
108
|
+
};
|
package/dist/DocHandle.js
CHANGED
|
@@ -3,7 +3,7 @@ import debug from "debug";
|
|
|
3
3
|
import { EventEmitter } from "eventemitter3";
|
|
4
4
|
import { assign, createMachine, interpret, } from "xstate";
|
|
5
5
|
import { waitFor } from "xstate/lib/waitFor.js";
|
|
6
|
-
import { stringifyAutomergeUrl } from "./
|
|
6
|
+
import { stringifyAutomergeUrl } from "./AutomergeUrl.js";
|
|
7
7
|
import { encode } from "./helpers/cbor.js";
|
|
8
8
|
import { headsAreSame } from "./helpers/headsAreSame.js";
|
|
9
9
|
import { withTimeout } from "./helpers/withTimeout.js";
|
package/dist/Repo.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { NetworkAdapter } from "./network/NetworkAdapter.js";
|
|
|
4
4
|
import { NetworkSubsystem } from "./network/NetworkSubsystem.js";
|
|
5
5
|
import { StorageAdapter } from "./storage/StorageAdapter.js";
|
|
6
6
|
import { StorageSubsystem } from "./storage/StorageSubsystem.js";
|
|
7
|
-
import { DocumentId, PeerId
|
|
7
|
+
import type { AnyDocumentId, DocumentId, PeerId } from "./types.js";
|
|
8
8
|
/** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
|
|
9
9
|
/** The `Repo` is the main entry point of this library
|
|
10
10
|
*
|
|
@@ -55,11 +55,11 @@ export declare class Repo extends EventEmitter<RepoEvents> {
|
|
|
55
55
|
* event to advertise interest in the document.
|
|
56
56
|
*/
|
|
57
57
|
find<T>(
|
|
58
|
-
/** The documentId of the handle to retrieve */
|
|
59
|
-
|
|
58
|
+
/** The url or documentId of the handle to retrieve */
|
|
59
|
+
id: AnyDocumentId): DocHandle<T>;
|
|
60
60
|
delete(
|
|
61
|
-
/** The documentId of the handle to delete */
|
|
62
|
-
id:
|
|
61
|
+
/** The url or documentId of the handle to delete */
|
|
62
|
+
id: AnyDocumentId): void;
|
|
63
63
|
}
|
|
64
64
|
export interface RepoConfig {
|
|
65
65
|
/** Our unique identifier */
|
package/dist/Repo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAM5C,OAAO,EAAE,SAAS,EAAiC,MAAM,gBAAgB,CAAA;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnE,8FAA8F;AAC9F;;;;;;GAMG;AACH,qBAAa,IAAK,SAAQ,YAAY,CAAC,UAAU,CAAC;;IAGhD,cAAc;IACd,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,cAAc;IACd,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC,mDAAmD;IACnD,cAAc;IACd,gBAAgB,SAAM;IAItB,sDAAsD;IACtD,cAAc;IACd,WAAW,EAAE,WAAW,CAAmB;gBAE/B,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;IA8HjE,8CAA8C;IAC9C,IAAI,OAAO,uCAEV;IAED;;;;OAIG;IACH,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IA0BzB;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;IAuBnC;;;OAGG;IACH,IAAI,CAAC,CAAC;IACJ,sDAAsD;IACtD,EAAE,EAAE,aAAa,GAChB,SAAS,CAAC,CAAC,CAAC;IAqBf,MAAM;IACJ,oDAAoD;IACpD,EAAE,EAAE,aAAa;CAUpB;AAED,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,gDAAgD;IAChD,OAAO,CAAC,EAAE,cAAc,CAAA;IAExB,oDAAoD;IACpD,OAAO,EAAE,cAAc,EAAE,CAAA;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED;;;;;;;KAOK;AACL,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,OAAO,CAAC,CAAA;AAGrB,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,6BAA6B;IAC7B,iBAAiB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IACvD,4FAA4F;IAC5F,sBAAsB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;CAC7D;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,UAAU,CAAA;CACvB"}
|
package/dist/Repo.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { next as Automerge } from "@automerge/automerge";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
import { EventEmitter } from "eventemitter3";
|
|
4
|
+
import { generateAutomergeUrl, interpretAsDocumentId, parseAutomergeUrl, } from "./AutomergeUrl.js";
|
|
4
5
|
import { DocHandle } from "./DocHandle.js";
|
|
5
|
-
import { generateAutomergeUrl, isValidAutomergeUrl, parseAutomergeUrl, parseLegacyUUID, } from "./DocUrl.js";
|
|
6
6
|
import { throttle } from "./helpers/throttle.js";
|
|
7
7
|
import { NetworkSubsystem } from "./network/NetworkSubsystem.js";
|
|
8
8
|
import { StorageSubsystem } from "./storage/StorageSubsystem.js";
|
|
@@ -198,19 +198,9 @@ export class Repo extends EventEmitter {
|
|
|
198
198
|
* event to advertise interest in the document.
|
|
199
199
|
*/
|
|
200
200
|
find(
|
|
201
|
-
/** The documentId of the handle to retrieve */
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const maybeAutomergeUrl = parseLegacyUUID(automergeUrl);
|
|
205
|
-
if (maybeAutomergeUrl) {
|
|
206
|
-
console.warn("Legacy UUID document ID detected, converting to AutomergeUrl. This will be removed in a future version.");
|
|
207
|
-
automergeUrl = maybeAutomergeUrl;
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
throw new Error(`Invalid AutomergeUrl: '${automergeUrl}'`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
const { documentId } = parseAutomergeUrl(automergeUrl);
|
|
201
|
+
/** The url or documentId of the handle to retrieve */
|
|
202
|
+
id) {
|
|
203
|
+
const documentId = interpretAsDocumentId(id);
|
|
214
204
|
// If we have the handle cached, return it
|
|
215
205
|
if (this.#handleCache[documentId]) {
|
|
216
206
|
if (this.#handleCache[documentId].isUnavailable()) {
|
|
@@ -228,13 +218,12 @@ export class Repo extends EventEmitter {
|
|
|
228
218
|
return handle;
|
|
229
219
|
}
|
|
230
220
|
delete(
|
|
231
|
-
/** The documentId of the handle to delete */
|
|
221
|
+
/** The url or documentId of the handle to delete */
|
|
232
222
|
id) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const handle = this.#getHandle(id, false);
|
|
223
|
+
const documentId = interpretAsDocumentId(id);
|
|
224
|
+
const handle = this.#getHandle(documentId, false);
|
|
236
225
|
handle.delete();
|
|
237
|
-
delete this.#handleCache[
|
|
238
|
-
this.emit("delete-document", { documentId
|
|
226
|
+
delete this.#handleCache[documentId];
|
|
227
|
+
this.emit("delete-document", { documentId });
|
|
239
228
|
}
|
|
240
229
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
export { DocHandle } from "./DocHandle.js";
|
|
29
|
-
export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./
|
|
29
|
+
export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./AutomergeUrl.js";
|
|
30
30
|
export { Repo } from "./Repo.js";
|
|
31
31
|
export { NetworkAdapter } from "./network/NetworkAdapter.js";
|
|
32
32
|
export { isValidRepoMessage } from "./network/messages.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D,eAAe;AACf,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA;AAIzC,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,gCAAgC,EAChC,eAAe,EACf,gBAAgB,EAChB,wCAAwC,EACxC,WAAW,GACZ,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,GACZ,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AACpC,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7D,cAAc,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
export { DocHandle } from "./DocHandle.js";
|
|
29
|
-
export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./
|
|
29
|
+
export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./AutomergeUrl.js";
|
|
30
30
|
export { Repo } from "./Repo.js";
|
|
31
31
|
export { NetworkAdapter } from "./network/NetworkAdapter.js";
|
|
32
32
|
export { isValidRepoMessage } from "./network/messages.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
|
-
import { stringifyAutomergeUrl } from "../
|
|
2
|
+
import { stringifyAutomergeUrl } from "../AutomergeUrl.js";
|
|
3
3
|
import { DocSynchronizer } from "./DocSynchronizer.js";
|
|
4
4
|
import { Synchronizer } from "./Synchronizer.js";
|
|
5
5
|
const log = debug("automerge-repo:collectionsync");
|
package/dist/types.d.ts
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
__documentId: true;
|
|
5
|
-
};
|
|
6
|
-
/** A branded string representing a URL for a document
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
* An automerge URL has the form `automerge:<base58 encoded string>`. This
|
|
10
|
-
* type is returned from various routines which validate a url.
|
|
11
|
-
*
|
|
1
|
+
/**
|
|
2
|
+
* A branded string representing a URL for a document, in the form `automerge:<base58check encoded
|
|
3
|
+
* string>`; for example, `automerge:4NMNnkMhL8jXrdJ9jamS58PAVdXu`.
|
|
12
4
|
*/
|
|
13
5
|
export type AutomergeUrl = string & {
|
|
14
6
|
__documentUrl: true;
|
|
15
7
|
};
|
|
16
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* The base58check-encoded UUID of a document. This is the string following the `automerge:`
|
|
10
|
+
* protocol prefix in an AutomergeUrl; for example, `4NMNnkMhL8jXrdJ9jamS58PAVdXu`. When recording
|
|
11
|
+
* links to an Automerge document in another Automerge document, you should store a
|
|
12
|
+
* {@link AutomergeUrl} instead.
|
|
17
13
|
*/
|
|
14
|
+
export type DocumentId = string & {
|
|
15
|
+
__documentId: true;
|
|
16
|
+
};
|
|
17
|
+
/** The unencoded UUID of a document. Typically you should use a {@link AutomergeUrl} instead. */
|
|
18
18
|
export type BinaryDocumentId = Uint8Array & {
|
|
19
19
|
__binaryDocumentId: true;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* A UUID encoded as a hex string. As of v1.0, a {@link DocumentID} is stored as a base58-encoded string with a checksum.
|
|
23
|
+
* Support for this format will be removed in a future version.
|
|
24
|
+
*/
|
|
25
|
+
export type LegacyDocumentId = string & {
|
|
26
|
+
__legacyDocumentId: true;
|
|
27
|
+
};
|
|
28
|
+
export type AnyDocumentId = AutomergeUrl | DocumentId | BinaryDocumentId | LegacyDocumentId;
|
|
21
29
|
/** A branded type for peer IDs */
|
|
22
30
|
export type PeerId = string & {
|
|
23
31
|
__peerId: true;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,aAAa,EAAE,IAAI,CAAA;CAAE,CAAA;AAE3D;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,YAAY,EAAE,IAAI,CAAA;CAAE,CAAA;AAExD,iGAAiG;AACjG,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAAE,kBAAkB,EAAE,IAAI,CAAA;CAAE,CAAA;AAExE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG;IAAE,kBAAkB,EAAE,IAAI,CAAA;CAAE,CAAA;AAEpE,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,UAAU,GACV,gBAAgB,GAChB,gBAAgB,CAAA;AAEpB,kCAAkC;AAClC,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAA;AAEhD,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "A repository object to manage a collection of automerge documents",
|
|
5
5
|
"repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo",
|
|
6
6
|
"author": "Peter van Hardenberg <pvh@pvh.ca>",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "48ca7b968758d7fd95f13fa03dc69d452cdd15f5"
|
|
61
61
|
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LegacyDocumentId,
|
|
3
|
+
AutomergeUrl,
|
|
4
|
+
BinaryDocumentId,
|
|
5
|
+
DocumentId,
|
|
6
|
+
AnyDocumentId,
|
|
7
|
+
} from "./types.js"
|
|
8
|
+
import * as Uuid from "uuid"
|
|
9
|
+
import bs58check from "bs58check"
|
|
10
|
+
|
|
11
|
+
export const urlPrefix = "automerge:"
|
|
12
|
+
|
|
13
|
+
/** Given an Automerge URL, returns the DocumentId in both base58check-encoded form and binary form */
|
|
14
|
+
export const parseAutomergeUrl = (url: AutomergeUrl) => {
|
|
15
|
+
const regex = new RegExp(`^${urlPrefix}(\\w+)$`)
|
|
16
|
+
const [_, docMatch] = url.match(regex) || []
|
|
17
|
+
const documentId = docMatch as DocumentId
|
|
18
|
+
const binaryDocumentId = documentIdToBinary(documentId)
|
|
19
|
+
|
|
20
|
+
if (!binaryDocumentId) throw new Error("Invalid document URL: " + url)
|
|
21
|
+
return {
|
|
22
|
+
/** unencoded DocumentId */
|
|
23
|
+
binaryDocumentId,
|
|
24
|
+
/** encoded DocumentId */
|
|
25
|
+
documentId,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Given a documentId in either binary or base58check-encoded form, returns an Automerge URL.
|
|
31
|
+
* Throws on invalid input.
|
|
32
|
+
*/
|
|
33
|
+
export const stringifyAutomergeUrl = (
|
|
34
|
+
arg: UrlOptions | DocumentId | BinaryDocumentId
|
|
35
|
+
) => {
|
|
36
|
+
let documentId =
|
|
37
|
+
arg instanceof Uint8Array || typeof arg === "string"
|
|
38
|
+
? arg
|
|
39
|
+
: "documentId" in arg
|
|
40
|
+
? arg.documentId
|
|
41
|
+
: undefined
|
|
42
|
+
|
|
43
|
+
const encodedDocumentId =
|
|
44
|
+
documentId instanceof Uint8Array
|
|
45
|
+
? binaryToDocumentId(documentId)
|
|
46
|
+
: typeof documentId === "string"
|
|
47
|
+
? documentId
|
|
48
|
+
: undefined
|
|
49
|
+
|
|
50
|
+
if (encodedDocumentId === undefined)
|
|
51
|
+
throw new Error("Invalid documentId: " + documentId)
|
|
52
|
+
|
|
53
|
+
return (urlPrefix + encodedDocumentId) as AutomergeUrl
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Given a string, returns true if it is a valid Automerge URL. This function also acts as a type
|
|
58
|
+
* discriminator in Typescript.
|
|
59
|
+
*/
|
|
60
|
+
export const isValidAutomergeUrl = (
|
|
61
|
+
str: string | undefined | null
|
|
62
|
+
): str is AutomergeUrl => {
|
|
63
|
+
if (!str || !str.startsWith(urlPrefix)) return false
|
|
64
|
+
const automergeUrl = str as AutomergeUrl
|
|
65
|
+
try {
|
|
66
|
+
const { documentId } = parseAutomergeUrl(automergeUrl)
|
|
67
|
+
return isValidDocumentId(documentId)
|
|
68
|
+
} catch {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const isValidDocumentId = (str: string): str is DocumentId => {
|
|
74
|
+
// try to decode from base58
|
|
75
|
+
const binaryDocumentID = documentIdToBinary(str as DocumentId)
|
|
76
|
+
if (binaryDocumentID === undefined) return false // invalid base58check encoding
|
|
77
|
+
|
|
78
|
+
// confirm that the document ID is a valid UUID
|
|
79
|
+
const documentId = Uuid.stringify(binaryDocumentID)
|
|
80
|
+
return Uuid.validate(documentId)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const isValidUuid = (str: string): str is LegacyDocumentId =>
|
|
84
|
+
Uuid.validate(str)
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Returns a new Automerge URL with a random UUID documentId. Called by Repo.create(), and also used by tests.
|
|
88
|
+
*/
|
|
89
|
+
export const generateAutomergeUrl = (): AutomergeUrl => {
|
|
90
|
+
const documentId = Uuid.v4(null, new Uint8Array(16)) as BinaryDocumentId
|
|
91
|
+
return stringifyAutomergeUrl({ documentId })
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const documentIdToBinary = (docId: DocumentId) =>
|
|
95
|
+
bs58check.decodeUnsafe(docId) as BinaryDocumentId | undefined
|
|
96
|
+
|
|
97
|
+
export const binaryToDocumentId = (docId: BinaryDocumentId) =>
|
|
98
|
+
bs58check.encode(docId) as DocumentId
|
|
99
|
+
|
|
100
|
+
export const parseLegacyUUID = (str: string) => {
|
|
101
|
+
if (!Uuid.validate(str)) return undefined
|
|
102
|
+
const documentId = Uuid.parse(str) as BinaryDocumentId
|
|
103
|
+
return stringifyAutomergeUrl({ documentId })
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Given any valid expression of a document ID, returns a DocumentId in base58check-encoded form.
|
|
108
|
+
*
|
|
109
|
+
* Currently supports:
|
|
110
|
+
* - base58check-encoded DocumentId
|
|
111
|
+
* - Automerge URL
|
|
112
|
+
* - legacy UUID
|
|
113
|
+
* - binary DocumentId
|
|
114
|
+
*
|
|
115
|
+
* Throws on invalid input.
|
|
116
|
+
*/
|
|
117
|
+
export const interpretAsDocumentId = (id: AnyDocumentId) => {
|
|
118
|
+
// binary
|
|
119
|
+
if (id instanceof Uint8Array) return binaryToDocumentId(id)
|
|
120
|
+
|
|
121
|
+
// url
|
|
122
|
+
if (isValidAutomergeUrl(id)) return parseAutomergeUrl(id).documentId
|
|
123
|
+
|
|
124
|
+
// base58check
|
|
125
|
+
if (isValidDocumentId(id)) return id
|
|
126
|
+
|
|
127
|
+
// legacy UUID
|
|
128
|
+
if (isValidUuid(id)) {
|
|
129
|
+
console.warn(
|
|
130
|
+
"Future versions will not support UUIDs as document IDs; use Automerge URLs instead."
|
|
131
|
+
)
|
|
132
|
+
const binaryDocumentID = Uuid.parse(id) as BinaryDocumentId
|
|
133
|
+
return binaryToDocumentId(binaryDocumentID)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// none of the above
|
|
137
|
+
throw new Error(`Invalid AutomergeUrl: '${id}'`)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// TYPES
|
|
141
|
+
|
|
142
|
+
type UrlOptions = {
|
|
143
|
+
documentId: DocumentId | BinaryDocumentId
|
|
144
|
+
}
|
package/src/DocHandle.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
TypegenDisabled,
|
|
15
15
|
} from "xstate"
|
|
16
16
|
import { waitFor } from "xstate/lib/waitFor.js"
|
|
17
|
-
import { stringifyAutomergeUrl } from "./
|
|
17
|
+
import { stringifyAutomergeUrl } from "./AutomergeUrl.js"
|
|
18
18
|
import { encode } from "./helpers/cbor.js"
|
|
19
19
|
import { headsAreSame } from "./helpers/headsAreSame.js"
|
|
20
20
|
import { withTimeout } from "./helpers/withTimeout.js"
|
package/src/Repo.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { next as Automerge } from "@automerge/automerge"
|
|
2
2
|
import debug from "debug"
|
|
3
3
|
import { EventEmitter } from "eventemitter3"
|
|
4
|
-
import { DocHandle, DocHandleEncodedChangePayload } from "./DocHandle.js"
|
|
5
4
|
import {
|
|
6
5
|
generateAutomergeUrl,
|
|
7
|
-
|
|
6
|
+
interpretAsDocumentId,
|
|
8
7
|
parseAutomergeUrl,
|
|
9
|
-
|
|
10
|
-
} from "./
|
|
8
|
+
} from "./AutomergeUrl.js"
|
|
9
|
+
import { DocHandle, DocHandleEncodedChangePayload } from "./DocHandle.js"
|
|
11
10
|
import { throttle } from "./helpers/throttle.js"
|
|
12
11
|
import { NetworkAdapter } from "./network/NetworkAdapter.js"
|
|
13
12
|
import { NetworkSubsystem } from "./network/NetworkSubsystem.js"
|
|
14
13
|
import { StorageAdapter } from "./storage/StorageAdapter.js"
|
|
15
14
|
import { StorageSubsystem } from "./storage/StorageSubsystem.js"
|
|
16
15
|
import { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js"
|
|
17
|
-
import { DocumentId, PeerId
|
|
16
|
+
import type { AnyDocumentId, DocumentId, PeerId } from "./types.js"
|
|
18
17
|
|
|
19
18
|
/** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
|
|
20
19
|
/** The `Repo` is the main entry point of this library
|
|
@@ -247,22 +246,11 @@ export class Repo extends EventEmitter<RepoEvents> {
|
|
|
247
246
|
* event to advertise interest in the document.
|
|
248
247
|
*/
|
|
249
248
|
find<T>(
|
|
250
|
-
/** The documentId of the handle to retrieve */
|
|
251
|
-
|
|
249
|
+
/** The url or documentId of the handle to retrieve */
|
|
250
|
+
id: AnyDocumentId
|
|
252
251
|
): DocHandle<T> {
|
|
253
|
-
|
|
254
|
-
const maybeAutomergeUrl = parseLegacyUUID(automergeUrl)
|
|
255
|
-
if (maybeAutomergeUrl) {
|
|
256
|
-
console.warn(
|
|
257
|
-
"Legacy UUID document ID detected, converting to AutomergeUrl. This will be removed in a future version."
|
|
258
|
-
)
|
|
259
|
-
automergeUrl = maybeAutomergeUrl
|
|
260
|
-
} else {
|
|
261
|
-
throw new Error(`Invalid AutomergeUrl: '${automergeUrl}'`)
|
|
262
|
-
}
|
|
263
|
-
}
|
|
252
|
+
const documentId = interpretAsDocumentId(id)
|
|
264
253
|
|
|
265
|
-
const { documentId } = parseAutomergeUrl(automergeUrl)
|
|
266
254
|
// If we have the handle cached, return it
|
|
267
255
|
if (this.#handleCache[documentId]) {
|
|
268
256
|
if (this.#handleCache[documentId].isUnavailable()) {
|
|
@@ -282,16 +270,16 @@ export class Repo extends EventEmitter<RepoEvents> {
|
|
|
282
270
|
}
|
|
283
271
|
|
|
284
272
|
delete(
|
|
285
|
-
/** The documentId of the handle to delete */
|
|
286
|
-
id:
|
|
273
|
+
/** The url or documentId of the handle to delete */
|
|
274
|
+
id: AnyDocumentId
|
|
287
275
|
) {
|
|
288
|
-
|
|
276
|
+
const documentId = interpretAsDocumentId(id)
|
|
289
277
|
|
|
290
|
-
const handle = this.#getHandle(
|
|
278
|
+
const handle = this.#getHandle(documentId, false)
|
|
291
279
|
handle.delete()
|
|
292
280
|
|
|
293
|
-
delete this.#handleCache[
|
|
294
|
-
this.emit("delete-document", { documentId
|
|
281
|
+
delete this.#handleCache[documentId]
|
|
282
|
+
this.emit("delete-document", { documentId })
|
|
295
283
|
}
|
|
296
284
|
}
|
|
297
285
|
|
package/src/index.ts
CHANGED
|
@@ -31,7 +31,7 @@ export {
|
|
|
31
31
|
isValidAutomergeUrl,
|
|
32
32
|
parseAutomergeUrl,
|
|
33
33
|
stringifyAutomergeUrl,
|
|
34
|
-
} from "./
|
|
34
|
+
} from "./AutomergeUrl.js"
|
|
35
35
|
export { Repo } from "./Repo.js"
|
|
36
36
|
export { NetworkAdapter } from "./network/NetworkAdapter.js"
|
|
37
37
|
export { isValidRepoMessage } from "./network/messages.js"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import debug from "debug"
|
|
2
2
|
import { DocHandle } from "../DocHandle.js"
|
|
3
|
-
import { stringifyAutomergeUrl } from "../
|
|
3
|
+
import { stringifyAutomergeUrl } from "../AutomergeUrl.js"
|
|
4
4
|
import { Repo } from "../Repo.js"
|
|
5
5
|
import { RepoMessage } from "../network/messages.js"
|
|
6
6
|
import { DocumentId, PeerId } from "../types.js"
|
package/src/types.ts
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/** A branded string representing a URL for a document
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* An automerge URL has the form `automerge:<base58 encoded string>`. This
|
|
9
|
-
* type is returned from various routines which validate a url.
|
|
10
|
-
*
|
|
1
|
+
/**
|
|
2
|
+
* A branded string representing a URL for a document, in the form `automerge:<base58check encoded
|
|
3
|
+
* string>`; for example, `automerge:4NMNnkMhL8jXrdJ9jamS58PAVdXu`.
|
|
11
4
|
*/
|
|
12
5
|
export type AutomergeUrl = string & { __documentUrl: true } // for opening / linking
|
|
13
6
|
|
|
14
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* The base58check-encoded UUID of a document. This is the string following the `automerge:`
|
|
9
|
+
* protocol prefix in an AutomergeUrl; for example, `4NMNnkMhL8jXrdJ9jamS58PAVdXu`. When recording
|
|
10
|
+
* links to an Automerge document in another Automerge document, you should store a
|
|
11
|
+
* {@link AutomergeUrl} instead.
|
|
15
12
|
*/
|
|
13
|
+
export type DocumentId = string & { __documentId: true } // for logging
|
|
14
|
+
|
|
15
|
+
/** The unencoded UUID of a document. Typically you should use a {@link AutomergeUrl} instead. */
|
|
16
16
|
export type BinaryDocumentId = Uint8Array & { __binaryDocumentId: true } // for storing / syncing
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* A UUID encoded as a hex string. As of v1.0, a {@link DocumentID} is stored as a base58-encoded string with a checksum.
|
|
20
|
+
* Support for this format will be removed in a future version.
|
|
21
|
+
*/
|
|
22
|
+
export type LegacyDocumentId = string & { __legacyDocumentId: true }
|
|
23
|
+
|
|
24
|
+
export type AnyDocumentId =
|
|
25
|
+
| AutomergeUrl
|
|
26
|
+
| DocumentId
|
|
27
|
+
| BinaryDocumentId
|
|
28
|
+
| LegacyDocumentId
|
|
29
|
+
|
|
18
30
|
/** A branded type for peer IDs */
|
|
19
31
|
export type PeerId = string & { __peerId: true }
|
|
20
32
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import assert from "assert"
|
|
2
|
+
import bs58check from "bs58check"
|
|
3
|
+
import { describe, it } from "vitest"
|
|
4
|
+
import {
|
|
5
|
+
generateAutomergeUrl,
|
|
6
|
+
isValidAutomergeUrl,
|
|
7
|
+
parseAutomergeUrl,
|
|
8
|
+
stringifyAutomergeUrl,
|
|
9
|
+
} from "../src/AutomergeUrl.js"
|
|
10
|
+
import type {
|
|
11
|
+
AutomergeUrl,
|
|
12
|
+
BinaryDocumentId,
|
|
13
|
+
DocumentId,
|
|
14
|
+
} from "../src/types.js"
|
|
15
|
+
|
|
16
|
+
const goodUrl = "automerge:4NMNnkMhL8jXrdJ9jamS58PAVdXu" as AutomergeUrl
|
|
17
|
+
const badChecksumUrl = "automerge:badbadbad" as AutomergeUrl
|
|
18
|
+
const badPrefixUrl = "yjs😉:4NMNnkMhL8jXrdJ9jamS58PAVdXu" as AutomergeUrl
|
|
19
|
+
|
|
20
|
+
const goodDocumentId = "4NMNnkMhL8jXrdJ9jamS58PAVdXu" as DocumentId
|
|
21
|
+
const badChecksumDocumentId = "badbadbad" as DocumentId
|
|
22
|
+
const badUuidDocumentId = bs58check.encode(
|
|
23
|
+
new Uint8Array([1, 2, 3, 4, 42, -1, 69, 777])
|
|
24
|
+
) as DocumentId
|
|
25
|
+
|
|
26
|
+
const goodBinaryDocumentId = Uint8Array.from([
|
|
27
|
+
241, 194, 156, 132, 116, 200, 74, 222, 184, 0, 190, 71, 98, 125, 51, 191,
|
|
28
|
+
]) as BinaryDocumentId
|
|
29
|
+
|
|
30
|
+
describe("AutomergeUrl", () => {
|
|
31
|
+
describe("generateAutomergeUrl", () => {
|
|
32
|
+
it("should generate a valid Automerge URL", () => {
|
|
33
|
+
const url = generateAutomergeUrl()
|
|
34
|
+
assert(url.startsWith("automerge:"))
|
|
35
|
+
assert(parseAutomergeUrl(url).binaryDocumentId)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe("stringifyAutomergeUrl", () => {
|
|
40
|
+
it("should stringify a binary document ID", () => {
|
|
41
|
+
const url = stringifyAutomergeUrl({ documentId: goodBinaryDocumentId })
|
|
42
|
+
assert.strictEqual(url, goodUrl)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it("should stringify a string document ID", () => {
|
|
46
|
+
const url = stringifyAutomergeUrl({ documentId: goodDocumentId })
|
|
47
|
+
assert.strictEqual(url, goodUrl)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("supports passing a document ID without wrapping it in an object", () => {
|
|
51
|
+
const url1 = stringifyAutomergeUrl(goodDocumentId)
|
|
52
|
+
const url2 = stringifyAutomergeUrl({ documentId: goodDocumentId })
|
|
53
|
+
assert.equal(url1, url2)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe("parseAutomergeUrl", () => {
|
|
58
|
+
it("should parse a valid url", () => {
|
|
59
|
+
const { binaryDocumentId, documentId } = parseAutomergeUrl(goodUrl)
|
|
60
|
+
assert.deepEqual(binaryDocumentId, goodBinaryDocumentId)
|
|
61
|
+
assert.equal(documentId, goodDocumentId)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it("should throw on url with invalid checksum", () => {
|
|
65
|
+
assert.throws(() => parseAutomergeUrl(badChecksumUrl))
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it("should throw on url with invalid prefix", () => {
|
|
69
|
+
assert.throws(() => parseAutomergeUrl(badPrefixUrl))
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe("isValidAutomergeUrl", () => {
|
|
74
|
+
it("should return true for a valid url", () => {
|
|
75
|
+
assert(isValidAutomergeUrl(goodUrl) === true)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it("should return false for null url", () => {
|
|
79
|
+
assert(isValidAutomergeUrl(null) === false)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it("should return false for a url with invalid checksum", () => {
|
|
83
|
+
assert(isValidAutomergeUrl(badChecksumUrl) === false)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it("should return false for a url with invalid prefix", () => {
|
|
87
|
+
assert(isValidAutomergeUrl(badPrefixUrl) === false)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it("should return false for a documentId with an invalid checksum", () => {
|
|
91
|
+
const url = stringifyAutomergeUrl({ documentId: badChecksumDocumentId })
|
|
92
|
+
assert(isValidAutomergeUrl(url) === false)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it("should return false for a documentId that is not a valid UUID ", () => {
|
|
96
|
+
const url = stringifyAutomergeUrl({ documentId: badUuidDocumentId })
|
|
97
|
+
assert(isValidAutomergeUrl(url) === false)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
package/test/DocHandle.test.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as A from "@automerge/automerge/next"
|
|
|
2
2
|
import assert from "assert"
|
|
3
3
|
import { decode } from "cbor-x"
|
|
4
4
|
import { describe, it } from "vitest"
|
|
5
|
-
import { generateAutomergeUrl, parseAutomergeUrl } from "../src/
|
|
5
|
+
import { generateAutomergeUrl, parseAutomergeUrl } from "../src/AutomergeUrl.js"
|
|
6
6
|
import { eventPromise } from "../src/helpers/eventPromise.js"
|
|
7
7
|
import { pause } from "../src/helpers/pause.js"
|
|
8
8
|
import { DocHandle, DocHandleChangePayload } from "../src/index.js"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "assert"
|
|
2
2
|
import { describe, it } from "vitest"
|
|
3
3
|
import { DocHandle } from "../src/DocHandle.js"
|
|
4
|
-
import { generateAutomergeUrl, parseAutomergeUrl } from "../src/
|
|
4
|
+
import { generateAutomergeUrl, parseAutomergeUrl } from "../src/AutomergeUrl.js"
|
|
5
5
|
import { eventPromise } from "../src/helpers/eventPromise.js"
|
|
6
6
|
import {
|
|
7
7
|
DocumentUnavailableMessage,
|
package/test/Repo.test.ts
CHANGED
|
@@ -2,9 +2,12 @@ import { MessageChannelNetworkAdapter } from "@automerge/automerge-repo-network-
|
|
|
2
2
|
import assert from "assert"
|
|
3
3
|
import * as Uuid from "uuid"
|
|
4
4
|
import { describe, it } from "vitest"
|
|
5
|
-
import { parseAutomergeUrl } from "../
|
|
5
|
+
import { parseAutomergeUrl } from "../src/AutomergeUrl.js"
|
|
6
6
|
import { READY } from "../src/DocHandle.js"
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
generateAutomergeUrl,
|
|
9
|
+
stringifyAutomergeUrl,
|
|
10
|
+
} from "../src/AutomergeUrl.js"
|
|
8
11
|
import { Repo } from "../src/Repo.js"
|
|
9
12
|
import { eventPromise } from "../src/helpers/eventPromise.js"
|
|
10
13
|
import { pause } from "../src/helpers/pause.js"
|
|
@@ -12,6 +15,7 @@ import {
|
|
|
12
15
|
AutomergeUrl,
|
|
13
16
|
DocHandle,
|
|
14
17
|
DocumentId,
|
|
18
|
+
LegacyDocumentId,
|
|
15
19
|
PeerId,
|
|
16
20
|
SharePolicy,
|
|
17
21
|
} from "../src/index.js"
|
|
@@ -51,7 +55,7 @@ describe("Repo", () => {
|
|
|
51
55
|
assert.equal(handle.isReady(), true)
|
|
52
56
|
})
|
|
53
57
|
|
|
54
|
-
it("can find a document
|
|
58
|
+
it("can find a document by url", () => {
|
|
55
59
|
const { repo } = setup()
|
|
56
60
|
const handle = repo.create<TestDoc>()
|
|
57
61
|
handle.change((d: TestDoc) => {
|
|
@@ -63,7 +67,19 @@ describe("Repo", () => {
|
|
|
63
67
|
assert.deepEqual(handle2.docSync(), { foo: "bar" })
|
|
64
68
|
})
|
|
65
69
|
|
|
66
|
-
it("can find a document
|
|
70
|
+
it("can find a document by its unprefixed document ID", () => {
|
|
71
|
+
const { repo } = setup()
|
|
72
|
+
const handle = repo.create<TestDoc>()
|
|
73
|
+
handle.change((d: TestDoc) => {
|
|
74
|
+
d.foo = "bar"
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const handle2 = repo.find(handle.documentId)
|
|
78
|
+
assert.equal(handle, handle2)
|
|
79
|
+
assert.deepEqual(handle2.docSync(), { foo: "bar" })
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it("can find a document by legacy UUID (for now)", () => {
|
|
67
83
|
disableConsoleWarn()
|
|
68
84
|
|
|
69
85
|
const { repo } = setup()
|
|
@@ -74,9 +90,9 @@ describe("Repo", () => {
|
|
|
74
90
|
|
|
75
91
|
const url = handle.url
|
|
76
92
|
const { binaryDocumentId } = parseAutomergeUrl(url)
|
|
77
|
-
const
|
|
93
|
+
const legacyDocId = Uuid.stringify(binaryDocumentId) as LegacyDocumentId
|
|
78
94
|
|
|
79
|
-
const handle2 = repo.find(
|
|
95
|
+
const handle2 = repo.find(legacyDocId)
|
|
80
96
|
assert.equal(handle, handle2)
|
|
81
97
|
assert.deepEqual(handle2.docSync(), { foo: "bar" })
|
|
82
98
|
|
|
@@ -5,7 +5,7 @@ import fs from "fs"
|
|
|
5
5
|
import os from "os"
|
|
6
6
|
import path from "path"
|
|
7
7
|
import { describe, it } from "vitest"
|
|
8
|
-
import { generateAutomergeUrl, parseAutomergeUrl } from "../src/
|
|
8
|
+
import { generateAutomergeUrl, parseAutomergeUrl } from "../src/AutomergeUrl.js"
|
|
9
9
|
import { StorageSubsystem } from "../src/storage/StorageSubsystem.js"
|
|
10
10
|
import { DummyStorageAdapter } from "./helpers/DummyStorageAdapter.js"
|
|
11
11
|
|
package/dist/DocUrl.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { type AutomergeUrl, type BinaryDocumentId, type DocumentId } from "./types.js";
|
|
2
|
-
export declare const urlPrefix = "automerge:";
|
|
3
|
-
/**
|
|
4
|
-
* given an Automerge URL, return a decoded DocumentId (and the encoded DocumentId)
|
|
5
|
-
*
|
|
6
|
-
* @param url
|
|
7
|
-
* @returns { binaryDocumentId: BinaryDocumentId, documentId: DocumentId }
|
|
8
|
-
*/
|
|
9
|
-
export declare const parseAutomergeUrl: (url: AutomergeUrl) => {
|
|
10
|
-
binaryDocumentId: BinaryDocumentId;
|
|
11
|
-
documentId: DocumentId;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Given a documentId in either canonical form, return an Automerge URL
|
|
15
|
-
* Throws on invalid input.
|
|
16
|
-
* Note: this is an object because we anticipate adding fields in the future.
|
|
17
|
-
* @param { documentId: BinaryDocumentId | DocumentId }
|
|
18
|
-
* @returns AutomergeUrl
|
|
19
|
-
*/
|
|
20
|
-
export declare const stringifyAutomergeUrl: ({ documentId, }: {
|
|
21
|
-
documentId: DocumentId | BinaryDocumentId;
|
|
22
|
-
}) => AutomergeUrl;
|
|
23
|
-
/**
|
|
24
|
-
* Given a string, return true if it is a valid Automerge URL
|
|
25
|
-
* also acts as a type discriminator in Typescript.
|
|
26
|
-
* @param str: URL candidate
|
|
27
|
-
* @returns boolean
|
|
28
|
-
*/
|
|
29
|
-
export declare const isValidAutomergeUrl: (str: string) => str is AutomergeUrl;
|
|
30
|
-
/**
|
|
31
|
-
* generateAutomergeUrl produces a new AutomergeUrl.
|
|
32
|
-
* generally only called by create(), but used in tests as well.
|
|
33
|
-
* @returns a new Automerge URL with a random UUID documentId
|
|
34
|
-
*/
|
|
35
|
-
export declare const generateAutomergeUrl: () => AutomergeUrl;
|
|
36
|
-
export declare const documentIdToBinary: (docId: DocumentId) => BinaryDocumentId | undefined;
|
|
37
|
-
export declare const binaryToDocumentId: (docId: BinaryDocumentId) => DocumentId;
|
|
38
|
-
export declare const parseLegacyUUID: (str: string) => AutomergeUrl | undefined;
|
|
39
|
-
//# sourceMappingURL=DocUrl.d.ts.map
|
package/dist/DocUrl.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DocUrl.d.ts","sourceRoot":"","sources":["../src/DocUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;AAInB,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAS,YAAY;;;CAIlD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;gBAGpB,UAAU,GAAG,gBAAgB;MACvC,YAQH,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,wBAK9C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGpC,CAAA;AAEJ,eAAO,MAAM,kBAAkB,UACtB,UAAU,KAChB,gBAAgB,GAAG,SACyC,CAAA;AAE/D,eAAO,MAAM,kBAAkB,UAAW,gBAAgB,KAAG,UACtB,CAAA;AAEvC,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,YAAY,GAAG,SAM5D,CAAA"}
|
package/dist/DocUrl.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import * as Uuid from "uuid";
|
|
2
|
-
import bs58check from "bs58check";
|
|
3
|
-
export const urlPrefix = "automerge:";
|
|
4
|
-
/**
|
|
5
|
-
* given an Automerge URL, return a decoded DocumentId (and the encoded DocumentId)
|
|
6
|
-
*
|
|
7
|
-
* @param url
|
|
8
|
-
* @returns { binaryDocumentId: BinaryDocumentId, documentId: DocumentId }
|
|
9
|
-
*/
|
|
10
|
-
export const parseAutomergeUrl = (url) => {
|
|
11
|
-
const { binaryDocumentId, documentId } = parts(url);
|
|
12
|
-
if (!binaryDocumentId)
|
|
13
|
-
throw new Error("Invalid document URL: " + url);
|
|
14
|
-
return { binaryDocumentId, documentId };
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Given a documentId in either canonical form, return an Automerge URL
|
|
18
|
-
* Throws on invalid input.
|
|
19
|
-
* Note: this is an object because we anticipate adding fields in the future.
|
|
20
|
-
* @param { documentId: BinaryDocumentId | DocumentId }
|
|
21
|
-
* @returns AutomergeUrl
|
|
22
|
-
*/
|
|
23
|
-
export const stringifyAutomergeUrl = ({ documentId, }) => {
|
|
24
|
-
if (documentId instanceof Uint8Array)
|
|
25
|
-
return (urlPrefix +
|
|
26
|
-
binaryToDocumentId(documentId));
|
|
27
|
-
else if (typeof documentId === "string") {
|
|
28
|
-
return (urlPrefix + documentId);
|
|
29
|
-
}
|
|
30
|
-
throw new Error("Invalid documentId: " + documentId);
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Given a string, return true if it is a valid Automerge URL
|
|
34
|
-
* also acts as a type discriminator in Typescript.
|
|
35
|
-
* @param str: URL candidate
|
|
36
|
-
* @returns boolean
|
|
37
|
-
*/
|
|
38
|
-
export const isValidAutomergeUrl = (str) => {
|
|
39
|
-
if (!str.startsWith(urlPrefix))
|
|
40
|
-
return false;
|
|
41
|
-
const { binaryDocumentId: documentId } = parts(str);
|
|
42
|
-
return documentId ? true : false;
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* generateAutomergeUrl produces a new AutomergeUrl.
|
|
46
|
-
* generally only called by create(), but used in tests as well.
|
|
47
|
-
* @returns a new Automerge URL with a random UUID documentId
|
|
48
|
-
*/
|
|
49
|
-
export const generateAutomergeUrl = () => stringifyAutomergeUrl({
|
|
50
|
-
documentId: Uuid.v4(null, new Uint8Array(16)),
|
|
51
|
-
});
|
|
52
|
-
export const documentIdToBinary = (docId) => bs58check.decodeUnsafe(docId);
|
|
53
|
-
export const binaryToDocumentId = (docId) => bs58check.encode(docId);
|
|
54
|
-
export const parseLegacyUUID = (str) => {
|
|
55
|
-
if (Uuid.validate(str)) {
|
|
56
|
-
const uuid = Uuid.parse(str);
|
|
57
|
-
return stringifyAutomergeUrl({ documentId: uuid });
|
|
58
|
-
}
|
|
59
|
-
return undefined;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* parts breaks up the URL into constituent pieces,
|
|
63
|
-
* eventually this could include things like heads, so we use this structure
|
|
64
|
-
* we return both a binary & string-encoded version of the document ID
|
|
65
|
-
* @param str
|
|
66
|
-
* @returns { binaryDocumentId, documentId }
|
|
67
|
-
*/
|
|
68
|
-
const parts = (str) => {
|
|
69
|
-
const regex = new RegExp(`^${urlPrefix}(\\w+)$`);
|
|
70
|
-
const [_, docMatch] = str.match(regex) || [];
|
|
71
|
-
const documentId = docMatch;
|
|
72
|
-
const binaryDocumentId = documentIdToBinary(documentId);
|
|
73
|
-
return { binaryDocumentId, documentId };
|
|
74
|
-
};
|
package/src/DocUrl.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type AutomergeUrl,
|
|
3
|
-
type BinaryDocumentId,
|
|
4
|
-
type DocumentId,
|
|
5
|
-
} from "./types.js"
|
|
6
|
-
import * as Uuid from "uuid"
|
|
7
|
-
import bs58check from "bs58check"
|
|
8
|
-
|
|
9
|
-
export const urlPrefix = "automerge:"
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* given an Automerge URL, return a decoded DocumentId (and the encoded DocumentId)
|
|
13
|
-
*
|
|
14
|
-
* @param url
|
|
15
|
-
* @returns { binaryDocumentId: BinaryDocumentId, documentId: DocumentId }
|
|
16
|
-
*/
|
|
17
|
-
export const parseAutomergeUrl = (url: AutomergeUrl) => {
|
|
18
|
-
const { binaryDocumentId, documentId } = parts(url)
|
|
19
|
-
if (!binaryDocumentId) throw new Error("Invalid document URL: " + url)
|
|
20
|
-
return { binaryDocumentId, documentId }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Given a documentId in either canonical form, return an Automerge URL
|
|
25
|
-
* Throws on invalid input.
|
|
26
|
-
* Note: this is an object because we anticipate adding fields in the future.
|
|
27
|
-
* @param { documentId: BinaryDocumentId | DocumentId }
|
|
28
|
-
* @returns AutomergeUrl
|
|
29
|
-
*/
|
|
30
|
-
export const stringifyAutomergeUrl = ({
|
|
31
|
-
documentId,
|
|
32
|
-
}: {
|
|
33
|
-
documentId: DocumentId | BinaryDocumentId
|
|
34
|
-
}): AutomergeUrl => {
|
|
35
|
-
if (documentId instanceof Uint8Array)
|
|
36
|
-
return (urlPrefix +
|
|
37
|
-
binaryToDocumentId(documentId as BinaryDocumentId)) as AutomergeUrl
|
|
38
|
-
else if (typeof documentId === "string") {
|
|
39
|
-
return (urlPrefix + documentId) as AutomergeUrl
|
|
40
|
-
}
|
|
41
|
-
throw new Error("Invalid documentId: " + documentId)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Given a string, return true if it is a valid Automerge URL
|
|
46
|
-
* also acts as a type discriminator in Typescript.
|
|
47
|
-
* @param str: URL candidate
|
|
48
|
-
* @returns boolean
|
|
49
|
-
*/
|
|
50
|
-
export const isValidAutomergeUrl = (str: string): str is AutomergeUrl => {
|
|
51
|
-
if (!str.startsWith(urlPrefix)) return false
|
|
52
|
-
|
|
53
|
-
const { binaryDocumentId: documentId } = parts(str)
|
|
54
|
-
return documentId ? true : false
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* generateAutomergeUrl produces a new AutomergeUrl.
|
|
59
|
-
* generally only called by create(), but used in tests as well.
|
|
60
|
-
* @returns a new Automerge URL with a random UUID documentId
|
|
61
|
-
*/
|
|
62
|
-
export const generateAutomergeUrl = (): AutomergeUrl =>
|
|
63
|
-
stringifyAutomergeUrl({
|
|
64
|
-
documentId: Uuid.v4(null, new Uint8Array(16)) as BinaryDocumentId,
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
export const documentIdToBinary = (
|
|
68
|
-
docId: DocumentId
|
|
69
|
-
): BinaryDocumentId | undefined =>
|
|
70
|
-
bs58check.decodeUnsafe(docId) as BinaryDocumentId | undefined
|
|
71
|
-
|
|
72
|
-
export const binaryToDocumentId = (docId: BinaryDocumentId): DocumentId =>
|
|
73
|
-
bs58check.encode(docId) as DocumentId
|
|
74
|
-
|
|
75
|
-
export const parseLegacyUUID = (str: string): AutomergeUrl | undefined => {
|
|
76
|
-
if (Uuid.validate(str)) {
|
|
77
|
-
const uuid = Uuid.parse(str) as BinaryDocumentId
|
|
78
|
-
return stringifyAutomergeUrl({ documentId: uuid })
|
|
79
|
-
}
|
|
80
|
-
return undefined
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* parts breaks up the URL into constituent pieces,
|
|
85
|
-
* eventually this could include things like heads, so we use this structure
|
|
86
|
-
* we return both a binary & string-encoded version of the document ID
|
|
87
|
-
* @param str
|
|
88
|
-
* @returns { binaryDocumentId, documentId }
|
|
89
|
-
*/
|
|
90
|
-
const parts = (str: string) => {
|
|
91
|
-
const regex = new RegExp(`^${urlPrefix}(\\w+)$`)
|
|
92
|
-
const [_, docMatch] = str.match(regex) || []
|
|
93
|
-
const documentId = docMatch as DocumentId
|
|
94
|
-
const binaryDocumentId = documentIdToBinary(documentId)
|
|
95
|
-
return { binaryDocumentId, documentId }
|
|
96
|
-
}
|