diff --git a/package-lock.json b/package-lock.json index a03901f7f..f30a28fdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8826,9 +8826,9 @@ } }, "semver": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz", - "integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==" + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==" }, "semver-compare": { "version": "1.0.0", diff --git a/package.json b/package.json index f77e1a533..5a3ad5277 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "rimraf": "3.0.2", "sanitize-filename": "1.6.3", "sax": "1.2.4", - "semver": "7.1.2", + "semver": "7.1.3", "serve-favicon": "2.5.0", "session-file-store": "1.4.0", "simple-node-logger": "18.12.24", diff --git a/src/public/javascripts/services/mutex.js b/src/public/javascripts/services/mutex.js new file mode 100644 index 000000000..d74b03b1f --- /dev/null +++ b/src/public/javascripts/services/mutex.js @@ -0,0 +1,29 @@ +export default class Mutex { + constructor() { + this.queue = []; + this.pending = false; + } + + isLocked() { + return this.pending; + } + + acquire() { + const ticket = new Promise(resolve => this.queue.push(resolve)); + + if (!this.pending) { + this.dispatchNext(); + } + + return ticket; + } + + dispatchNext() { + if (this.queue.length > 0) { + this.pending = true; + this.queue.shift()(this.dispatchNext.bind(this)); + } else { + this.pending = false; + } + } +} \ No newline at end of file diff --git a/src/public/javascripts/widgets/component.js b/src/public/javascripts/widgets/component.js index 0fa44bbe0..dc10ddb07 100644 --- a/src/public/javascripts/widgets/component.js +++ b/src/public/javascripts/widgets/component.js @@ -1,4 +1,5 @@ import utils from '../services/utils.js'; +import Mutex from "../services/mutex.js"; export default class Component { /** @param {AppContext} appContext */ @@ -11,6 +12,7 @@ export default class Component { /** @type Component[] */ this.children = []; this.initialized = Promise.resolve(); + this.mutex = new Mutex(); } async eventReceived(name, data, sync = false) { @@ -23,7 +25,18 @@ export default class Component { const start = Date.now(); if (typeof fun === 'function') { - propagateToChildren = await fun.call(this, data) !== false; + let release; + + try { + release = await this.mutex.acquire(); + + propagateToChildren = await fun.call(this, data) !== false; + } + finally { + if (release) { + release(); + } + } } const end = Date.now(); @@ -46,12 +59,14 @@ export default class Component { } async triggerChildren(name, data, sync = false) { - for (const child of this.children) { - let promise = child.eventReceived(name, data, sync); + const promises = []; - if (sync) { - await promise; - } + for (const child of this.children) { + promises.push(child.eventReceived(name, data, sync)); + } + + if (sync) { + await Promise.all(promises); } } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/note_tree.js b/src/public/javascripts/widgets/note_tree.js index bbfc42b49..d2bc27d36 100644 --- a/src/public/javascripts/widgets/note_tree.js +++ b/src/public/javascripts/widgets/note_tree.js @@ -372,7 +372,7 @@ export default class NoteTreeWidget extends TabAwareWidget { } async updateNode(node) { - const note = await treeCache.getNote(node.data.noteId); + const note = treeCache.getNoteFromCache(node.data.noteId); const branch = treeCache.getBranch(node.data.branchId); node.data.isProtected = note.isProtected;