diff --git a/packages/automerge-repo/src/Repo.ts b/packages/automerge-repo/src/Repo.ts index 09342f09..bf12445b 100644 --- a/packages/automerge-repo/src/Repo.ts +++ b/packages/automerge-repo/src/Repo.ts @@ -340,12 +340,14 @@ export class Repo extends EventEmitter { /** * Creates a new document and returns a handle to it. The initial value of the document is an - * empty object `{}` unless an initial value is provided. Its documentId is generated by the - * system. we emit a `document` event to advertise interest in the document. + * empty object `{}` unless an initial value is provided. If an id is not provided, the system + * will generate a unique id. We emit a `document` event to advertise interest in the document. + * + * The `id` parameter should be sufficiently random or unique to avoid conflicts with existing documents. + * Alternatively, it can match an existing id, but the initial value must share ancestry with that document. */ - create(initialValue?: T): DocHandle { - // Generate a new UUID and store it in the buffer - const { documentId } = parseAutomergeUrl(generateAutomergeUrl()) + create(initialValue?: T, id: AnyDocumentId = generateAutomergeUrl()): DocHandle { + const documentId = interpretAsDocumentId(id) const handle = this.#getHandle({ documentId, }) as DocHandle diff --git a/packages/automerge-repo/test/Repo.test.ts b/packages/automerge-repo/test/Repo.test.ts index f2d12f3e..7d6e4f7b 100644 --- a/packages/automerge-repo/test/Repo.test.ts +++ b/packages/automerge-repo/test/Repo.test.ts @@ -3,7 +3,7 @@ import { MessageChannelNetworkAdapter } from "../../automerge-repo-network-messa import assert from "assert" import * as Uuid from "uuid" import { describe, expect, it } from "vitest" -import { parseAutomergeUrl } from "../src/AutomergeUrl.js" +import { interpretAsDocumentId, parseAutomergeUrl } from "../src/AutomergeUrl.js" import { generateAutomergeUrl, stringifyAutomergeUrl, @@ -76,6 +76,26 @@ describe("Repo", () => { assert.equal(handle.docSync().foo, "bar") }) + it("can create a document with an initial id", async () => { + const { repo } = setup() + const docId = interpretAsDocumentId(Uuid.v4() as LegacyDocumentId) + const docUrl = stringifyAutomergeUrl(docId) + const handle = repo.create({ foo: "bar" }, docId); + await handle.doc() + assert.equal(handle.documentId, docId) + assert.equal(handle.url, docUrl) + }) + + it("throws an error if we try to create a handle with an invalid id", async () => { + const { repo } = setup() + const docId = "invalid-url" as unknown as AutomergeUrl + try { + repo.create({ foo: "bar" }, docId); + } catch (e: any) { + assert.equal(e.message, "Invalid AutomergeUrl: 'invalid-url'") + } + }) + it("can find a document by url", () => { const { repo } = setup() const handle = repo.create()