Skip to content

Commit 527283e

Browse files
Merge branch 'listen-service' into listen-service-robin
2 parents 892fab3 + 56899a0 commit 527283e

2 files changed

Lines changed: 72 additions & 3 deletions

File tree

packages/feathers-automerge-server/src/sync-service.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ export class AutomergeSyncService {
227227
const { getDocumentsForData } = this.options
228228
const documents = this.rootDocument.doc().documents
229229
const service = this.app.service(servicePath)
230+
const serviceOptions = feathers.getServiceOptions(service) as AdapterServiceOptions
230231
const syncDocuments = await getDocumentsForData(servicePath, data, documents)
231232
// Skip when there's no target automerge documents to update
232233
if (syncDocuments.length === 0) {
@@ -253,8 +254,10 @@ export class AutomergeSyncService {
253254
handle.change((doc: any) => {
254255
const changeId: string = _.get(doc, [servicePath, id, CHANGE_ID])
255256

256-
if (!doc[servicePath]) {
257-
// doc.__meta[servicePath] = { idField: idField, paginate: { default: 10, max: 50 } }
257+
if (shouldContain && !doc[servicePath]) {
258+
const paginate = serviceOptions?.paginate ||
259+
(service as any).options?.paginate || { default: 10, max: 10 }
260+
doc.__meta[servicePath] = { idField: idField, paginate }
258261
doc[servicePath] = {}
259262
}
260263

@@ -369,6 +372,10 @@ export class AutomergeSyncService {
369372

370373
patches.forEach((patch) => {
371374
const [path, id] = patch.path
375+
// Skip patches touching the __meta root object
376+
if (path === '__meta') {
377+
return
378+
}
372379
// id may be undefined when path has just been added as a newly listened service
373380
if (id) {
374381
serviceChanges[path] = serviceChanges[path] || new Set()

packages/feathers-automerge-server/test/index.test.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export function createApp(options: Partial<SyncOptions>) {
6969
})
7070
}
7171

72-
if (servicePath === 'messages') {
72+
// This will collect data from every service including 'messages' in it's path
73+
if (servicePath.includes('messages')) {
7374
return documents.filter((doc) => {
7475
return !doc.query.username || (data as Message).username === doc.query.username
7576
})
@@ -762,4 +763,65 @@ describe('@kalisio/feathers-automerge-server', () => {
762763
expect(validateSyncServerOptions(fullOptions)).toBe(true)
763764
})
764765
})
766+
767+
describe('listen to dynamically created services feature', () => {
768+
let dynamicApp: Application<{
769+
todos: MemoryService<Todo>
770+
messages: MemoryService<Message>
771+
automerge: AutomergeSyncService
772+
}>
773+
let fooMessagesDoc: DocHandle<unknown>
774+
775+
beforeAll(async () => {
776+
dynamicApp = createApp({
777+
directory,
778+
serverId: 'dynamic-server',
779+
async authenticate() {
780+
return true
781+
},
782+
async canAccess(query, params) {
783+
return true
784+
}
785+
})
786+
787+
await dynamicApp.listen(9191)
788+
})
789+
790+
it('initializes an app', async () => {
791+
// Create an automerge document to gather all objects in all *messages* services
792+
// By default app has a single 'messages' service and will collect events
793+
// from services whose path includes 'messages', cf. createApp > getDocumentsForData
794+
const fooMessagesInfos = await dynamicApp.service('automerge').create({
795+
query: {
796+
username: 'foo'
797+
}
798+
})
799+
fooMessagesDoc = await dynamicApp.service('automerge').repo.find(fooMessagesInfos.url as AnyDocumentId)
800+
801+
// Create a message for foo and make sure it exists in the underlying automerge doc
802+
const msg1 = await dynamicApp.service('messages').create({
803+
text: 'How are you ?',
804+
username: 'foo'
805+
})
806+
expect(fooMessagesDoc.doc().messages[msg1.id]).toBeDefined()
807+
expect(fooMessagesDoc.doc().messages[msg1.id].username).toBe('foo')
808+
expect(fooMessagesDoc.doc().messages[msg1.id].text).toBe('How are you ?')
809+
})
810+
811+
it('creates a new service to publish important messages', async () => {
812+
// Create a new service for important-messages and make the automerge service aware of this one
813+
const servicePath = 'important-messages'
814+
dynamicApp.use(servicePath, new MemoryService())
815+
dynamicApp.service('automerge').listenService(servicePath)
816+
817+
// Publish an important message and make sure it also exists in the automerge doc
818+
const msg2 = await dynamicApp.service('important-messages').create({
819+
text: 'We need you !',
820+
username: 'foo'
821+
})
822+
expect(fooMessagesDoc.doc()[servicePath][msg2.id]).toBeDefined()
823+
expect(fooMessagesDoc.doc()[servicePath][msg2.id].username).toBe('foo')
824+
expect(fooMessagesDoc.doc()[servicePath][msg2.id].text).toBe('We need you !')
825+
})
826+
})
765827
})

0 commit comments

Comments
 (0)