Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor: hide connection in sync service
Signed-off-by: Max <[email protected]>
  • Loading branch information
max-nextcloud committed Jul 2, 2024
commit a4ea9fcb5c780bb98b635cb9569231424cdb55c2
13 changes: 5 additions & 8 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -664,14 +664,11 @@ export default {

async close() {
if (this.currentSession && this.$syncService) {
try {
await this.$syncService.close()
this.unlistenSyncServiceEvents()
this.currentSession = null
this.$syncService = null
} catch (e) {
// Ignore issues closing the session since those might happen due to network issues
}
await this.$syncService.close()
this.unlistenSyncServiceEvents()
this.$syncService = null
// disallow editing while still showing the content
this.readOnly = true
}
if (this.$editor) {
try {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Editor/GuestNameDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ export default {
},
},
beforeMount() {
this.guestName = this.$syncService.connection.session.guestName
this.guestName = this.$syncService.guestName
this.updateBufferedGuestName()
},
methods: {
setGuestName() {
const previousGuestName = this.$syncService.connection.session.guestName
const previousGuestName = this.$syncService.guestName
this.$syncService.updateSession(this.guestName).then(() => {
localStorage.setItem('nick', this.guestName)
this.updateBufferedGuestName()
Expand Down
2 changes: 1 addition & 1 deletion src/services/PollingBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class PollingBackend {
}
const disconnect = Date.now() - COLLABORATOR_DISCONNECT_TIME
const alive = sessions.filter((s) => s.lastContact * 1000 > disconnect)
if (this.#syncService.connection.state.document.readOnly) {
if (this.#syncService.isReadOnly) {
this.maximumReadOnlyTimer()
} else if (alive.length < 2) {
this.maximumRefetchTimer()
Expand Down
4 changes: 4 additions & 0 deletions src/services/SessionApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ export class Connection {
}
}

get isClosed() {
return this.closed
}

get #defaultParams() {
return {
documentId: this.#document.id,
Expand Down
60 changes: 34 additions & 26 deletions src/services/SyncService.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const ERROR_TYPE = {
class SyncService {

#sendIntervalId
#connection

constructor({ baseVersionEtag, serialize, getDocumentState, ...options }) {
/** @type {import('mitt').Emitter<import('./SyncService').EventTypes>} _bus */
Expand All @@ -60,7 +61,7 @@ class SyncService {
this.serialize = serialize
this.getDocumentState = getDocumentState
this._api = new SessionApi(options)
this.connection = null
this.#connection = null

this.stepClientIDs = []

Expand All @@ -76,27 +77,35 @@ class SyncService {
return this
}

get isReadOnly() {
return this.#connection.state.document.readOnly
}

get guestName() {
return this.#connection.session.guestName
}

async open({ fileId, initialSession }) {

const connect = initialSession
? Promise.resolve(new Connection({ data: initialSession }, {}))
: this._api.open({ fileId, baseVersionEtag: this.baseVersionEtag })
.catch(error => this._emitError(error))

this.connection = await connect
if (!this.connection) {
this.#connection = await connect
if (!this.#connection) {
// Error was already emitted in connect
return
}
this.backend = new PollingBackend(this, this.connection)
this.version = this.connection.docStateVersion
this.baseVersionEtag = this.connection.document.baseVersionEtag
this.backend = new PollingBackend(this, this.#connection)
this.version = this.#connection.docStateVersion
this.baseVersionEtag = this.#connection.document.baseVersionEtag
this.emit('opened', {
...this.connection.state,
...this.#connection.state,
version: this.version,
})
this.emit('loaded', {
...this.connection.state,
...this.#connection.state,
version: this.version,
})
}
Expand All @@ -118,10 +127,10 @@ class SyncService {
}

updateSession(guestName) {
if (!this.connection.isPublic) {
if (!this.#connection.isPublic) {
return Promise.reject(new Error())
}
return this.connection.update(guestName)
return this.#connection.update(guestName)
.catch((error) => {
logger.error('Failed to update the session', { error })
return Promise.reject(error)
Expand All @@ -135,7 +144,7 @@ class SyncService {
}
return new Promise((resolve, reject) => {
this.#sendIntervalId = setInterval(() => {
if (this.connection && !this.sending) {
if (this.#connection && !this.sending) {
this.sendStepsNow(getSendable).then(resolve).catch(reject)
}
}, 200)
Expand All @@ -150,12 +159,12 @@ class SyncService {
if (data.steps.length > 0) {
this.emit('stateChange', { dirty: true })
}
return this.connection.push(data)
return this.#connection.push(data)
.then((response) => {
this.sending = false
this.emit('sync', {
steps: [],
document: this.connection.document,
document: this.#connection.document,
version: this.version,
})
}).catch(err => {
Expand Down Expand Up @@ -210,7 +219,7 @@ class SyncService {
this.emit('sync', {
steps: newSteps,
// TODO: do we actually need to dig into the connection here?
document: this.connection.document,
document: this.#connection.document,
version: this.version,
})
}
Expand All @@ -232,15 +241,15 @@ class SyncService {
async save({ force = false, manualSave = true } = {}) {
logger.debug('[SyncService] saving', arguments[0])
try {
const response = await this.connection.save({
const response = await this.#connection.save({
version: this.version,
autosaveContent: this._getContent(),
documentState: this.getDocumentState(),
force,
manualSave,
})
this.emit('stateChange', { dirty: false })
this.connection.document.lastSavedVersionTime = Date.now() / 1000
this.#connection.document.lastSavedVersionTime = Date.now() / 1000
logger.debug('[SyncService] saved', response)
const { document, sessions } = response.data
this.emit('save', { document, sessions })
Expand All @@ -265,23 +274,22 @@ class SyncService {
// Make sure to leave no pending requests behind.
this.autosave.clear()
this.backend?.disconnect()
return this._close()
}

_close() {
if (this.connection === null) {
return Promise.resolve()
if (!this.#connection || this.#connection.isClosed) {
return
}
this.backend.disconnect()
return this.connection.close()
return this.#connection.close()
// Log and ignore possible network issues.
.catch(e => {
logger.info('Failed to close connection.', { e })
})
}

uploadAttachment(file) {
return this.connection.uploadAttachment(file)
return this.#connection.uploadAttachment(file)
}

insertAttachmentFile(filePath) {
return this.connection.insertAttachmentFile(filePath)
return this.#connection.insertAttachmentFile(filePath)
}

on(event, callback) {
Expand Down