mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-03-14 06:30:35 +00:00
69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
nopaque.app.extensions.UserHub = class UserHub extends EventTarget {
|
|
#data;
|
|
|
|
constructor(app) {
|
|
super();
|
|
|
|
this.app = app;
|
|
|
|
this.#data = {
|
|
users: {},
|
|
promises: {}
|
|
};
|
|
}
|
|
|
|
init() {
|
|
this.app.socket.on('PATCH', (patch) => {this.#onPatch(patch)});
|
|
}
|
|
|
|
add(userId) {
|
|
if (!(userId in this.#data.promises)) {
|
|
this.#data.promises[userId] = this.#add(userId);
|
|
}
|
|
|
|
return this.#data.promises[userId];
|
|
}
|
|
|
|
async #add(userId) {
|
|
await this.app.users.subscribe(userId);
|
|
this.#data.users[userId] = await this.app.users.get(userId);
|
|
}
|
|
|
|
async get(userId) {
|
|
await this.add(userId);
|
|
return this.#data.users[userId];
|
|
}
|
|
|
|
#onPatch(patch) {
|
|
// Filter patch to only include operations on users that are initialized
|
|
const filterRegExp = new RegExp(`^/users/(${Object.keys(this.#data.users).join('|')})`);
|
|
const filteredPatch = patch.filter(operation => filterRegExp.test(operation.path));
|
|
|
|
// Apply patch
|
|
jsonpatch.applyPatch(this.#data, filteredPatch);
|
|
|
|
// Notify event listeners
|
|
const patchEventa = new CustomEvent('patch', {detail: filteredPatch});
|
|
this.dispatchEvent(patchEventa);
|
|
|
|
// Notify event listeners. Event type: "patch *"
|
|
const patchEvent = new CustomEvent('patch *', {detail: filteredPatch});
|
|
this.dispatchEvent(patchEvent);
|
|
|
|
// Group patches by user id: {<user-id>: [op, ...], ...}
|
|
const patches = {};
|
|
const matchRegExp = new RegExp(`^/users/([A-Za-z0-9]+)`);
|
|
for (let operation of filteredPatch) {
|
|
const [match, userId] = operation.path.match(matchRegExp);
|
|
if (!(userId in patches)) {patches[userId] = [];}
|
|
patches[userId].push(operation);
|
|
}
|
|
|
|
// Notify event listeners. Event type: "patch <user-id>"
|
|
for (let [userId, patch] of Object.entries(patches)) {
|
|
const userPatchEvent = new CustomEvent(`patch ${userId}`, {detail: patch});
|
|
this.dispatchEvent(userPatchEvent);
|
|
}
|
|
}
|
|
}
|