90 lines
3.1 KiB
JavaScript
90 lines
3.1 KiB
JavaScript
import { Presence } from '@supabase/phoenix';
|
|
export default class PresenceAdapter {
|
|
constructor(channel, opts) {
|
|
const phoenixOptions = phoenixPresenceOptions(opts);
|
|
this.presence = new Presence(channel.getChannel(), phoenixOptions);
|
|
this.presence.onJoin((key, currentPresence, newPresence) => {
|
|
const onJoinPayload = PresenceAdapter.onJoinPayload(key, currentPresence, newPresence);
|
|
channel.getChannel().trigger('presence', onJoinPayload);
|
|
});
|
|
this.presence.onLeave((key, currentPresence, leftPresence) => {
|
|
const onLeavePayload = PresenceAdapter.onLeavePayload(key, currentPresence, leftPresence);
|
|
channel.getChannel().trigger('presence', onLeavePayload);
|
|
});
|
|
this.presence.onSync(() => {
|
|
channel.getChannel().trigger('presence', { event: 'sync' });
|
|
});
|
|
}
|
|
get state() {
|
|
return PresenceAdapter.transformState(this.presence.state);
|
|
}
|
|
/**
|
|
* @private
|
|
* Remove 'metas' key
|
|
* Change 'phx_ref' to 'presence_ref'
|
|
* Remove 'phx_ref' and 'phx_ref_prev'
|
|
*
|
|
* @example Transform state
|
|
* // returns {
|
|
* abc123: [
|
|
* { presence_ref: '2', user_id: 1 },
|
|
* { presence_ref: '3', user_id: 2 }
|
|
* ]
|
|
* }
|
|
* RealtimePresence.transformState({
|
|
* abc123: {
|
|
* metas: [
|
|
* { phx_ref: '2', phx_ref_prev: '1' user_id: 1 },
|
|
* { phx_ref: '3', user_id: 2 }
|
|
* ]
|
|
* }
|
|
* })
|
|
*
|
|
*/
|
|
static transformState(state) {
|
|
state = cloneState(state);
|
|
return Object.getOwnPropertyNames(state).reduce((newState, key) => {
|
|
const presences = state[key];
|
|
newState[key] = transformState(presences);
|
|
return newState;
|
|
}, {});
|
|
}
|
|
static onJoinPayload(key, currentPresence, newPresence) {
|
|
const currentPresences = parseCurrentPresences(currentPresence);
|
|
const newPresences = transformState(newPresence);
|
|
return {
|
|
event: 'join',
|
|
key,
|
|
currentPresences,
|
|
newPresences,
|
|
};
|
|
}
|
|
static onLeavePayload(key, currentPresence, leftPresence) {
|
|
const currentPresences = parseCurrentPresences(currentPresence);
|
|
const leftPresences = transformState(leftPresence);
|
|
return {
|
|
event: 'leave',
|
|
key,
|
|
currentPresences,
|
|
leftPresences,
|
|
};
|
|
}
|
|
}
|
|
function transformState(presences) {
|
|
return presences.metas.map((presence) => {
|
|
presence['presence_ref'] = presence['phx_ref'];
|
|
delete presence['phx_ref'];
|
|
delete presence['phx_ref_prev'];
|
|
return presence;
|
|
});
|
|
}
|
|
function cloneState(state) {
|
|
return JSON.parse(JSON.stringify(state));
|
|
}
|
|
function phoenixPresenceOptions(opts) {
|
|
return (opts === null || opts === void 0 ? void 0 : opts.events) && { events: opts.events };
|
|
}
|
|
function parseCurrentPresences(currentPresences) {
|
|
return (currentPresences === null || currentPresences === void 0 ? void 0 : currentPresences.metas) ? transformState(currentPresences) : [];
|
|
}
|
|
//# sourceMappingURL=presenceAdapter.js.map
|