@automerge/automerge-repo-react-hooks 2.5.2-alpha.6 → 2.5.3
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.js +53 -146
- package/dist/index.js.map +1 -1
- package/dist/usePresence.d.ts +2 -4
- package/dist/usePresence.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/usePresence.ts +2 -10
package/dist/index.js
CHANGED
|
@@ -6692,139 +6692,67 @@ const DEFAULT_HEARTBEAT_INTERVAL_MS = 15_000;
|
|
|
6692
6692
|
const DEFAULT_PEER_TTL_MS = 3 * DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
6693
6693
|
const PRESENCE_MESSAGE_MARKER = "__presence";
|
|
6694
6694
|
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6695
|
+
/**
|
|
6696
|
+
* A grouped view of peer states.
|
|
6697
|
+
*/
|
|
6699
6698
|
class PeerStateView {
|
|
6700
6699
|
value;
|
|
6701
6700
|
constructor(value) {
|
|
6702
6701
|
this.value = value;
|
|
6703
6702
|
}
|
|
6704
6703
|
/**
|
|
6705
|
-
* Get all
|
|
6706
|
-
*
|
|
6707
|
-
* @returns Array of user presence {@link State}s
|
|
6708
|
-
*/
|
|
6709
|
-
get users() {
|
|
6710
|
-
const userIds = unique(Object.values(this.value).map(peerState => peerState.userId));
|
|
6711
|
-
return userIds.map(u => this.getUserState(u));
|
|
6712
|
-
}
|
|
6713
|
-
/**
|
|
6714
|
-
* Get all devices.
|
|
6715
|
-
*
|
|
6716
|
-
* @returns Array of device presence {@link State}s
|
|
6717
|
-
*/
|
|
6718
|
-
get devices() {
|
|
6719
|
-
const deviceIds = unique(Object.values(this.value).map(peerState => peerState.deviceId));
|
|
6720
|
-
return deviceIds.map(d => this.getDeviceState(d));
|
|
6721
|
-
}
|
|
6722
|
-
/**
|
|
6723
|
-
* Get all peers.
|
|
6724
|
-
*
|
|
6725
|
-
* @returns Array of peer presence {@link State}s
|
|
6726
|
-
*/
|
|
6727
|
-
get peers() {
|
|
6728
|
-
return Object.values(this.value);
|
|
6729
|
-
}
|
|
6730
|
-
/**
|
|
6731
|
-
* Get all peer ids for this user.
|
|
6732
|
-
*
|
|
6733
|
-
* @param userId
|
|
6734
|
-
* @returns Array of peer ids for this user
|
|
6735
|
-
*/
|
|
6736
|
-
getUserPeers(userId) {
|
|
6737
|
-
return Object.values(this.value)
|
|
6738
|
-
.filter(peerState => peerState.userId === userId)
|
|
6739
|
-
.map(peerState => peerState.peerId);
|
|
6740
|
-
}
|
|
6741
|
-
/**
|
|
6742
|
-
* Get all peers for this device.
|
|
6743
|
-
*
|
|
6744
|
-
* @param deviceId
|
|
6745
|
-
* @returns Array of peer ids for this device
|
|
6746
|
-
*/
|
|
6747
|
-
getDevicePeers(deviceId) {
|
|
6748
|
-
return Object.values(this.value)
|
|
6749
|
-
.filter(peerState => peerState.deviceId === deviceId)
|
|
6750
|
-
.map(peerState => peerState.peerId);
|
|
6751
|
-
}
|
|
6752
|
-
/**
|
|
6753
|
-
* Return the most-recently-seen peer from this group.
|
|
6704
|
+
* Get the presence state of all peers. By default, each peer is its own
|
|
6705
|
+
* group, but presence activity can be aggregated by arbitrary criteria.
|
|
6754
6706
|
*
|
|
6755
|
-
* @param
|
|
6756
|
-
* @returns
|
|
6707
|
+
* @param opts
|
|
6708
|
+
* @returns presence state for all groups
|
|
6757
6709
|
*/
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
freshestLastSeenAt = lastSeenAt;
|
|
6767
|
-
return curr;
|
|
6710
|
+
getStates(opts) {
|
|
6711
|
+
const groupingFn = opts?.groupingFn ?? peerIdentity;
|
|
6712
|
+
const summaryFn = opts?.summaryFn ??
|
|
6713
|
+
getLastActivePeer;
|
|
6714
|
+
const statesByKey = Object.values(this.value).reduce((byKey, curr) => {
|
|
6715
|
+
const key = groupingFn(curr);
|
|
6716
|
+
if (!(key in byKey)) {
|
|
6717
|
+
byKey[key] = [];
|
|
6768
6718
|
}
|
|
6769
|
-
|
|
6770
|
-
|
|
6719
|
+
byKey[key].push(curr);
|
|
6720
|
+
return byKey;
|
|
6721
|
+
}, {});
|
|
6722
|
+
return Object.entries(statesByKey).reduce((result, [key, states]) => {
|
|
6723
|
+
result[key] = summaryFn(states);
|
|
6724
|
+
return result;
|
|
6725
|
+
}, {});
|
|
6771
6726
|
}
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6727
|
+
}
|
|
6728
|
+
/**
|
|
6729
|
+
* Get the peerId of this peer.
|
|
6730
|
+
*
|
|
6731
|
+
* @param peer
|
|
6732
|
+
* @returns peer id
|
|
6733
|
+
*/
|
|
6734
|
+
function peerIdentity(peer) {
|
|
6735
|
+
return peer.peerId;
|
|
6736
|
+
}
|
|
6737
|
+
/**
|
|
6738
|
+
* Find the peer that most recently sent a state update.
|
|
6739
|
+
*
|
|
6740
|
+
* @param peers
|
|
6741
|
+
* @returns id of most recently active peer
|
|
6742
|
+
*/
|
|
6743
|
+
function getLastActivePeer(peers) {
|
|
6744
|
+
let freshestLastActiveAt;
|
|
6745
|
+
return peers.reduce((freshest, curr) => {
|
|
6746
|
+
const lastActiveAt = curr.lastActiveAt;
|
|
6747
|
+
if (!lastActiveAt) {
|
|
6789
6748
|
return freshest;
|
|
6790
|
-
}, undefined);
|
|
6791
|
-
}
|
|
6792
|
-
/**
|
|
6793
|
-
* Get current ephemeral state value for this user's most-recently-active
|
|
6794
|
-
* peer.
|
|
6795
|
-
*
|
|
6796
|
-
* @param userId
|
|
6797
|
-
* @returns user's {@link State}
|
|
6798
|
-
*/
|
|
6799
|
-
getUserState(userId) {
|
|
6800
|
-
const peers = this.getUserPeers(userId);
|
|
6801
|
-
if (!peers) {
|
|
6802
|
-
return undefined;
|
|
6803
6749
|
}
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
return
|
|
6807
|
-
}
|
|
6808
|
-
return this.value[peer];
|
|
6809
|
-
}
|
|
6810
|
-
/**
|
|
6811
|
-
* Get current ephemeral state value for this device's most-recently-active
|
|
6812
|
-
* peer.
|
|
6813
|
-
*
|
|
6814
|
-
* @param deviceId
|
|
6815
|
-
* @returns device's {@link State}
|
|
6816
|
-
*/
|
|
6817
|
-
getDeviceState(deviceId) {
|
|
6818
|
-
const peers = this.getDevicePeers(deviceId);
|
|
6819
|
-
if (!peers) {
|
|
6820
|
-
return undefined;
|
|
6750
|
+
if (!freshest || lastActiveAt > freshestLastActiveAt) {
|
|
6751
|
+
freshestLastActiveAt = lastActiveAt;
|
|
6752
|
+
return curr;
|
|
6821
6753
|
}
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
return undefined;
|
|
6825
|
-
}
|
|
6826
|
-
return this.value[peer];
|
|
6827
|
-
}
|
|
6754
|
+
return freshest;
|
|
6755
|
+
}, undefined);
|
|
6828
6756
|
}
|
|
6829
6757
|
|
|
6830
6758
|
class PeerPresenceInfo {
|
|
@@ -6867,7 +6795,7 @@ class PeerPresenceInfo {
|
|
|
6867
6795
|
* @param peerId
|
|
6868
6796
|
* @param value
|
|
6869
6797
|
*/
|
|
6870
|
-
update({ peerId,
|
|
6798
|
+
update({ peerId, value }) {
|
|
6871
6799
|
const peerState = this.#peerStates.value[peerId];
|
|
6872
6800
|
const existingState = peerState?.value ?? {};
|
|
6873
6801
|
const now = Date.now();
|
|
@@ -6875,10 +6803,8 @@ class PeerPresenceInfo {
|
|
|
6875
6803
|
...this.#peerStates.value,
|
|
6876
6804
|
[peerId]: {
|
|
6877
6805
|
peerId,
|
|
6878
|
-
deviceId,
|
|
6879
|
-
userId,
|
|
6880
|
-
lastActiveAt: now,
|
|
6881
6806
|
lastSeenAt: now,
|
|
6807
|
+
lastActiveAt: now,
|
|
6882
6808
|
value: {
|
|
6883
6809
|
...existingState,
|
|
6884
6810
|
...value,
|
|
@@ -6933,8 +6859,6 @@ class PeerPresenceInfo {
|
|
|
6933
6859
|
*/
|
|
6934
6860
|
class Presence extends EventEmitter {
|
|
6935
6861
|
#handle;
|
|
6936
|
-
deviceId;
|
|
6937
|
-
userId;
|
|
6938
6862
|
#peers;
|
|
6939
6863
|
#localState;
|
|
6940
6864
|
#heartbeatMs;
|
|
@@ -6949,13 +6873,11 @@ class Presence extends EventEmitter {
|
|
|
6949
6873
|
* @param config see {@link PresenceConfig}
|
|
6950
6874
|
* @returns
|
|
6951
6875
|
*/
|
|
6952
|
-
constructor({ handle
|
|
6876
|
+
constructor({ handle }) {
|
|
6953
6877
|
super();
|
|
6954
6878
|
this.#handle = handle;
|
|
6955
6879
|
this.#peers = new PeerPresenceInfo(DEFAULT_PEER_TTL_MS);
|
|
6956
6880
|
this.#localState = {};
|
|
6957
|
-
this.userId = userId;
|
|
6958
|
-
this.deviceId = deviceId;
|
|
6959
6881
|
}
|
|
6960
6882
|
/**
|
|
6961
6883
|
* Start listening to ephemeral messages on the handle, broadcast initial
|
|
@@ -6979,7 +6901,6 @@ class Presence extends EventEmitter {
|
|
|
6979
6901
|
return;
|
|
6980
6902
|
}
|
|
6981
6903
|
const message = envelope[PRESENCE_MESSAGE_MARKER];
|
|
6982
|
-
const { deviceId, userId } = message;
|
|
6983
6904
|
if (!this.#peers.has(peerId)) {
|
|
6984
6905
|
this.announce();
|
|
6985
6906
|
}
|
|
@@ -6995,15 +6916,11 @@ class Presence extends EventEmitter {
|
|
|
6995
6916
|
case "update":
|
|
6996
6917
|
this.#peers.update({
|
|
6997
6918
|
peerId,
|
|
6998
|
-
deviceId,
|
|
6999
|
-
userId,
|
|
7000
6919
|
value: { [message.channel]: message.value },
|
|
7001
6920
|
});
|
|
7002
6921
|
this.emit("update", {
|
|
7003
6922
|
type: "update",
|
|
7004
6923
|
peerId,
|
|
7005
|
-
deviceId,
|
|
7006
|
-
userId,
|
|
7007
6924
|
channel: message.channel,
|
|
7008
6925
|
value: message.value,
|
|
7009
6926
|
});
|
|
@@ -7011,15 +6928,11 @@ class Presence extends EventEmitter {
|
|
|
7011
6928
|
case "snapshot":
|
|
7012
6929
|
this.#peers.update({
|
|
7013
6930
|
peerId,
|
|
7014
|
-
deviceId,
|
|
7015
|
-
userId,
|
|
7016
6931
|
value: message.state,
|
|
7017
6932
|
});
|
|
7018
6933
|
this.emit("snapshot", {
|
|
7019
6934
|
type: "snapshot",
|
|
7020
6935
|
peerId,
|
|
7021
|
-
deviceId,
|
|
7022
|
-
userId,
|
|
7023
6936
|
state: message.state,
|
|
7024
6937
|
});
|
|
7025
6938
|
break;
|
|
@@ -7114,8 +7027,6 @@ class Presence extends EventEmitter {
|
|
|
7114
7027
|
}
|
|
7115
7028
|
doBroadcast(type, extra) {
|
|
7116
7029
|
this.send({
|
|
7117
|
-
userId: this.userId,
|
|
7118
|
-
deviceId: this.deviceId,
|
|
7119
7030
|
type,
|
|
7120
7031
|
...extra,
|
|
7121
7032
|
});
|
|
@@ -7168,8 +7079,6 @@ class Presence extends EventEmitter {
|
|
|
7168
7079
|
|
|
7169
7080
|
function usePresence({
|
|
7170
7081
|
handle,
|
|
7171
|
-
userId,
|
|
7172
|
-
deviceId,
|
|
7173
7082
|
initialState,
|
|
7174
7083
|
heartbeatMs,
|
|
7175
7084
|
peerTtlMs
|
|
@@ -7181,9 +7090,7 @@ function usePresence({
|
|
|
7181
7090
|
peerTtlMs
|
|
7182
7091
|
});
|
|
7183
7092
|
const firstInitialState = useRef(initialState);
|
|
7184
|
-
const [presence] = useState(
|
|
7185
|
-
() => new Presence({ handle, userId, deviceId })
|
|
7186
|
-
);
|
|
7093
|
+
const [presence] = useState(() => new Presence({ handle }));
|
|
7187
7094
|
useEffect(() => {
|
|
7188
7095
|
presence.start({
|
|
7189
7096
|
initialState: firstInitialState.current,
|
|
@@ -7197,7 +7104,7 @@ function usePresence({
|
|
|
7197
7104
|
return () => {
|
|
7198
7105
|
presence.stop();
|
|
7199
7106
|
};
|
|
7200
|
-
}, [presence,
|
|
7107
|
+
}, [presence, firstInitialState, firstOpts]);
|
|
7201
7108
|
const start = useCallback(
|
|
7202
7109
|
(config) => {
|
|
7203
7110
|
const initialState2 = config?.initialState ?? presence.getLocalState();
|