Skip to content

Commit 34dbc9a

Browse files
committed
chore(logging): some optional debug logging
yjs and editor update logging can be very verbose. Uncomment it but keep it disabled by default. Can be enabled by setting the corresponding key in OCA.Text - i.e. `window.OCA.Text.logWebSocketPolyfill = true` in the browser console. Signed-off-by: Max <[email protected]>
1 parent 7b9e343 commit 34dbc9a

File tree

5 files changed

+59
-21
lines changed

5 files changed

+59
-21
lines changed

src/components/Editor.vue

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,13 @@ export default defineComponent({
410410
if (!val) {
411411
return
412412
}
413-
console.debug('Document is outdated')
413+
logger.debug('Document is outdated')
414414
if (this.dirty) {
415-
console.debug('There are local edits, need to resolve conflict')
415+
logger.debug('There are local edits, need to resolve conflict')
416416
// handle conflict between active editing session and offline content
417417
} else {
418418
// clear the outdated cached content and reload without it.
419-
console.debug(
419+
logger.debug(
420420
'No local edits... clearing storage and reloading the editor',
421421
)
422422
this.clearIndexedDb().then(() => {
@@ -442,8 +442,16 @@ export default defineComponent({
442442
created() {
443443
// The following can be useful for debugging ydoc updates
444444
this.ydoc.on('update', function (update, origin, doc, tr) {
445-
console.debug('ydoc update', update, origin, doc, tr)
446-
logUpdate(update)
445+
if (window.OCA.Text.logYjsUpdates) {
446+
logger.debug('ydoc update', {
447+
update,
448+
origin,
449+
doc,
450+
tr,
451+
content: doc.getXmlFragment('default').toJSON(),
452+
})
453+
logUpdate(update)
454+
}
447455
})
448456
this.$attachmentResolver = null
449457
if (this.active && this.hasDocumentParameters) {
@@ -452,6 +460,7 @@ export default defineComponent({
452460
}
453461
},
454462
async beforeDestroy() {
463+
logger.debug('beforeDestroy')
455464
if (!this.richWorkspace) {
456465
window.removeEventListener('beforeprint', this.preparePrinting)
457466
window.removeEventListener('afterprint', this.preparePrinting)
@@ -556,6 +565,10 @@ export default defineComponent({
556565
this.lowlightLoaded.then(() => {
557566
this.syncService.startSync()
558567
if (!documentState) {
568+
logger.debug('loading initial content', {
569+
content,
570+
isRichEditor: this.isRichEditor,
571+
})
559572
setInitialYjsState(this.ydoc, content, {
560573
isRichEditor: this.isRichEditor,
561574
})
@@ -579,7 +592,9 @@ export default defineComponent({
579592
},
580593
581594
onUpdate({ editor }) {
582-
// this.debugContent(editor)
595+
if (window.OCA.Text.logEditorUpdates) {
596+
this.debugContent(editor)
597+
}
583598
const proseMirrorMarkdown = this.serialize()
584599
this.emit('update:content', {
585600
markdown: proseMirrorMarkdown,
@@ -651,7 +666,6 @@ export default defineComponent({
651666
if (Object.prototype.hasOwnProperty.call(state, 'dirty')) {
652667
// ignore initial loading and other automated changes before first user change
653668
if (this.editor.can().undo() || this.editor.can().redo()) {
654-
console.debug('Setting dirty to', state.dirty)
655669
this.setDirty(state.dirty)
656670
if (this.dirty) {
657671
this.saveService.autosave()
@@ -707,6 +721,7 @@ export default defineComponent({
707721
},
708722
709723
async disconnect() {
724+
logger.debug('disconnecting')
710725
await this.syncService.close()
711726
this.unlistenSyncServiceEvents()
712727
this.syncProvider?.destroy()
@@ -715,11 +730,13 @@ export default defineComponent({
715730
},
716731
717732
async close() {
733+
logger.debug('closing')
718734
await this.syncService
719735
.sendRemainingSteps()
720736
.catch((err) =>
721737
logger.warn('Failed to send remaining steps', { err }),
722738
)
739+
logger.debug('sent remaining steps')
723740
await this.disconnect().catch((err) =>
724741
logger.warn('Failed to disconnect', { err }),
725742
)
@@ -767,17 +784,18 @@ export default defineComponent({
767784
* @param {object} editor The Tiptap editor
768785
*/
769786
debugContent(editor) {
787+
// markdown, serialized from editor state by prosemirror-markdown
770788
const proseMirrorMarkdown = this.serialize()
789+
// HTML, serialized from markdown by markdown-it
771790
const markdownItHtml = markdownit.render(proseMirrorMarkdown)
791+
// HTML, as rendered in the browser by Tiptap
792+
const tiptapHtml = editor.getHTML()
772793
773-
logger.debug(
774-
'markdown, serialized from editor state by prosemirror-markdown',
775-
)
776-
console.debug(proseMirrorMarkdown)
777-
logger.debug('HTML, serialized from markdown by markdown-it')
778-
console.debug(markdownItHtml)
779-
logger.debug('HTML, as rendered in the browser by Tiptap')
780-
console.debug(editor.getHTML())
794+
logger.debug('editor update', {
795+
proseMirrorMarkdown,
796+
markdownItHtml,
797+
tiptapHtml,
798+
})
781799
},
782800
783801
/**

src/composables/useIndexedDbProvider.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { readonly, ref } from 'vue'
77
import { IndexeddbPersistence } from 'y-indexeddb'
88
import type { Doc } from 'yjs'
9+
import { logger } from '../helpers/logger.js'
910

1011
/**
1112
* Initialize a indexed db provider for the given ydoc
@@ -21,8 +22,11 @@ export function useIndexedDbProvider(
2122
) {
2223
const name = `${props.fileId}`
2324
const indexedDbProvider = new IndexeddbPersistence(name, ydoc)
24-
indexedDbProvider.on('synced', (provider: IndexeddbPersistence) => {
25-
console.info('synced from indexeddb', provider)
25+
indexedDbProvider.on('synced', async (provider: IndexeddbPersistence) => {
26+
logger.info('synced from indexeddb', {
27+
dirty: await provider.get('dirty'),
28+
baseVersionEtag: await provider.get('baseVersionEtag'),
29+
})
2630
})
2731
const dirty = ref(false)
2832
indexedDbProvider.get('dirty').then((val) => {
@@ -58,6 +62,7 @@ export function useIndexedDbProvider(
5862
* Used to reset the browser state to load a new editing session.
5963
*/
6064
function clearIndexedDb() {
65+
logger.info('clearing indexeddb')
6166
return indexedDbProvider.clearData()
6267
}
6368

src/helpers/debug.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ if (!window.OCA.Text) {
1111
window.OCA.Text = {}
1212
}
1313

14+
// These can be changed in the browser console for more verbose logging.
15+
window.OCA.Text.logEditorUpdates = false
16+
window.OCA.Text.logWebSocketPolyfill = false
17+
window.OCA.Text.logYjsUpdates = false
18+
1419
const editorComponents = window.OCA.Text.editorComponents ?? new Set()
1520
window.OCA.Text.editorComponents = editorComponents
1621

File renamed without changes.

src/services/WebSocketPolyfill.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ import { stepsFromOpenData } from '../helpers/yjs'
1010
import getNotifyBus from './NotifyService'
1111
import type { Step, SyncService } from './SyncService'
1212

13+
// Optional debug logging if window.OCA.Text.logWebSocketPolyfill is set.
14+
const debug = (message: string, context: object) => {
15+
if (window.OCA?.Text?.logWebSocketPolyfill) {
16+
debug(message, context)
17+
}
18+
}
19+
1320
/**
1421
*
1522
* @param syncService - the sync service to build upon
@@ -35,9 +42,10 @@ export default function initWebSocketPolyfill(
3542
this.#notifyPushBus = getNotifyBus()
3643
this.#notifyPushBus?.on('notify_push', this.#onNotifyPush.bind(this))
3744
this.#url = url
38-
logger.debug('WebSocketPolyfill#constructor', { url, fileId })
45+
debug('WebSocketPolyfill#constructor', { url, fileId })
3946

4047
this.#onOpened = (data: OpenData) => {
48+
debug('WebSocketPolyfill#onOpen', { data })
4149
if (syncService.hasActiveConnection()) {
4250
this.onopen?.()
4351
}
@@ -46,9 +54,10 @@ export default function initWebSocketPolyfill(
4654
syncService.bus.on('opened', this.#onOpened)
4755

4856
this.#onSync = ({ steps }: { steps: Step[] }) => {
57+
debug('WebSocketPolyfill#onSync', { steps })
4958
if (steps) {
5059
this.#processSteps(steps)
51-
logger.debug('synced ', {
60+
debug('synced ', {
5261
version: syncService.version,
5362
steps,
5463
})
@@ -95,7 +104,7 @@ export default function initWebSocketPolyfill(
95104
// If `this.#processingVersion` is set, we're in the middle of applying steps of one version.
96105
// If `isSyncStep1`, Yjs failed to integrate a message due to pending structs.
97106
// Log and ask for recovery due to a not applied/missing step.
98-
console.error(`Failed to process step ${this.#processingVersion}.`, {
107+
logger.error(`Failed to process step ${this.#processingVersion}.`, {
99108
lastSuccessfullyProcessed: syncService.version,
100109
sendingSyncStep1: step,
101110
})
@@ -110,14 +119,15 @@ export default function initWebSocketPolyfill(
110119
syncService.bus.off('opened', this.#onOpened)
111120
this.#notifyPushBus?.off('notify_push', this.#onNotifyPush.bind(this))
112121
this.onclose?.(new CloseEvent('closing'))
113-
logger.debug('Websocket closed')
122+
debug('Websocket closed')
114123
}
115124

116125
#onNotifyPush({
117126
messageBody,
118127
}: {
119128
messageBody: { documentId: number; steps: string[] }
120129
}) {
130+
debug('WebSocketPolyfill#onNotifyPush', messageBody)
121131
if (messageBody.documentId !== fileId) {
122132
return
123133
}

0 commit comments

Comments
 (0)