@mescius/js-collaboration-presence-client 18.0.7 → 18.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,82 +1,108 @@
1
- import type { Connection } from "@mescius/js-collaboration-client";
1
+ import { Connection } from "@mescius/js-collaboration-client";
2
2
 
3
3
  export interface IPresences<P> {
4
4
  [id: string]: P;
5
5
  }
6
- export interface IEvents<P> {
7
- add: (presences: IPresences<P>) => void;
8
- update: (presences: IPresences<P>) => void;
9
- remove: (presencesIds: string[]) => void;
6
+
7
+ export interface IPresenceEvents<P> {
8
+ add: (addedPresences: IPresences<P>) => void;
9
+ update: (updatedPresences: IPresences<P>) => void;
10
+ remove: (removedPresencesIds: string[]) => void;
10
11
  }
11
12
 
12
13
  /**
14
+ * Manages presence information for real-time collaboration.
15
+ * @template P - The type of presence data.
13
16
  * @example
14
17
  * const uiComponent = new xxx.uiComponent();
15
- * const conn = new Client('ws://localhost:8080/').connect('room1');
16
- * const presence = new Presence(conn);
17
- * presence.subscribe(() => {
18
- * uiComponent.showPresences(presence.others);
18
+ * const connection = new Client('ws://localhost:8080/').connect('room1');
19
+ * const presence = new Presence(connection);
20
+ * presence.subscribe().then(() => {
21
+ * uiComponent.showPresences(presence.otherStates);
22
+ * presence.submitLocalState({ userId: xxx, selection: xxx });
19
23
  * uiComponent.on('selectionChanges', () => {
20
- * uiComponent.submitLocal({ userId: xxx, selection: xxx });
24
+ * presence.submitLocalStateField('selection', xxx);
21
25
  * });
22
26
  * presence.on('add', () => {
23
- * uiComponent.showPresences(presence.others);
27
+ * uiComponent.showPresences(presence.otherStates);
24
28
  * });
25
29
  * presence.on('update', () => {
26
- * uiComponent.showPresences(presence.others);
30
+ * uiComponent.showPresences(presence.otherStates);
27
31
  * });
28
32
  * presence.on('remove', () => {
29
- * uiComponent.showPresences(presence.others);
33
+ * uiComponent.showPresences(presence.otherStates);
30
34
  * });
31
- * presence.submitLocal({ userId: xxx, selection: xxx });
32
35
  * });
33
36
  */
34
37
  export declare class Presence<P> {
35
- constructor(conn: Connection);
38
+ constructor(connection: Connection);
39
+
40
+ /**
41
+ * Retrieves the unique identifier of the presence instance.
42
+ * @returns {string} The presence ID.
43
+ */
36
44
  get id(): string;
37
45
  /**
38
- * The local presence object.
46
+ * Retrieves the local presence state.
47
+ * @returns {P | undefined} The local presence data, or undefined if not set.
48
+ */
49
+ get localState(): P | undefined;
50
+ /**
51
+ * Retrieves the presence states of other clients.
52
+ * @returns {IPresences<P>} The collection of other clients' presence data.
39
53
  */
40
- local?: P;
54
+ get otherStates(): IPresences<P>;
41
55
  /**
42
- * The other presence objects.
56
+ * Retrieves the associated connection object.
57
+ * @returns {Connection} The connection instance.
43
58
  */
44
- others: IPresences<P>;
45
- conn: Connection;
59
+ get connection(): Connection;
46
60
  /**
47
- * Submit the local presence object to the server, server will broadcast the presence object to other clients.
48
- * @param p - The local presence object.
61
+ * Registers a listener for a specific event.
62
+ * @template NAME - The type of the event name, extending keyof IPresenceEvents<P>.
63
+ * @param {NAME} name - The name of the event.
64
+ * @param {IPresenceEvents<P>[NAME]} f - The event handler function.
65
+ * @returns {IPresenceEvents<P>[NAME]} The registered event handler.
49
66
  */
50
- submitLocal(p: P): void;
67
+ on<NAME extends keyof IPresenceEvents<P>>(name: NAME, f: IPresenceEvents<P>[NAME]): IPresenceEvents<P>[NAME];
51
68
  /**
52
- * Remove the local presence object from the server, server will broadcast to other clients.
69
+ * Registers a one-time listener for a specific event.
70
+ * @template NAME - The type of the event name, extending keyof IPresenceEvents<P>.
71
+ * @param {NAME} name - The name of the event.
72
+ * @param {IPresenceEvents<P>[NAME]} f - The event handler function to call once.
53
73
  */
54
- removeLocal(): void;
74
+ once<NAME extends keyof IPresenceEvents<P>>(name: NAME, f: IPresenceEvents<P>[NAME]): void;
55
75
  /**
56
- * Subscribe to presences.
57
- * @param callback - After the subscription is successful, can get others presences by "presence.others".
76
+ * Removes a listener for a specific event.
77
+ * @template NAME - The type of the event name, extending keyof IPresenceEvents<P>.
78
+ * @param {NAME} name - The name of the event.
79
+ * @param {IPresenceEvents<P>[NAME]} f - The event handler function to remove.
58
80
  */
59
- subscribe(callback: () => void): void;
81
+ off<NAME extends keyof IPresenceEvents<P>>(name: NAME, f: IPresenceEvents<P>[NAME]): void;
60
82
  /**
61
- * Register a listener for an event.
62
- * @param name - The event name.
63
- * @param f - The event handler.
83
+ * Destroys the presence instance and cleans up resources.
64
84
  */
65
- on<NAME extends keyof IEvents<P> & string>(name: NAME, f: IEvents<P>[NAME]): IEvents<P>[NAME];
85
+ destroy(): void;
86
+
66
87
  /**
67
- * Register a listener for an event that will only be called once.
68
- * @param name - The event name.
69
- * @param f - The event handler.
88
+ * Submits the local presence state to the server for broadcasting to other clients.
89
+ * @template P - The type of the presence data.
90
+ * @param {P} p - The local presence data to submit.
70
91
  */
71
- once<NAME_1 extends keyof IEvents<P> & string>(name: NAME_1, f: IEvents<P>[NAME_1]): void;
92
+ submitLocalState(p: P): void;
72
93
  /**
73
- * Remove a listener for an event.
74
- * @param name - The event name.
75
- * @param f - The event handler.
94
+ * Submits an update to a specific field of the local presence state to the server for broadcasting.
95
+ * @param {string} name - The name of the field to update.
96
+ * @param {unknown} value - The new value of the field.
76
97
  */
77
- off<NAME_2 extends keyof IEvents<P> & string>(name: NAME_2, f: IEvents<P>[NAME_2]): void;
98
+ submitLocalStateField(name: string, value: unknown): void;
78
99
  /**
79
- * Destroy the observable.
100
+ * Removes the local presence state from the server, notifying other clients.
80
101
  */
81
- destroy(): void;
82
- }
102
+ removeLocalState(): void;
103
+ /**
104
+ * Subscribes to presence updates from other clients.
105
+ * @returns {Promise<void>} A promise that resolves when subscription is complete; access other states via "presence.otherStates".
106
+ */
107
+ subscribe(): Promise<void>;
108
+ }
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var s=t();for(var r in s)("object"==typeof exports?exports:e)[r]=s[r]}}(this,(()=>(()=>{"use strict";var e={871:e=>{e.exports=require("buffer")},331:e=>{e.exports=require("pako")},884:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,i)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__exportStar||function(e,t){for(var s in e)"default"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_REQUEST_PATH=void 0,i(s(589),t),i(s(735),t),i(s(31),t),i(s(76),t),i(s(959),t),t.DEFAULT_REQUEST_PATH="/collaboration/"},31:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.logger=void 0,t.logger=class{static info(e,...t){}static warn(e,...t){}static error(e,...t){}}},735:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,i)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var s in e)"default"!==s&&Object.prototype.hasOwnProperty.call(e,s)&&r(t,e,s);return i(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.SOCKET_IO_MESSAGE_EVENT=void 0,t.encodeMessage=function(e,t=null){return[t,"string"==typeof e?a(e):e]},t.decodeMessage=function(e){return["string"==typeof e[1]?d(e[1]):e[1],e[0]]};const n=o(s(331)),c=s(871);function a(e){const t=(new TextEncoder).encode(e),s=n.deflate(t);return c.Buffer.from(s).toString("base64")}function d(e){const t=c.Buffer.from(e,"base64"),s=n.inflate(new Uint8Array(t));return(new TextDecoder).decode(s)}t.SOCKET_IO_MESSAGE_EVENT="m"},589:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Middleware=void 0,t.Middleware=class{constructor(){this.middlewares=new Map,this.hooks=new Map}use(e,t){this.middlewares.has(e)||this.middlewares.set(e,[]),this.middlewares.get(e).push(t)}on(e,t){this.hooks.has(e)||this.hooks.set(e,[]),this.hooks.get(e).push(t)}async trigger(e,t){let s=this.middlewares.get(e);if(!s)return;s=s.slice();const r=async e=>{if(e)throw e;const i=null==s?void 0:s.shift();i&&await i(t,r)};await r()}emit(e,t){const s=this.hooks.get(e);s&&s.forEach((e=>e(t)))}}},959:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Observable=void 0,t.Observable=class{constructor(){this._observers=new Map}on(e,t){return s(this._observers,e,(()=>new Set)).add(t),t}once(e,t){const s=(...r)=>{this.off(e,s),t(...r)};this.on(e,s)}off(e,t){const s=this._observers.get(e);void 0!==s&&(s.delete(t),0===s.size&&this._observers.delete(e))}emit(e,t){return Array.from((this._observers.get(e)||new Map).values()).forEach((e=>e(...t)))}destroy(){this._observers=new Map}};const s=(e,t,s)=>{let r=e.get(t);return void 0===r&&(r=s(),e.set(t,r)),r}},76:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isNullOrUndefined=function(e){return null==e}},773:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.PRESENCE_MESSAGE_TYPE=t.Actions=void 0,t.createPresences=function(e,t){const s={};for(let r=0;r<e.length;r++)s[e[r]]=t[r];return s},function(e){e.subscribe="s",e.unsubscribe="u",e.update="d",e.add="a",e.remove="r"}(s||(t.Actions=s={})),t.PRESENCE_MESSAGE_TYPE="p"}},t={};function s(r){var i=t[r];if(void 0!==i)return i.exports;var o=t[r]={exports:{}};return e[r].call(o.exports,o,o.exports,s),o.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.Presence=void 0;const t=s(773),i=s(884);class o extends i.Observable{constructor(e){super(),this.conn=e,this.others={},this._subscribeCallback=[],e.on("message",this._messageHandler.bind(this))}get id(){return this.conn.id}submitLocal(e){this.local=e,this._send({a:t.Actions.update,presence:e})}removeLocal(){delete this.local,this._send({a:t.Actions.remove})}subscribe(e){var s;null===(s=this._subscribeCallback)||void 0===s||s.push(e),this._send({a:t.Actions.subscribe})}_send(e){this.conn.send(JSON.stringify(e),t.PRESENCE_MESSAGE_TYPE)}_messageHandler(e,s){if(s!==t.PRESENCE_MESSAGE_TYPE)return;if("string"!=typeof e)return;const r=JSON.parse(e);switch(r.a){case t.Actions.subscribe:this._handleSubscribe(r);break;case t.Actions.add:this._handleAdd(r);break;case t.Actions.update:this._handleUpdate(r);break;case t.Actions.remove:this._handleRemove(r)}}_handleSubscribe(e){e.presences&&(this.others={},this._updatePresences(e.presences),this._subscribeCallback.forEach((e=>e())),this._subscribeCallback=[])}_handleAdd(e){const t=e.presences;t&&(this._updatePresences(t),this.emit("add",[t]))}_handleUpdate(e){const t=e.presences;t&&(this._updatePresences(t),this.emit("update",[t]))}_handleRemove(e){const t=e.presencesIds;if(!t||0===t.length)return;const s=this.id;t.forEach((e=>{e!==s?delete this.others[e]:delete this.local})),this.emit("remove",[t])}_updatePresences(e){const t=this.id;Object.keys(e).forEach((s=>{s!==t?this.others[s]=e[s]:this.local=e[s]}))}}e.Presence=o})(),r})()));
1
+ !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var s=t();for(var r in s)("object"==typeof exports?exports:e)[r]=s[r]}}(this,(()=>(()=>{"use strict";var e={871:e=>{e.exports=require("buffer")},331:e=>{e.exports=require("pako")},884:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var n=Object.getOwnPropertyDescriptor(t,s);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,n)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),n=this&&this.__exportStar||function(e,t){for(var s in e)"default"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_REQUEST_PATH=void 0,n(s(589),t),n(s(735),t),n(s(31),t),n(s(76),t),n(s(959),t),t.DEFAULT_REQUEST_PATH="/collaboration/"},31:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.LoggerManager=void 0;class s{debug(...e){}info(e){}warn(...e){}error(...e){}}class r{constructor(e){this.namespace=e}debug(...e){this.isEnabled&&this.logger.debug(`[${this.namespace}]`,...e)}info(...e){this.isEnabled&&this.logger.info(`[${this.namespace}]`,...e)}warn(...e){this.isEnabled&&this.logger.warn(`[${this.namespace}]`,...e)}error(...e){this.isEnabled&&this.logger.error(`[${this.namespace}]`,...e)}get isEnabled(){return n._isEnabledNamespace(this.namespace)}get logger(){return n.getInstance()}}class n{static getInstance(){return n._instance||(n._instance=new s),n._instance}static createLogger(e){return new r(e)}static setLogger(e){n._instance=e}static enableNamespace(e){n._enabledNamespace.push(...e)}static disableNamespace(e){n._enabledNamespace=n._enabledNamespace.filter((t=>!e.includes(t)))}static _isEnabledNamespace(e){return n._enabledNamespace.includes(e)||n._enabledNamespace.includes("*")}}t.LoggerManager=n,n._enabledNamespace=[]},735:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var n=Object.getOwnPropertyDescriptor(t,s);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,n)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var s in e)"default"!==s&&Object.prototype.hasOwnProperty.call(e,s)&&r(t,e,s);return n(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.SOCKET_IO_MESSAGE_EVENT=void 0,t.encodeMessage=function(e,t=null){return[t,"string"==typeof e?c(e):e]},t.decodeMessage=function(e){return["string"==typeof e[1]?d(e[1]):e[1],e[0]]};const a=i(s(331)),o=s(871);function c(e){const t=(new TextEncoder).encode(e),s=a.deflate(t);return o.Buffer.from(s).toString("base64")}function d(e){const t=o.Buffer.from(e,"base64"),s=a.inflate(new Uint8Array(t));return(new TextDecoder).decode(s)}t.SOCKET_IO_MESSAGE_EVENT="m"},589:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Middleware=void 0,t.Middleware=class{constructor(){this.middlewares=new Map,this.hooks=new Map}use(e,t){this.middlewares.has(e)||this.middlewares.set(e,[]),this.middlewares.get(e).push(t)}on(e,t){this.hooks.has(e)||this.hooks.set(e,[]),this.hooks.get(e).push(t)}async trigger(e,t,s){let r=this.middlewares.get(e);if(!r||0===r.length)return s();r=r.slice();const n=async e=>{if(e)return await s(e);const i=r.shift();if(!i)return await s();await i(t,n)};await n()}async emit(e,t){const s=this.hooks.get(e);if(s)for(const e of s)await e(t)}}},959:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Observable=void 0,t.Observable=class{constructor(){this._observers=new Map}on(e,t){return s(this._observers,e,(()=>new Set)).add(t),t}once(e,t){const s=(...r)=>{this.off(e,s),t(...r)};this.on(e,s)}off(e,t){const s=this._observers.get(e);void 0!==s&&(s.delete(t),0===s.size&&this._observers.delete(e))}emit(e,t){return Array.from((this._observers.get(e)||new Map).values()).forEach((e=>e(...t)))}destroy(){this._observers=new Map}};const s=(e,t,s)=>{let r=e.get(t);return void 0===r&&(r=s(),e.set(t,r)),r}},76:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isNullOrUndefined=function(e){return null==e}},773:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.PRESENCE_MESSAGE_TYPE=t.Actions=void 0,t.createPresences=function(e,t){const s={};for(let r=0;r<e.length;r++)s[e[r]]=t[r];return s},t.canApplyFieldUpdate=function(e){return"object"==typeof e&&null!==e},function(e){e.subscribe="s",e.unsubscribe="u",e.update="d",e.updateField="df",e.add="a",e.remove="r"}(s||(t.Actions=s={})),t.PRESENCE_MESSAGE_TYPE="presence"}},t={};function s(r){var n=t[r];if(void 0!==n)return n.exports;var i=t[r]={exports:{}};return e[r].call(i.exports,i,i.exports,s),i.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.Presence=void 0;const t=s(773),n=s(884);class i extends n.Observable{constructor(e){super(),this._others={},this._connection=e,this._subscribeCallback=[],e.on("message",this._messageHandler.bind(this))}get id(){return this.connection.id}get localState(){return this._local}get otherStates(){return this._others}get connection(){return this._connection}submitLocalState(e){this._local=e,this._send({a:t.Actions.update,presence:e})}submitLocalStateField(e,s){(0,t.canApplyFieldUpdate)(this._local)&&(this._local[e]=s,this._send({a:t.Actions.updateField,fieldUpdate:{k:e,v:s}}))}removeLocalState(){delete this._local,this._send({a:t.Actions.remove})}subscribe(){return new Promise((e=>{var s;null===(s=this._subscribeCallback)||void 0===s||s.push((()=>{e()})),this._send({a:t.Actions.subscribe})}))}_send(e){this.connection.send(JSON.stringify(e),t.PRESENCE_MESSAGE_TYPE)}_messageHandler(e,s){if(s!==t.PRESENCE_MESSAGE_TYPE)return;if("string"!=typeof e)return;const r=JSON.parse(e);switch(r.a){case t.Actions.subscribe:this._handleSubscribe(r);break;case t.Actions.add:this._handleAdd(r);break;case t.Actions.update:this._handleUpdate(r);break;case t.Actions.updateField:this._handleUpdateField(r);break;case t.Actions.remove:this._handleRemove(r)}}_handleSubscribe(e){e.presences&&(this._others={},this._updatePresences(e.presences),this._subscribeCallback.forEach((e=>e())),this._subscribeCallback=[])}_handleAdd(e){const t=e.presences;t&&(this._updatePresences(t),this.emit("add",[t]))}_handleUpdate(e){const t=e.presences;t&&(this._updatePresences(t),this.emit("update",[t]))}_handleUpdateField(e){const s=e.fieldUpdates;if(!s)return;const r=this._others,n={};for(const[e,i]of Object.entries(s)){if(!(0,t.canApplyFieldUpdate)(r[e]))return;r[e][i.k]=i.v,n[e]=r[e]}this.emit("update",[n])}_handleRemove(e){const t=e.presencesIds;if(!t||0===t.length)return;const s=this.id;t.forEach((e=>{e!==s?delete this._others[e]:delete this._local})),this.emit("remove",[t])}_updatePresences(e){const t=this.id;Object.keys(e).forEach((s=>{s!==t?this._others[s]=e[s]:this._local=e[s]}))}}e.Presence=i})(),r})()));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mescius/js-collaboration-presence-client",
3
- "version": "18.0.7",
3
+ "version": "18.1.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "keywords": [
@@ -22,7 +22,7 @@
22
22
  "license": "Commercial",
23
23
  "description": "SpreadJS Collaboration plugin",
24
24
  "dependencies": {
25
- "@mescius/js-collaboration-client": "18.0.7"
25
+ "@mescius/js-collaboration-client": "18.1.0"
26
26
  },
27
27
  "homepage": "https://developer.mescius.com/spreadjs"
28
28
  }