Skip to content

Commit

Permalink
Replace setGlobalMetadata with changeMetadata function
Browse files Browse the repository at this point in the history
  • Loading branch information
paulsonnentag committed Jan 12, 2024
1 parent 9d21e1b commit c5d41a0
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 26 deletions.
27 changes: 16 additions & 11 deletions packages/automerge-repo/src/DocHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ export class DocHandle<T> //
#machine: DocHandleXstateMachine<T>
#timeoutDelay: number
#remoteHeads: Record<StorageId, A.Heads> = {}

// Reference to global meta data that is set on the repo to be attached to each change
#globalMetadataRef?: ChangeMetadataRef
#changeMetadata: ChangeMetadataFunction

/** The URL of this document
*
Expand All @@ -60,12 +58,12 @@ export class DocHandle<T> //
{
isNew = false,
timeoutDelay = 60_000,
globalMetadataRef,
changeMetadata = () => undefined,
}: DocHandleOptions = {}
) {
super()
this.#timeoutDelay = timeoutDelay
this.#globalMetadataRef = globalMetadataRef
this.#changeMetadata = changeMetadata
this.#log = debug(`automerge-repo:dochandle:${this.documentId.slice(0, 5)}`)

// initial doc
Expand Down Expand Up @@ -364,7 +362,7 @@ export class DocHandle<T> //
doc,
optionsWithGlobalMetadata(
options,
this.#globalMetadataRef?.current ?? {}
this.#changeMetadata(this.documentId) ?? {}
),
callback
)
Expand Down Expand Up @@ -396,7 +394,7 @@ export class DocHandle<T> //
heads,
optionsWithGlobalMetadata(
options,
this.#globalMetadataRef?.current ?? {}
this.#changeMetadata(this.documentId) ?? {}
),
callback
)
Expand Down Expand Up @@ -502,7 +500,7 @@ function optionsWithGlobalMetadata<T>(
export interface DocHandleOptions {
isNew?: boolean
timeoutDelay?: number
globalMetadataRef?: ChangeMetadataRef
changeMetadata?: ChangeMetadataFunction
}

// todo: remove this type once we have real metadata on changes in automerge
Expand All @@ -514,9 +512,16 @@ export interface DocHandleChangeOptions<T> {
}

export type ChangeMetadata = Record<string, number | string | boolean>
export interface ChangeMetadataRef {
current: ChangeMetadata
}

/** A function that defines default meta data for each change on the handle
*
* @remarks
* This function can be defined globally on the {@link Repo} and is passed down to all {@link DocHandle}.
* The metadata can be override by explicitly passing metadata in {@link DocHandle.change} or {@link DocHandle.changeAt}.
* */
export type ChangeMetadataFunction = (
documentId: DocumentId
) => ChangeMetadata | undefined

