nopaque/app/static/js/app/user-live-registry.js
2024-12-03 15:59:08 +01:00

71 lines
1.9 KiB
JavaScript

nopaque.LiveUserRegistryExtension = class LiveUserRegistryExtension extends EventTarget {
#data;
constructor(app) {
super();
this.app = app;
this.#data = {
users: {},
promises: {}
};
}
init() {
this.app.users.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
let filterRegExp = new RegExp(`^/users/(${Object.keys(this.#data.users).join('|')})`);
let filteredPatch = patch.filter(operation => filterRegExp.test(operation.path));
// Apply patch
jsonpatch.applyPatch(this.#data, filteredPatch);
// Notify event listeners
let event = new CustomEvent('patch', {detail: filteredPatch});
this.dispatchEvent(event);
/*
// Notify event listeners. Event type: "patch *"
let event = new CustomEvent('patch *', {detail: filteredPatch});
this.dispatchEvent(event);
// Group patches by user id: {<user-id>: [op, ...], ...}
let patches = {};
let matchRegExp = new RegExp(`^/users/([A-Za-z0-9]+)`);
for (let operation of filteredPatch) {
let [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)) {
let event = new CustomEvent(`patch ${userId}`, {detail: patch});
this.dispatchEvent(event);
}
*/
}
}