export interface DocHandleMessagePayload {
destinationId: PeerId
Expand Down
19 changes: 11 additions & 8 deletions packages/automerge-repo/src/Repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
DocHandle,
DocHandleEncodedChangePayload,
ChangeMetadata,
ChangeMetadataRef,
ChangeMetadataFunction,
} from "./DocHandle.js"
import { RemoteHeadsSubscriptions } from "./RemoteHeadsSubscriptions.js"
import { headsAreSame } from "./helpers/headsAreSame.js"
Expand Down Expand Up @@ -60,7 +60,7 @@ export class Repo extends EventEmitter<RepoEvents> {
#remoteHeadsSubscriptions = new RemoteHeadsSubscriptions()
#remoteHeadsGossipingEnabled = false

#globalMetadataRef: ChangeMetadataRef = { current: {} }
#changeMetadata: ChangeMetadataFunction

constructor({
storage,
Expand All @@ -69,11 +69,13 @@ export class Repo extends EventEmitter<RepoEvents> {
sharePolicy,
isEphemeral = storage === undefined,
enableRemoteHeadsGossiping = false,
changeMetadata = () => undefined,
}: RepoConfig) {
super()
this.#remoteHeadsGossipingEnabled = enableRemoteHeadsGossiping
this.#log = debug(`automerge-repo:repo`)
this.sharePolicy = sharePolicy ?? this.sharePolicy
this.#changeMetadata = changeMetadata

// DOC COLLECTION

Expand Down Expand Up @@ -340,7 +342,7 @@ export class Repo extends EventEmitter<RepoEvents> {
if (!documentId) throw new Error(`Invalid documentId ${documentId}`)
const handle = new DocHandle<T>(documentId, {
isNew,
globalMetadataRef: this.#globalMetadataRef,
changeMetadata: this.#changeMetadata,
})
this.#handleCache[documentId] = handle
return handle
Expand All @@ -356,11 +358,6 @@ export class Repo extends EventEmitter<RepoEvents> {
return this.#synchronizer.peers
}

/** Set meta data that will be attached to each change that is created through a handle from this repo */
setGlobalMetadata(metadata: ChangeMetadata) {
this.#globalMetadataRef.current = metadata
}

getStorageIdOfPeer(peerId: PeerId): StorageId | undefined {
return this.peerMetadataByPeerId[peerId]?.storageId
}
Expand Down Expand Up @@ -547,6 +544,12 @@ export interface RepoConfig {
*/
sharePolicy?: SharePolicy

/**
* Define default meta data that is added to each change made through the repo.
* This function is called inside of {@link DocHandle} on each change.
*/
changeMetadata?: ChangeMetadataFunction

/**
* Whether to enable the experimental remote heads gossiping feature
*/
Expand Down
24 changes: 21 additions & 3 deletions packages/automerge-repo/test/DocHandle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,13 @@ describe("DocHandle", () => {
it("should allow to pass in a reference to global metadata", () => {
const handle = new DocHandle<TestDoc>(TEST_ID, {
isNew: true,
globalMetadataRef: { current: { author: "bob" } },
changeMetadata: documentId => {
assert.equal(documentId, handle.documentId)

return {
author: "bob",
}
},
})

const doc1 = handle.docSync()
Expand All @@ -333,7 +339,13 @@ describe("DocHandle", () => {
it("should allow to add additional local metadata with", () => {
const handle = new DocHandle<TestDoc>(TEST_ID, {
isNew: true,
globalMetadataRef: { current: { author: "bob" } },
changeMetadata: documentId => {
assert.equal(documentId, handle.documentId)

return {
author: "bob",
}
},
})

const doc1 = handle.docSync()
Expand Down Expand Up @@ -372,7 +384,13 @@ describe("DocHandle", () => {
it("should allow to override global data with change", () => {
const handle = new DocHandle<TestDoc>(TEST_ID, {
isNew: true,
globalMetadataRef: { current: { author: "bob" } },
changeMetadata: documentId => {
assert.equal(documentId, handle.documentId)

return {
author: "bob",
}
},
})

const doc1 = handle.docSync()
Expand Down
21 changes: 17 additions & 4 deletions packages/automerge-repo/test/Repo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
import { getRandomItem } from "./helpers/getRandomItem.js"
import { TestDoc } from "./types.js"
import { StorageId } from "../src/storage/types.js"
import { ChangeMetadataFunction } from "../src/DocHandle.js"

describe("Repo", () => {
describe("constructor", () => {
Expand All @@ -43,13 +44,20 @@ describe("Repo", () => {
})

describe("local only", () => {
const setup = ({ startReady = true } = {}) => {
const setup = ({
startReady = true,
changeMetadata,
}: {
startReady?: boolean
changeMetadata?: ChangeMetadataFunction
} = {}) => {
const storageAdapter = new DummyStorageAdapter()
const networkAdapter = new DummyNetworkAdapter({ startReady })

const repo = new Repo({
storage: storageAdapter,
network: [networkAdapter],
changeMetadata,
})
return { repo, storageAdapter, networkAdapter }
}
Expand Down Expand Up @@ -453,14 +461,19 @@ describe("Repo", () => {
}).toThrow()
})

it("can set global change metadata", () => {
const { repo } = setup()
it("can set change metadata function", () => {
const { repo } = setup({
changeMetadata: documentId => {
assert.equal(documentId, handle.documentId)

return { author: "bob" }
},
})

const handle = repo.create<TestDoc>()

const doc1 = handle.docSync()

repo.setGlobalMetadata({ author: "bob" })
handle.change(doc => {
doc.foo = "bar"
})
Expand Down

0 comments on commit c5d41a0

Please sign in to comment.