@fluidframework/presence 2.10.0-307399
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/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/alpha.d.ts +58 -0
- package/dist/baseTypes.d.ts +24 -0
- package/dist/baseTypes.d.ts.map +1 -0
- package/dist/baseTypes.js +7 -0
- package/dist/baseTypes.js.map +1 -0
- package/dist/container-definitions/containerExtensions.d.ts +137 -0
- package/dist/container-definitions/containerExtensions.d.ts.map +1 -0
- package/dist/container-definitions/containerExtensions.js +7 -0
- package/dist/container-definitions/containerExtensions.js.map +1 -0
- package/dist/container-definitions/index.d.ts +7 -0
- package/dist/container-definitions/index.d.ts.map +1 -0
- package/dist/container-definitions/index.js +7 -0
- package/dist/container-definitions/index.js.map +1 -0
- package/dist/container-definitions/runtime.d.ts +12 -0
- package/dist/container-definitions/runtime.d.ts.map +1 -0
- package/dist/container-definitions/runtime.js +7 -0
- package/dist/container-definitions/runtime.js.map +1 -0
- package/dist/core-interfaces/exposedUtilityTypes.d.ts +446 -0
- package/dist/core-interfaces/exposedUtilityTypes.d.ts.map +1 -0
- package/dist/core-interfaces/exposedUtilityTypes.js +11 -0
- package/dist/core-interfaces/exposedUtilityTypes.js.map +1 -0
- package/dist/core-interfaces/index.d.ts +10 -0
- package/dist/core-interfaces/index.d.ts.map +1 -0
- package/dist/core-interfaces/index.js +7 -0
- package/dist/core-interfaces/index.js.map +1 -0
- package/dist/core-interfaces/jsonDeserialized.d.ts +109 -0
- package/dist/core-interfaces/jsonDeserialized.d.ts.map +1 -0
- package/dist/core-interfaces/jsonDeserialized.js +7 -0
- package/dist/core-interfaces/jsonDeserialized.js.map +1 -0
- package/dist/core-interfaces/jsonSerializable.d.ts +120 -0
- package/dist/core-interfaces/jsonSerializable.d.ts.map +1 -0
- package/dist/core-interfaces/jsonSerializable.js +7 -0
- package/dist/core-interfaces/jsonSerializable.js.map +1 -0
- package/dist/core-interfaces/jsonSerializationErrors.d.ts +31 -0
- package/dist/core-interfaces/jsonSerializationErrors.d.ts.map +1 -0
- package/dist/core-interfaces/jsonSerializationErrors.js +7 -0
- package/dist/core-interfaces/jsonSerializationErrors.js.map +1 -0
- package/dist/core-interfaces/jsonType.d.ts +29 -0
- package/dist/core-interfaces/jsonType.d.ts.map +1 -0
- package/dist/core-interfaces/jsonType.js +7 -0
- package/dist/core-interfaces/jsonType.js.map +1 -0
- package/dist/datastorePresenceManagerFactory.d.ts +48 -0
- package/dist/datastorePresenceManagerFactory.d.ts.map +1 -0
- package/dist/datastorePresenceManagerFactory.js +79 -0
- package/dist/datastorePresenceManagerFactory.js.map +1 -0
- package/dist/datastoreSupport.d.ts +31 -0
- package/dist/datastoreSupport.d.ts.map +1 -0
- package/dist/datastoreSupport.js +82 -0
- package/dist/datastoreSupport.js.map +1 -0
- package/dist/events/events.d.ts +198 -0
- package/dist/events/events.d.ts.map +1 -0
- package/dist/events/events.js +157 -0
- package/dist/events/events.js.map +1 -0
- package/dist/experimentalAccess.d.ts +15 -0
- package/dist/experimentalAccess.d.ts.map +1 -0
- package/dist/experimentalAccess.js +46 -0
- package/dist/experimentalAccess.js.map +1 -0
- package/dist/exposedInternalTypes.d.ts +100 -0
- package/dist/exposedInternalTypes.d.ts.map +1 -0
- package/dist/exposedInternalTypes.js +19 -0
- package/dist/exposedInternalTypes.js.map +1 -0
- package/dist/exposedUtilityTypes.d.ts +63 -0
- package/dist/exposedUtilityTypes.d.ts.map +1 -0
- package/dist/exposedUtilityTypes.js +7 -0
- package/dist/exposedUtilityTypes.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/internalTypes.d.ts +39 -0
- package/dist/internalTypes.d.ts.map +1 -0
- package/dist/internalTypes.js +14 -0
- package/dist/internalTypes.js.map +1 -0
- package/dist/latestMapValueManager.d.ts +182 -0
- package/dist/latestMapValueManager.d.ts.map +1 -0
- package/dist/latestMapValueManager.js +206 -0
- package/dist/latestMapValueManager.js.map +1 -0
- package/dist/latestValueControls.d.ts +44 -0
- package/dist/latestValueControls.d.ts.map +1 -0
- package/dist/latestValueControls.js +28 -0
- package/dist/latestValueControls.js.map +1 -0
- package/dist/latestValueManager.d.ts +69 -0
- package/dist/latestValueManager.d.ts.map +1 -0
- package/dist/latestValueManager.js +100 -0
- package/dist/latestValueManager.js.map +1 -0
- package/dist/latestValueTypes.d.ts +44 -0
- package/dist/latestValueTypes.d.ts.map +1 -0
- package/dist/latestValueTypes.js +7 -0
- package/dist/latestValueTypes.js.map +1 -0
- package/dist/notificationsManager.d.ts +101 -0
- package/dist/notificationsManager.d.ts.map +1 -0
- package/dist/notificationsManager.js +82 -0
- package/dist/notificationsManager.js.map +1 -0
- package/dist/package.json +15 -0
- package/dist/presence.d.ts +180 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +23 -0
- package/dist/presence.js.map +1 -0
- package/dist/presenceDatastoreManager.d.ts +91 -0
- package/dist/presenceDatastoreManager.d.ts.map +1 -0
- package/dist/presenceDatastoreManager.js +248 -0
- package/dist/presenceDatastoreManager.js.map +1 -0
- package/dist/presenceManager.d.ts +20 -0
- package/dist/presenceManager.d.ts.map +1 -0
- package/dist/presenceManager.js +104 -0
- package/dist/presenceManager.js.map +1 -0
- package/dist/presenceStates.d.ts +78 -0
- package/dist/presenceStates.d.ts.map +1 -0
- package/dist/presenceStates.js +182 -0
- package/dist/presenceStates.js.map +1 -0
- package/dist/stateDatastore.d.ts +35 -0
- package/dist/stateDatastore.d.ts.map +1 -0
- package/dist/stateDatastore.js +26 -0
- package/dist/stateDatastore.js.map +1 -0
- package/dist/systemWorkspace.d.ts +51 -0
- package/dist/systemWorkspace.d.ts.map +1 -0
- package/dist/systemWorkspace.js +180 -0
- package/dist/systemWorkspace.js.map +1 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/valueManager.d.ts +19 -0
- package/dist/valueManager.d.ts.map +1 -0
- package/dist/valueManager.js +26 -0
- package/dist/valueManager.js.map +1 -0
- package/lib/alpha.d.ts +58 -0
- package/lib/baseTypes.d.ts +24 -0
- package/lib/baseTypes.d.ts.map +1 -0
- package/lib/baseTypes.js +6 -0
- package/lib/baseTypes.js.map +1 -0
- package/lib/container-definitions/containerExtensions.d.ts +137 -0
- package/lib/container-definitions/containerExtensions.d.ts.map +1 -0
- package/lib/container-definitions/containerExtensions.js +6 -0
- package/lib/container-definitions/containerExtensions.js.map +1 -0
- package/lib/container-definitions/index.d.ts +7 -0
- package/lib/container-definitions/index.d.ts.map +1 -0
- package/lib/container-definitions/index.js +6 -0
- package/lib/container-definitions/index.js.map +1 -0
- package/lib/container-definitions/runtime.d.ts +12 -0
- package/lib/container-definitions/runtime.d.ts.map +1 -0
- package/lib/container-definitions/runtime.js +6 -0
- package/lib/container-definitions/runtime.js.map +1 -0
- package/lib/core-interfaces/exposedUtilityTypes.d.ts +446 -0
- package/lib/core-interfaces/exposedUtilityTypes.d.ts.map +1 -0
- package/lib/core-interfaces/exposedUtilityTypes.js +10 -0
- package/lib/core-interfaces/exposedUtilityTypes.js.map +1 -0
- package/lib/core-interfaces/index.d.ts +10 -0
- package/lib/core-interfaces/index.d.ts.map +1 -0
- package/lib/core-interfaces/index.js +6 -0
- package/lib/core-interfaces/index.js.map +1 -0
- package/lib/core-interfaces/jsonDeserialized.d.ts +109 -0
- package/lib/core-interfaces/jsonDeserialized.d.ts.map +1 -0
- package/lib/core-interfaces/jsonDeserialized.js +6 -0
- package/lib/core-interfaces/jsonDeserialized.js.map +1 -0
- package/lib/core-interfaces/jsonSerializable.d.ts +120 -0
- package/lib/core-interfaces/jsonSerializable.d.ts.map +1 -0
- package/lib/core-interfaces/jsonSerializable.js +6 -0
- package/lib/core-interfaces/jsonSerializable.js.map +1 -0
- package/lib/core-interfaces/jsonSerializationErrors.d.ts +31 -0
- package/lib/core-interfaces/jsonSerializationErrors.d.ts.map +1 -0
- package/lib/core-interfaces/jsonSerializationErrors.js +6 -0
- package/lib/core-interfaces/jsonSerializationErrors.js.map +1 -0
- package/lib/core-interfaces/jsonType.d.ts +29 -0
- package/lib/core-interfaces/jsonType.d.ts.map +1 -0
- package/lib/core-interfaces/jsonType.js +6 -0
- package/lib/core-interfaces/jsonType.js.map +1 -0
- package/lib/datastorePresenceManagerFactory.d.ts +48 -0
- package/lib/datastorePresenceManagerFactory.d.ts.map +1 -0
- package/lib/datastorePresenceManagerFactory.js +75 -0
- package/lib/datastorePresenceManagerFactory.js.map +1 -0
- package/lib/datastoreSupport.d.ts +31 -0
- package/lib/datastoreSupport.d.ts.map +1 -0
- package/lib/datastoreSupport.js +77 -0
- package/lib/datastoreSupport.js.map +1 -0
- package/lib/events/events.d.ts +198 -0
- package/lib/events/events.d.ts.map +1 -0
- package/lib/events/events.js +152 -0
- package/lib/events/events.js.map +1 -0
- package/lib/experimentalAccess.d.ts +15 -0
- package/lib/experimentalAccess.d.ts.map +1 -0
- package/lib/experimentalAccess.js +42 -0
- package/lib/experimentalAccess.js.map +1 -0
- package/lib/exposedInternalTypes.d.ts +100 -0
- package/lib/exposedInternalTypes.d.ts.map +1 -0
- package/lib/exposedInternalTypes.js +16 -0
- package/lib/exposedInternalTypes.js.map +1 -0
- package/lib/exposedUtilityTypes.d.ts +63 -0
- package/lib/exposedUtilityTypes.d.ts.map +1 -0
- package/lib/exposedUtilityTypes.js +6 -0
- package/lib/exposedUtilityTypes.js.map +1 -0
- package/lib/index.d.ts +22 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/internalTypes.d.ts +39 -0
- package/lib/internalTypes.d.ts.map +1 -0
- package/lib/internalTypes.js +11 -0
- package/lib/internalTypes.js.map +1 -0
- package/lib/latestMapValueManager.d.ts +182 -0
- package/lib/latestMapValueManager.d.ts.map +1 -0
- package/lib/latestMapValueManager.js +202 -0
- package/lib/latestMapValueManager.js.map +1 -0
- package/lib/latestValueControls.d.ts +44 -0
- package/lib/latestValueControls.d.ts.map +1 -0
- package/lib/latestValueControls.js +24 -0
- package/lib/latestValueControls.js.map +1 -0
- package/lib/latestValueManager.d.ts +69 -0
- package/lib/latestValueManager.d.ts.map +1 -0
- package/lib/latestValueManager.js +96 -0
- package/lib/latestValueManager.js.map +1 -0
- package/lib/latestValueTypes.d.ts +44 -0
- package/lib/latestValueTypes.d.ts.map +1 -0
- package/lib/latestValueTypes.js +6 -0
- package/lib/latestValueTypes.js.map +1 -0
- package/lib/notificationsManager.d.ts +101 -0
- package/lib/notificationsManager.d.ts.map +1 -0
- package/lib/notificationsManager.js +78 -0
- package/lib/notificationsManager.js.map +1 -0
- package/lib/presence.d.ts +180 -0
- package/lib/presence.d.ts.map +1 -0
- package/lib/presence.js +20 -0
- package/lib/presence.js.map +1 -0
- package/lib/presenceDatastoreManager.d.ts +91 -0
- package/lib/presenceDatastoreManager.d.ts.map +1 -0
- package/lib/presenceDatastoreManager.js +244 -0
- package/lib/presenceDatastoreManager.js.map +1 -0
- package/lib/presenceManager.d.ts +20 -0
- package/lib/presenceManager.d.ts.map +1 -0
- package/lib/presenceManager.js +100 -0
- package/lib/presenceManager.js.map +1 -0
- package/lib/presenceStates.d.ts +78 -0
- package/lib/presenceStates.d.ts.map +1 -0
- package/lib/presenceStates.js +177 -0
- package/lib/presenceStates.js.map +1 -0
- package/lib/stateDatastore.d.ts +35 -0
- package/lib/stateDatastore.d.ts.map +1 -0
- package/lib/stateDatastore.js +21 -0
- package/lib/stateDatastore.js.map +1 -0
- package/lib/systemWorkspace.d.ts +51 -0
- package/lib/systemWorkspace.d.ts.map +1 -0
- package/lib/systemWorkspace.js +176 -0
- package/lib/systemWorkspace.js.map +1 -0
- package/lib/tsdoc-metadata.json +11 -0
- package/lib/types.d.ts +92 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -0
- package/lib/valueManager.d.ts +19 -0
- package/lib/valueManager.d.ts.map +1 -0
- package/lib/valueManager.js +21 -0
- package/lib/valueManager.js.map +1 -0
- package/package.json +175 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createSystemWorkspace = void 0;
|
|
8
|
+
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
|
+
const presence_js_1 = require("./presence.js");
|
|
10
|
+
class SessionClient {
|
|
11
|
+
constructor(sessionId, connectionId = undefined) {
|
|
12
|
+
this.sessionId = sessionId;
|
|
13
|
+
this.connectionId = connectionId;
|
|
14
|
+
/**
|
|
15
|
+
* Order is used to track the most recent client connection
|
|
16
|
+
* during a session.
|
|
17
|
+
*/
|
|
18
|
+
this.order = 0;
|
|
19
|
+
this.connectionStatus =
|
|
20
|
+
connectionId === undefined
|
|
21
|
+
? presence_js_1.SessionClientStatus.Disconnected
|
|
22
|
+
: presence_js_1.SessionClientStatus.Connected;
|
|
23
|
+
}
|
|
24
|
+
getConnectionId() {
|
|
25
|
+
if (this.connectionId === undefined) {
|
|
26
|
+
throw new Error("Client has never been connected");
|
|
27
|
+
}
|
|
28
|
+
return this.connectionId;
|
|
29
|
+
}
|
|
30
|
+
getConnectionStatus() {
|
|
31
|
+
return this.connectionStatus;
|
|
32
|
+
}
|
|
33
|
+
setConnectionId(connectionId) {
|
|
34
|
+
this.connectionId = connectionId;
|
|
35
|
+
this.connectionStatus = presence_js_1.SessionClientStatus.Connected;
|
|
36
|
+
}
|
|
37
|
+
setDisconnected() {
|
|
38
|
+
this.connectionStatus = presence_js_1.SessionClientStatus.Disconnected;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
class SystemWorkspaceImpl {
|
|
42
|
+
constructor(clientSessionId, datastore, events, audience) {
|
|
43
|
+
this.datastore = datastore;
|
|
44
|
+
this.events = events;
|
|
45
|
+
this.audience = audience;
|
|
46
|
+
/**
|
|
47
|
+
* `attendees` is this client's understanding of the attendees in the
|
|
48
|
+
* session. The map covers entries for both session ids and connection
|
|
49
|
+
* ids, which are never expected to collide, but if they did for same
|
|
50
|
+
* client that would be fine.
|
|
51
|
+
* An entry is for session ID if the value's `sessionId` matches the key.
|
|
52
|
+
*/
|
|
53
|
+
this.attendees = new Map();
|
|
54
|
+
this.selfAttendee = new SessionClient(clientSessionId);
|
|
55
|
+
this.attendees.set(clientSessionId, this.selfAttendee);
|
|
56
|
+
}
|
|
57
|
+
ensureContent(_content) {
|
|
58
|
+
throw new Error("Method not implemented.");
|
|
59
|
+
}
|
|
60
|
+
processUpdate(_received, _timeModifier, remoteDatastore, senderConnectionId) {
|
|
61
|
+
const postUpdateActions = [];
|
|
62
|
+
const audienceMembers = this.audience.getMembers();
|
|
63
|
+
const connectedAttendees = new Set();
|
|
64
|
+
for (const [clientConnectionId, value] of Object.entries(remoteDatastore.clientToSessionId)) {
|
|
65
|
+
const clientSessionId = value.value;
|
|
66
|
+
const { attendee, isNew } = this.ensureAttendee(clientSessionId, clientConnectionId,
|
|
67
|
+
/* order */ value.rev);
|
|
68
|
+
// Check new attendee against audience to see if they're currently connected
|
|
69
|
+
const isAttendeeConnected = audienceMembers.has(clientConnectionId);
|
|
70
|
+
if (isAttendeeConnected) {
|
|
71
|
+
connectedAttendees.add(attendee);
|
|
72
|
+
if (attendee.getConnectionStatus() === presence_js_1.SessionClientStatus.Disconnected) {
|
|
73
|
+
attendee.setConnectionId(clientConnectionId);
|
|
74
|
+
}
|
|
75
|
+
if (isNew) {
|
|
76
|
+
// If the attendee is both new and in audience (i.e. currently connected), emit an attendeeJoined event.
|
|
77
|
+
postUpdateActions.push(() => this.events.emit("attendeeJoined", attendee));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// If the attendee is not in the audience, they are considered disconnected.
|
|
81
|
+
if (!connectedAttendees.has(attendee)) {
|
|
82
|
+
attendee.setDisconnected();
|
|
83
|
+
}
|
|
84
|
+
const knownSessionId = this.datastore.clientToSessionId[clientConnectionId];
|
|
85
|
+
if (knownSessionId === undefined) {
|
|
86
|
+
this.datastore.clientToSessionId[clientConnectionId] = value;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
(0, internal_1.assert)(knownSessionId.value === value.value, 0xa5a /* Mismatched SessionId */);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// TODO: reorganize processUpdate and caller to process actions after all updates are processed.
|
|
93
|
+
for (const action of postUpdateActions) {
|
|
94
|
+
action();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
onConnectionAdded(clientConnectionId) {
|
|
98
|
+
this.datastore.clientToSessionId[clientConnectionId] = {
|
|
99
|
+
rev: this.selfAttendee.order++,
|
|
100
|
+
timestamp: Date.now(),
|
|
101
|
+
value: this.selfAttendee.sessionId,
|
|
102
|
+
};
|
|
103
|
+
this.selfAttendee.setConnectionId(clientConnectionId);
|
|
104
|
+
this.attendees.set(clientConnectionId, this.selfAttendee);
|
|
105
|
+
}
|
|
106
|
+
removeClientConnectionId(clientConnectionId) {
|
|
107
|
+
const attendee = this.attendees.get(clientConnectionId);
|
|
108
|
+
if (!attendee) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// If the last known connectionID is different from the connection ID being removed, the attendee has reconnected,
|
|
112
|
+
// therefore we should not change the attendee connection status or emit a disconnect event.
|
|
113
|
+
const attendeeReconnected = attendee.getConnectionId() !== clientConnectionId;
|
|
114
|
+
const connected = attendee.getConnectionStatus() === presence_js_1.SessionClientStatus.Connected;
|
|
115
|
+
if (!attendeeReconnected && connected) {
|
|
116
|
+
attendee.setDisconnected();
|
|
117
|
+
this.events.emit("attendeeDisconnected", attendee);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
getAttendees() {
|
|
121
|
+
return new Set(this.attendees.values());
|
|
122
|
+
}
|
|
123
|
+
getAttendee(clientId) {
|
|
124
|
+
const attendee = this.attendees.get(clientId);
|
|
125
|
+
if (attendee) {
|
|
126
|
+
return attendee;
|
|
127
|
+
}
|
|
128
|
+
// TODO: Restore option to add attendee on demand to handle internal
|
|
129
|
+
// lookup cases that must come from internal data.
|
|
130
|
+
// There aren't any resiliency mechanisms in place to handle a missed
|
|
131
|
+
// ClientJoin right now.
|
|
132
|
+
throw new Error("Attendee not found");
|
|
133
|
+
}
|
|
134
|
+
getMyself() {
|
|
135
|
+
return this.selfAttendee;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Make sure the given client session and connection ID pair are represented
|
|
139
|
+
* in the attendee map. If not present, SessionClient is created and added
|
|
140
|
+
* to map. If present, make sure the current connection ID is updated.
|
|
141
|
+
*/
|
|
142
|
+
ensureAttendee(clientSessionId, clientConnectionId, order) {
|
|
143
|
+
let attendee = this.attendees.get(clientSessionId);
|
|
144
|
+
let isNew = false;
|
|
145
|
+
if (attendee === undefined) {
|
|
146
|
+
// New attendee. Create SessionClient and add session ID based
|
|
147
|
+
// entry to map.
|
|
148
|
+
attendee = new SessionClient(clientSessionId, clientConnectionId);
|
|
149
|
+
this.attendees.set(clientSessionId, attendee);
|
|
150
|
+
isNew = true;
|
|
151
|
+
}
|
|
152
|
+
else if (order > attendee.order) {
|
|
153
|
+
// The given association is newer than the one we have.
|
|
154
|
+
// Update the order and current connection ID.
|
|
155
|
+
attendee.order = order;
|
|
156
|
+
attendee.setConnectionId(clientConnectionId);
|
|
157
|
+
isNew = true;
|
|
158
|
+
}
|
|
159
|
+
// Always update entry for the connection ID. (Okay if already set.)
|
|
160
|
+
this.attendees.set(clientConnectionId, attendee);
|
|
161
|
+
return { attendee, isNew };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Instantiates the system workspace.
|
|
166
|
+
*
|
|
167
|
+
* @internal
|
|
168
|
+
*/
|
|
169
|
+
function createSystemWorkspace(clientSessionId, datastore, events, audience) {
|
|
170
|
+
const workspace = new SystemWorkspaceImpl(clientSessionId, datastore, events, audience);
|
|
171
|
+
return {
|
|
172
|
+
workspace,
|
|
173
|
+
statesEntry: {
|
|
174
|
+
internal: workspace,
|
|
175
|
+
public: undefined,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
exports.createSystemWorkspace = createSystemWorkspace;
|
|
180
|
+
//# sourceMappingURL=systemWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemWorkspace.js","sourceRoot":"","sources":["../src/systemWorkspace.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IAudience } from \"@fluidframework/container-definitions\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { ClientConnectionId } from \"./baseTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tClientSessionId,\n\tIPresence,\n\tISessionClient,\n\tPresenceEvents,\n} from \"./presence.js\";\nimport { SessionClientStatus } from \"./presence.js\";\nimport type { PresenceStatesInternal } from \"./presenceStates.js\";\nimport type { PresenceStates, PresenceStatesSchema } from \"./types.js\";\n\nimport type { IEmitter } from \"@fluidframework/presence/internal/events\";\n\n/**\n * The system workspace's datastore structure.\n *\n * @internal\n */\nexport interface SystemWorkspaceDatastore {\n\tclientToSessionId: {\n\t\t[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<ClientSessionId>;\n\t};\n}\n\nclass SessionClient implements ISessionClient {\n\t/**\n\t * Order is used to track the most recent client connection\n\t * during a session.\n\t */\n\tpublic order: number = 0;\n\n\tprivate connectionStatus: SessionClientStatus;\n\n\tpublic constructor(\n\t\tpublic readonly sessionId: ClientSessionId,\n\t\tprivate connectionId: ClientConnectionId | undefined = undefined,\n\t) {\n\t\tthis.connectionStatus =\n\t\t\tconnectionId === undefined\n\t\t\t\t? SessionClientStatus.Disconnected\n\t\t\t\t: SessionClientStatus.Connected;\n\t}\n\n\tpublic getConnectionId(): ClientConnectionId {\n\t\tif (this.connectionId === undefined) {\n\t\t\tthrow new Error(\"Client has never been connected\");\n\t\t}\n\t\treturn this.connectionId;\n\t}\n\n\tpublic getConnectionStatus(): SessionClientStatus {\n\t\treturn this.connectionStatus;\n\t}\n\n\tpublic setConnectionId(connectionId: ClientConnectionId): void {\n\t\tthis.connectionId = connectionId;\n\t\tthis.connectionStatus = SessionClientStatus.Connected;\n\t}\n\n\tpublic setDisconnected(): void {\n\t\tthis.connectionStatus = SessionClientStatus.Disconnected;\n\t}\n}\n\n/**\n * @internal\n */\nexport interface SystemWorkspace\n\t// Portion of IPresence that is handled by SystemWorkspace along with\n\t// responsiblity for emitting \"attendeeJoined\" events.\n\textends Pick<IPresence, \"getAttendees\" | \"getAttendee\" | \"getMyself\"> {\n\t/**\n\t * Must be called when the current client acquires a new connection.\n\t *\n\t * @param clientConnectionId - The new client connection ID.\n\t */\n\tonConnectionAdded(clientConnectionId: ClientConnectionId): void;\n\n\t/**\n\t * Removes the client connection ID from the system workspace.\n\t *\n\t * @param clientConnectionId - The client connection ID to remove.\n\t */\n\tremoveClientConnectionId(clientConnectionId: ClientConnectionId): void;\n}\n\nclass SystemWorkspaceImpl implements PresenceStatesInternal, SystemWorkspace {\n\tprivate readonly selfAttendee: SessionClient;\n\t/**\n\t * `attendees` is this client's understanding of the attendees in the\n\t * session. The map covers entries for both session ids and connection\n\t * ids, which are never expected to collide, but if they did for same\n\t * client that would be fine.\n\t * An entry is for session ID if the value's `sessionId` matches the key.\n\t */\n\tprivate readonly attendees = new Map<ClientConnectionId | ClientSessionId, SessionClient>();\n\n\tpublic constructor(\n\t\tclientSessionId: ClientSessionId,\n\t\tprivate readonly datastore: SystemWorkspaceDatastore,\n\t\tprivate readonly events: IEmitter<\n\t\t\tPick<PresenceEvents, \"attendeeJoined\" | \"attendeeDisconnected\">\n\t\t>,\n\t\tprivate readonly audience: IAudience,\n\t) {\n\t\tthis.selfAttendee = new SessionClient(clientSessionId);\n\t\tthis.attendees.set(clientSessionId, this.selfAttendee);\n\t}\n\n\tpublic ensureContent<TSchemaAdditional extends PresenceStatesSchema>(\n\t\t_content: TSchemaAdditional,\n\t): never {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tpublic processUpdate(\n\t\t_received: number,\n\t\t_timeModifier: number,\n\t\tremoteDatastore: {\n\t\t\tclientToSessionId: {\n\t\t\t\t[\n\t\t\t\t\tConnectionId: ClientConnectionId\n\t\t\t\t]: InternalTypes.ValueRequiredState<ClientSessionId> & {\n\t\t\t\t\tignoreUnmonitored?: true;\n\t\t\t\t};\n\t\t\t};\n\t\t},\n\t\tsenderConnectionId: ClientConnectionId,\n\t): void {\n\t\tconst postUpdateActions: (() => void)[] = [];\n\t\tconst audienceMembers = this.audience.getMembers();\n\t\tconst connectedAttendees = new Set<SessionClient>();\n\t\tfor (const [clientConnectionId, value] of Object.entries(\n\t\t\tremoteDatastore.clientToSessionId,\n\t\t)) {\n\t\t\tconst clientSessionId = value.value;\n\t\t\tconst { attendee, isNew } = this.ensureAttendee(\n\t\t\t\tclientSessionId,\n\t\t\t\tclientConnectionId,\n\t\t\t\t/* order */ value.rev,\n\t\t\t);\n\n\t\t\t// Check new attendee against audience to see if they're currently connected\n\t\t\tconst isAttendeeConnected = audienceMembers.has(clientConnectionId);\n\n\t\t\tif (isAttendeeConnected) {\n\t\t\t\tconnectedAttendees.add(attendee);\n\t\t\t\tif (attendee.getConnectionStatus() === SessionClientStatus.Disconnected) {\n\t\t\t\t\tattendee.setConnectionId(clientConnectionId);\n\t\t\t\t}\n\t\t\t\tif (isNew) {\n\t\t\t\t\t// If the attendee is both new and in audience (i.e. currently connected), emit an attendeeJoined event.\n\t\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"attendeeJoined\", attendee));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the attendee is not in the audience, they are considered disconnected.\n\t\t\tif (!connectedAttendees.has(attendee)) {\n\t\t\t\tattendee.setDisconnected();\n\t\t\t}\n\n\t\t\tconst knownSessionId: InternalTypes.ValueRequiredState<ClientSessionId> | undefined =\n\t\t\t\tthis.datastore.clientToSessionId[clientConnectionId];\n\t\t\tif (knownSessionId === undefined) {\n\t\t\t\tthis.datastore.clientToSessionId[clientConnectionId] = value;\n\t\t\t} else {\n\t\t\t\tassert(knownSessionId.value === value.value, 0xa5a /* Mismatched SessionId */);\n\t\t\t}\n\t\t}\n\n\t\t// TODO: reorganize processUpdate and caller to process actions after all updates are processed.\n\t\tfor (const action of postUpdateActions) {\n\t\t\taction();\n\t\t}\n\t}\n\n\tpublic onConnectionAdded(clientConnectionId: ClientConnectionId): void {\n\t\tthis.datastore.clientToSessionId[clientConnectionId] = {\n\t\t\trev: this.selfAttendee.order++,\n\t\t\ttimestamp: Date.now(),\n\t\t\tvalue: this.selfAttendee.sessionId,\n\t\t};\n\n\t\tthis.selfAttendee.setConnectionId(clientConnectionId);\n\t\tthis.attendees.set(clientConnectionId, this.selfAttendee);\n\t}\n\n\tpublic removeClientConnectionId(clientConnectionId: ClientConnectionId): void {\n\t\tconst attendee = this.attendees.get(clientConnectionId);\n\t\tif (!attendee) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the last known connectionID is different from the connection ID being removed, the attendee has reconnected,\n\t\t// therefore we should not change the attendee connection status or emit a disconnect event.\n\t\tconst attendeeReconnected = attendee.getConnectionId() !== clientConnectionId;\n\t\tconst connected = attendee.getConnectionStatus() === SessionClientStatus.Connected;\n\t\tif (!attendeeReconnected && connected) {\n\t\t\tattendee.setDisconnected();\n\t\t\tthis.events.emit(\"attendeeDisconnected\", attendee);\n\t\t}\n\t}\n\n\tpublic getAttendees(): ReadonlySet<ISessionClient> {\n\t\treturn new Set(this.attendees.values());\n\t}\n\n\tpublic getAttendee(clientId: ClientConnectionId | ClientSessionId): ISessionClient {\n\t\tconst attendee = this.attendees.get(clientId);\n\t\tif (attendee) {\n\t\t\treturn attendee;\n\t\t}\n\n\t\t// TODO: Restore option to add attendee on demand to handle internal\n\t\t// lookup cases that must come from internal data.\n\t\t// There aren't any resiliency mechanisms in place to handle a missed\n\t\t// ClientJoin right now.\n\t\tthrow new Error(\"Attendee not found\");\n\t}\n\n\tpublic getMyself(): ISessionClient {\n\t\treturn this.selfAttendee;\n\t}\n\n\t/**\n\t * Make sure the given client session and connection ID pair are represented\n\t * in the attendee map. If not present, SessionClient is created and added\n\t * to map. If present, make sure the current connection ID is updated.\n\t */\n\tprivate ensureAttendee(\n\t\tclientSessionId: ClientSessionId,\n\t\tclientConnectionId: ClientConnectionId,\n\t\torder: number,\n\t): { attendee: SessionClient; isNew: boolean } {\n\t\tlet attendee = this.attendees.get(clientSessionId);\n\t\tlet isNew = false;\n\n\t\tif (attendee === undefined) {\n\t\t\t// New attendee. Create SessionClient and add session ID based\n\t\t\t// entry to map.\n\t\t\tattendee = new SessionClient(clientSessionId, clientConnectionId);\n\t\t\tthis.attendees.set(clientSessionId, attendee);\n\t\t\tisNew = true;\n\t\t} else if (order > attendee.order) {\n\t\t\t// The given association is newer than the one we have.\n\t\t\t// Update the order and current connection ID.\n\t\t\tattendee.order = order;\n\t\t\tattendee.setConnectionId(clientConnectionId);\n\t\t\tisNew = true;\n\t\t}\n\t\t// Always update entry for the connection ID. (Okay if already set.)\n\t\tthis.attendees.set(clientConnectionId, attendee);\n\n\t\treturn { attendee, isNew };\n\t}\n}\n\n/**\n * Instantiates the system workspace.\n *\n * @internal\n */\nexport function createSystemWorkspace(\n\tclientSessionId: ClientSessionId,\n\tdatastore: SystemWorkspaceDatastore,\n\tevents: IEmitter<Pick<PresenceEvents, \"attendeeJoined\">>,\n\taudience: IAudience,\n): {\n\tworkspace: SystemWorkspace;\n\tstatesEntry: {\n\t\tinternal: PresenceStatesInternal;\n\t\tpublic: PresenceStates<PresenceStatesSchema>;\n\t};\n} {\n\tconst workspace = new SystemWorkspaceImpl(clientSessionId, datastore, events, audience);\n\treturn {\n\t\tworkspace,\n\t\tstatesEntry: {\n\t\t\tinternal: workspace,\n\t\t\tpublic: undefined as unknown as PresenceStates<PresenceStatesSchema>,\n\t\t},\n\t};\n}\n"]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import type { NotificationsManager } from "./notificationsManager.js";
|
|
6
|
+
import type { InternalTypes } from "@fluidframework/presence/internal/exposedInternalTypes";
|
|
7
|
+
/**
|
|
8
|
+
* Unique address within a session.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* A string known to all clients working with a certain Workspace and unique
|
|
12
|
+
* among Workspaces. Recommend using specifying concatenation of: type of
|
|
13
|
+
* unique identifier, `:` (required), and unique identifier.
|
|
14
|
+
*
|
|
15
|
+
* @example Examples
|
|
16
|
+
* ```typescript
|
|
17
|
+
* "guid:g0fl001d-1415-5000-c00l-g0fa54g0b1g1"
|
|
18
|
+
* "address:object0/sub-object2:pointers"
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @alpha
|
|
22
|
+
*/
|
|
23
|
+
export type PresenceWorkspaceAddress = `${string}:${string}`;
|
|
24
|
+
/**
|
|
25
|
+
* Single entry in {@link PresenceStatesSchema}.
|
|
26
|
+
*
|
|
27
|
+
* @alpha
|
|
28
|
+
*/
|
|
29
|
+
export type PresenceStatesEntry<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<unknown>, TManager = unknown> = InternalTypes.ManagerFactory<TKey, TValue, TManager>;
|
|
30
|
+
/**
|
|
31
|
+
* Schema for a {@link PresenceStates} workspace.
|
|
32
|
+
*
|
|
33
|
+
* Keys of schema are the keys of the {@link PresenceStates} providing access to `Value Manager`s.
|
|
34
|
+
*
|
|
35
|
+
* @alpha
|
|
36
|
+
*/
|
|
37
|
+
export interface PresenceStatesSchema {
|
|
38
|
+
[key: string]: PresenceStatesEntry<typeof key, InternalTypes.ValueDirectoryOrState<any>>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Map of `Value Manager`s registered with {@link PresenceStates}.
|
|
42
|
+
*
|
|
43
|
+
* @sealed
|
|
44
|
+
* @alpha
|
|
45
|
+
*/
|
|
46
|
+
export type PresenceStatesEntries<TSchema extends PresenceStatesSchema> = {
|
|
47
|
+
/**
|
|
48
|
+
* Registered `Value Manager`s
|
|
49
|
+
*/
|
|
50
|
+
readonly [Key in keyof TSchema]: ReturnType<TSchema[Key]>["manager"] extends InternalTypes.StateValue<infer TManager> ? TManager : never;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* `PresenceStates` maintains a registry of `Value Manager`s that all share and provide access to
|
|
54
|
+
* presence state values across client members in a session.
|
|
55
|
+
*
|
|
56
|
+
* `Value Manager`s offer variations on how to manage states, but all share same principle that
|
|
57
|
+
* each client's state is independent and may only be updated by originating client.
|
|
58
|
+
*
|
|
59
|
+
* @sealed
|
|
60
|
+
* @alpha
|
|
61
|
+
*/
|
|
62
|
+
export interface PresenceStates<TSchema extends PresenceStatesSchema, TManagerConstraints = unknown> {
|
|
63
|
+
/**
|
|
64
|
+
* Registers a new `Value Manager` with the {@link PresenceStates}.
|
|
65
|
+
* @param key - new unique key for the `Value Manager`
|
|
66
|
+
* @param manager - factory for creating a `Value Manager`
|
|
67
|
+
*/
|
|
68
|
+
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<any>, TManager extends TManagerConstraints>(key: TKey, manager: InternalTypes.ManagerFactory<TKey, TValue, TManager>): asserts this is PresenceStates<TSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>, TManagerConstraints>;
|
|
69
|
+
/**
|
|
70
|
+
* Registry of `Value Manager`s.
|
|
71
|
+
*/
|
|
72
|
+
readonly props: PresenceStatesEntries<TSchema>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Schema for a {@link PresenceNotifications} workspace.
|
|
76
|
+
*
|
|
77
|
+
* Keys of schema are the keys of the {@link PresenceNotifications} providing access to {@link NotificationsManager}s.
|
|
78
|
+
*
|
|
79
|
+
* @alpha
|
|
80
|
+
*/
|
|
81
|
+
export interface PresenceNotificationsSchema {
|
|
82
|
+
[key: string]: InternalTypes.ManagerFactory<typeof key, InternalTypes.ValueRequiredState<InternalTypes.NotificationType>, NotificationsManager<any>>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* `PresenceNotifications` maintains a registry of {@link NotificationsManager}s
|
|
86
|
+
* that facilitate messages across client members in a session.
|
|
87
|
+
*
|
|
88
|
+
* @sealed
|
|
89
|
+
* @alpha
|
|
90
|
+
*/
|
|
91
|
+
export type PresenceNotifications<TSchema extends PresenceNotificationsSchema> = PresenceStates<TSchema, NotificationsManager<any>>;
|
|
92
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wDAAwD,CAAC;AAE5F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,wBAAwB,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAI7D;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,CAC9B,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,aAAa,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAC3D,QAAQ,GAAG,OAAO,IACf,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAAC,OAAO,GAAG,EAAE,aAAa,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;CACzF;AAED;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAAC,OAAO,SAAS,oBAAoB,IAAI;IACzE;;OAEG;IACH,QAAQ,EAAE,GAAG,IAAI,MAAM,OAAO,GAAG,UAAU,CAC1C,OAAO,CAAC,GAAG,CAAC,CACZ,CAAC,SAAS,CAAC,SAAS,aAAa,CAAC,UAAU,CAAC,MAAM,QAAQ,CAAC,GAC1D,QAAQ,GACR,KAAK;CACR,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc,CAC9B,OAAO,SAAS,oBAAoB,EACpC,mBAAmB,GAAG,OAAO;IAE7B;;;;OAIG;IACH,GAAG,CACF,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,aAAa,CAAC,qBAAqB,CAAC,GAAG,CAAC,EACvD,QAAQ,SAAS,mBAAmB,EAEpC,GAAG,EAAE,IAAI,EACT,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,GAC3D,OAAO,CAAC,IAAI,IAAI,cAAc,CAChC,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EAC5E,mBAAmB,CACnB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;CAC/C;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,cAAc,CAC1C,OAAO,GAAG,EACV,aAAa,CAAC,kBAAkB,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAChE,oBAAoB,CAAC,GAAG,CAAC,CACzB,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,CAAC,OAAO,SAAS,2BAA2B,IAC5E,cAAc,CAAC,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
// #endregion PresenceNotifications
|
|
8
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAmIH,mCAAmC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { NotificationsManager } from \"./notificationsManager.js\";\n\nimport type { InternalTypes } from \"@fluidframework/presence/internal/exposedInternalTypes\";\n\n/**\n * Unique address within a session.\n *\n * @remarks\n * A string known to all clients working with a certain Workspace and unique\n * among Workspaces. Recommend using specifying concatenation of: type of\n * unique identifier, `:` (required), and unique identifier.\n *\n * @example Examples\n * ```typescript\n * \"guid:g0fl001d-1415-5000-c00l-g0fa54g0b1g1\"\n * \"address:object0/sub-object2:pointers\"\n * ```\n *\n * @alpha\n */\nexport type PresenceWorkspaceAddress = `${string}:${string}`;\n\n// #region PresenceStates\n\n/**\n * Single entry in {@link PresenceStatesSchema}.\n *\n * @alpha\n */\nexport type PresenceStatesEntry<\n\tTKey extends string,\n\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\tTManager = unknown,\n> = InternalTypes.ManagerFactory<TKey, TValue, TManager>;\n\n/**\n * Schema for a {@link PresenceStates} workspace.\n *\n * Keys of schema are the keys of the {@link PresenceStates} providing access to `Value Manager`s.\n *\n * @alpha\n */\nexport interface PresenceStatesSchema {\n\t[key: string]: PresenceStatesEntry<typeof key, InternalTypes.ValueDirectoryOrState<any>>;\n}\n\n/**\n * Map of `Value Manager`s registered with {@link PresenceStates}.\n *\n * @sealed\n * @alpha\n */\nexport type PresenceStatesEntries<TSchema extends PresenceStatesSchema> = {\n\t/**\n\t * Registered `Value Manager`s\n\t */\n\treadonly [Key in keyof TSchema]: ReturnType<\n\t\tTSchema[Key]\n\t>[\"manager\"] extends InternalTypes.StateValue<infer TManager>\n\t\t? TManager\n\t\t: never;\n};\n\n/**\n * `PresenceStates` maintains a registry of `Value Manager`s that all share and provide access to\n * presence state values across client members in a session.\n *\n * `Value Manager`s offer variations on how to manage states, but all share same principle that\n * each client's state is independent and may only be updated by originating client.\n *\n * @sealed\n * @alpha\n */\nexport interface PresenceStates<\n\tTSchema extends PresenceStatesSchema,\n\tTManagerConstraints = unknown,\n> {\n\t/**\n\t * Registers a new `Value Manager` with the {@link PresenceStates}.\n\t * @param key - new unique key for the `Value Manager`\n\t * @param manager - factory for creating a `Value Manager`\n\t */\n\tadd<\n\t\tTKey extends string,\n\t\tTValue extends InternalTypes.ValueDirectoryOrState<any>,\n\t\tTManager extends TManagerConstraints,\n\t>(\n\t\tkey: TKey,\n\t\tmanager: InternalTypes.ManagerFactory<TKey, TValue, TManager>,\n\t): asserts this is PresenceStates<\n\t\tTSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>,\n\t\tTManagerConstraints\n\t>;\n\n\t/**\n\t * Registry of `Value Manager`s.\n\t */\n\treadonly props: PresenceStatesEntries<TSchema>;\n}\n\n// #endregion PresenceStates\n\n// #region PresenceNotifications\n\n/**\n * Schema for a {@link PresenceNotifications} workspace.\n *\n * Keys of schema are the keys of the {@link PresenceNotifications} providing access to {@link NotificationsManager}s.\n *\n * @alpha\n */\nexport interface PresenceNotificationsSchema {\n\t[key: string]: InternalTypes.ManagerFactory<\n\t\ttypeof key,\n\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>,\n\t\tNotificationsManager<any>\n\t>;\n}\n\n/**\n * `PresenceNotifications` maintains a registry of {@link NotificationsManager}s\n * that facilitate messages across client members in a session.\n *\n * @sealed\n * @alpha\n */\nexport type PresenceNotifications<TSchema extends PresenceNotificationsSchema> =\n\tPresenceStates<TSchema, NotificationsManager<any>>;\n\n// #endregion PresenceNotifications\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
6
|
+
import type { ValueManager } from "./internalTypes.js";
|
|
7
|
+
/**
|
|
8
|
+
* Given a value manager, return opaque InternalTypes.StateValue.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function brandIVM<TManagerInterface, TValue, TValueState extends InternalTypes.ValueDirectoryOrState<TValue>>(manager: TManagerInterface & ValueManager<TValue, TValueState>): InternalTypes.StateValue<TManagerInterface>;
|
|
13
|
+
/**
|
|
14
|
+
* Extract the value manager from an opaque InternalTypes.StateValue.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare function unbrandIVM<TManagerInterface, TValue, TValueState extends InternalTypes.ValueDirectoryOrState<TValue>>(branded: InternalTypes.StateValue<TManagerInterface>): ValueManager<TValue, TValueState>;
|
|
19
|
+
//# sourceMappingURL=valueManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valueManager.d.ts","sourceRoot":"","sources":["../src/valueManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,QAAQ,CACvB,iBAAiB,EACjB,MAAM,EACN,WAAW,SAAS,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAE/D,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAC5D,aAAa,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,iBAAiB,EACjB,MAAM,EACN,WAAW,SAAS,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAC9D,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAEzF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.unbrandIVM = exports.brandIVM = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Given a value manager, return opaque InternalTypes.StateValue.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
function brandIVM(manager) {
|
|
14
|
+
return manager;
|
|
15
|
+
}
|
|
16
|
+
exports.brandIVM = brandIVM;
|
|
17
|
+
/**
|
|
18
|
+
* Extract the value manager from an opaque InternalTypes.StateValue.
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
function unbrandIVM(branded) {
|
|
23
|
+
return branded;
|
|
24
|
+
}
|
|
25
|
+
exports.unbrandIVM = unbrandIVM;
|
|
26
|
+
//# sourceMappingURL=valueManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valueManager.js","sourceRoot":"","sources":["../src/valueManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAKH;;;;GAIG;AACH,SAAgB,QAAQ,CAKvB,OAA8D;IAE9D,OAAO,OAA2E,CAAC;AACpF,CAAC;AARD,4BAQC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAIxB,OAAoD;IACrD,OAAO,OAAuD,CAAC;AAChE,CAAC;AAND,gCAMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { ValueManager } from \"./internalTypes.js\";\n\n/**\n * Given a value manager, return opaque InternalTypes.StateValue.\n *\n * @internal\n */\nexport function brandIVM<\n\tTManagerInterface,\n\tTValue,\n\tTValueState extends InternalTypes.ValueDirectoryOrState<TValue>,\n>(\n\tmanager: TManagerInterface & ValueManager<TValue, TValueState>,\n): InternalTypes.StateValue<TManagerInterface> {\n\treturn manager as TManagerInterface as InternalTypes.StateValue<TManagerInterface>;\n}\n\n/**\n * Extract the value manager from an opaque InternalTypes.StateValue.\n *\n * @internal\n */\nexport function unbrandIVM<\n\tTManagerInterface,\n\tTValue,\n\tTValueState extends InternalTypes.ValueDirectoryOrState<TValue>,\n>(branded: InternalTypes.StateValue<TManagerInterface>): ValueManager<TValue, TValueState> {\n\treturn branded as unknown as ValueManager<TValue, TValueState>;\n}\n"]}
|
package/lib/alpha.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
+
* Generated by "flub generate entrypoints" in @fluid-tools/build-cli.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Experimental package for client presence within a connected session.
|
|
13
|
+
*
|
|
14
|
+
* See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
// @alpha APIs
|
|
21
|
+
ClientConnectionId,
|
|
22
|
+
ClientSessionId,
|
|
23
|
+
ExperimentalPresenceDO,
|
|
24
|
+
ExperimentalPresenceManager,
|
|
25
|
+
IPresence,
|
|
26
|
+
ISessionClient,
|
|
27
|
+
Latest,
|
|
28
|
+
LatestMap,
|
|
29
|
+
LatestMapItemRemovedClientData,
|
|
30
|
+
LatestMapItemValueClientData,
|
|
31
|
+
LatestMapValueClientData,
|
|
32
|
+
LatestMapValueManager,
|
|
33
|
+
LatestMapValueManagerEvents,
|
|
34
|
+
LatestValueClientData,
|
|
35
|
+
LatestValueControls,
|
|
36
|
+
LatestValueData,
|
|
37
|
+
LatestValueManager,
|
|
38
|
+
LatestValueManagerEvents,
|
|
39
|
+
LatestValueMetadata,
|
|
40
|
+
NotificationEmitter,
|
|
41
|
+
NotificationSubscribable,
|
|
42
|
+
NotificationSubscriptions,
|
|
43
|
+
Notifications,
|
|
44
|
+
NotificationsManager,
|
|
45
|
+
NotificationsManagerEvents,
|
|
46
|
+
PresenceEvents,
|
|
47
|
+
PresenceNotifications,
|
|
48
|
+
PresenceNotificationsSchema,
|
|
49
|
+
PresenceStates,
|
|
50
|
+
PresenceStatesEntries,
|
|
51
|
+
PresenceStatesEntry,
|
|
52
|
+
PresenceStatesSchema,
|
|
53
|
+
PresenceWorkspaceAddress,
|
|
54
|
+
SessionClientStatus,
|
|
55
|
+
ValueMap,
|
|
56
|
+
acquirePresence,
|
|
57
|
+
acquirePresenceViaDataObject
|
|
58
|
+
} from "./index.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A Fluid client connection identifier.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Each client connection is given a unique identifier for the duration of the
|
|
10
|
+
* connection. If a client disconnects and reconnects, it will be given a new
|
|
11
|
+
* identifier. Prefer use of {@link ISessionClient} as a way to identify clients
|
|
12
|
+
* in a session. {@link ISessionClient.getConnectionId} will provide the current
|
|
13
|
+
* connection identifier for a logical session client.
|
|
14
|
+
*
|
|
15
|
+
* @privateRemarks
|
|
16
|
+
* This represents what is commonly `clientId` in Fluid code. Ideally this is
|
|
17
|
+
* moved somewhere more central and we brand it to avoid confusion with other
|
|
18
|
+
* strings. Branding broadly is likely a breaking change and may take decent
|
|
19
|
+
* effort to manage.
|
|
20
|
+
*
|
|
21
|
+
* @alpha
|
|
22
|
+
*/
|
|
23
|
+
export type ClientConnectionId = string;
|
|
24
|
+
//# sourceMappingURL=baseTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseTypes.d.ts","sourceRoot":"","sources":["../src/baseTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC"}
|
package/lib/baseTypes.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseTypes.js","sourceRoot":"","sources":["../src/baseTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * A Fluid client connection identifier.\n *\n * @remarks\n * Each client connection is given a unique identifier for the duration of the\n * connection. If a client disconnects and reconnects, it will be given a new\n * identifier. Prefer use of {@link ISessionClient} as a way to identify clients\n * in a session. {@link ISessionClient.getConnectionId} will provide the current\n * connection identifier for a logical session client.\n *\n * @privateRemarks\n * This represents what is commonly `clientId` in Fluid code. Ideally this is\n * moved somewhere more central and we brand it to avoid confusion with other\n * strings. Branding broadly is likely a breaking change and may take decent\n * effort to manage.\n *\n * @alpha\n */\nexport type ClientConnectionId = string;\n"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import type { JsonDeserialized, JsonSerializable } from "@fluidframework/presence/internal/core-interfaces";
|
|
6
|
+
/**
|
|
7
|
+
* While connected, the id of a client within a session.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export type ClientConnectionId = string;
|
|
12
|
+
/**
|
|
13
|
+
* Common interface between incoming and outgoing extension signals.
|
|
14
|
+
*
|
|
15
|
+
* @sealed
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export interface IExtensionMessage<TType extends string = string, TContent = unknown> {
|
|
19
|
+
/**
|
|
20
|
+
* Message type
|
|
21
|
+
*/
|
|
22
|
+
type: TType;
|
|
23
|
+
/**
|
|
24
|
+
* Message content
|
|
25
|
+
*/
|
|
26
|
+
content: JsonDeserialized<TContent>;
|
|
27
|
+
/**
|
|
28
|
+
* The client ID that submitted the message.
|
|
29
|
+
* For server generated messages the clientId will be null.
|
|
30
|
+
*/
|
|
31
|
+
clientId: ClientConnectionId | null;
|
|
32
|
+
/**
|
|
33
|
+
* Client ID of the singular client the message is being (or has been) sent to.
|
|
34
|
+
* May only be specified when IConnect.supportedFeatures['submit_signals_v2'] is true, will throw otherwise.
|
|
35
|
+
*/
|
|
36
|
+
targetClientId?: ClientConnectionId;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Defines requirements for a component to register with container as an extension.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export interface IContainerExtension<TContext extends unknown[]> {
|
|
44
|
+
/**
|
|
45
|
+
* Notifies the extension of a new use context.
|
|
46
|
+
*
|
|
47
|
+
* @param context - Context new reference to extension is acquired within
|
|
48
|
+
*/
|
|
49
|
+
onNewContext(...context: TContext): void;
|
|
50
|
+
/**
|
|
51
|
+
* Callback for signal sent by this extension.
|
|
52
|
+
*
|
|
53
|
+
* @param address - Address of the signal
|
|
54
|
+
* @param signal - Signal content and metadata
|
|
55
|
+
* @param local - True if signal was sent by this client
|
|
56
|
+
*/
|
|
57
|
+
processSignal?(address: string, signal: IExtensionMessage, local: boolean): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Defines the runtime interface an extension may access.
|
|
61
|
+
* In most cases this is a subset of {@link @fluidframework/container-runtime-definitions#IContainerRuntime}.
|
|
62
|
+
*
|
|
63
|
+
* @sealed
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
export interface IExtensionRuntime {
|
|
67
|
+
/**
|
|
68
|
+
* {@inheritdoc @fluidframework/container-runtime-definitions#IContainerRuntime.clientId}
|
|
69
|
+
*/
|
|
70
|
+
get clientId(): ClientConnectionId | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Submits a signal to be sent to other clients.
|
|
73
|
+
* @param address - Custom address for the signal.
|
|
74
|
+
* @param type - Custom type of the signal.
|
|
75
|
+
* @param content - Custom content of the signal. Should be a JSON serializable object or primitive via {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify|JSON.stringify}.
|
|
76
|
+
* @param targetClientId - When specified, the signal is only sent to the provided client id.
|
|
77
|
+
*
|
|
78
|
+
* Upon receipt of signal, {@link IContainerExtension.processSignal} will be called with the same
|
|
79
|
+
* address, type, and content (less any non-{@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify|JSON.stringify}-able data).
|
|
80
|
+
*/
|
|
81
|
+
submitAddressedSignal<T>(address: string, type: string, content: JsonSerializable<T>, targetClientId?: ClientConnectionId): void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Factory method to create an extension instance.
|
|
85
|
+
*
|
|
86
|
+
* Any such method provided to {@link ContainerExtensionStore.acquireExtension}
|
|
87
|
+
* must use the same value for a given {@link ContainerExtensionId} so that an
|
|
88
|
+
* `instanceof` check may be performed at runtime.
|
|
89
|
+
*
|
|
90
|
+
* @typeParam T - Type of extension to create
|
|
91
|
+
* @typeParam TContext - Array of optional custom context
|
|
92
|
+
*
|
|
93
|
+
* @param runtime - Runtime for extension to work against
|
|
94
|
+
* @param context - Custom context for extension.
|
|
95
|
+
* @returns Record providing:
|
|
96
|
+
* `interface` instance (type `T`) that is provided to caller of
|
|
97
|
+
* {@link ContainerExtensionStore.acquireExtension} and
|
|
98
|
+
* `extension` store/runtime uses to interact with extension.
|
|
99
|
+
*
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
export type ContainerExtensionFactory<T, TContext extends unknown[]> = new (runtime: IExtensionRuntime, ...context: TContext) => {
|
|
103
|
+
readonly interface: T;
|
|
104
|
+
readonly extension: IContainerExtension<TContext>;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Unique identifier for extension
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* A string known to all clients working with a certain ContainerExtension and unique
|
|
111
|
+
* among ContainerExtensions. Not `/` may be used in the string. Recommend using
|
|
112
|
+
* concatenation of: type of unique identifier, `:` (required), and unique identifier.
|
|
113
|
+
*
|
|
114
|
+
* @example Examples
|
|
115
|
+
* ```typescript
|
|
116
|
+
* "guid:g0fl001d-1415-5000-c00l-g0fa54g0b1g1"
|
|
117
|
+
* "name:@foo-scope_bar:v1"
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
export type ContainerExtensionId = `${string}:${string}`;
|
|
123
|
+
/**
|
|
124
|
+
* @sealed
|
|
125
|
+
* @internal
|
|
126
|
+
*/
|
|
127
|
+
export interface ContainerExtensionStore {
|
|
128
|
+
/**
|
|
129
|
+
* Acquires an extension from store or adds new one.
|
|
130
|
+
*
|
|
131
|
+
* @param id - Identifier for the requested extension
|
|
132
|
+
* @param factory - Factory to create the extension if not found
|
|
133
|
+
* @returns The extension
|
|
134
|
+
*/
|
|
135
|
+
acquireExtension<T, TContext extends unknown[]>(id: ContainerExtensionId, factory: ContainerExtensionFactory<T, TContext>, ...context: TContext): T;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=containerExtensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"containerExtensions.d.ts","sourceRoot":"","sources":["../../src/container-definitions/containerExtensions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,mDAAmD,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,QAAQ,GAAG,OAAO;IACnF;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC;IAEZ;;OAEG;IACH,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAEpC;;;OAGG;IAEH,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAEpC;;;OAGG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB,CAAC,QAAQ,SAAS,OAAO,EAAE;IAC9D;;;;OAIG;IACH,YAAY,CAAC,GAAG,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEzC;;;;;;OAMG;IACH,aAAa,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACjF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IACjC;;OAEG;IACH,IAAI,QAAQ,IAAI,kBAAkB,GAAG,SAAS,CAAC;IAE/C;;;;;;;;;OASG;IACH,qBAAqB,CAAC,CAAC,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC5B,cAAc,CAAC,EAAE,kBAAkB,GACjC,IAAI,CAAC;CACR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,yBAAyB,CAAC,CAAC,EAAE,QAAQ,SAAS,OAAO,EAAE,IAAI,KACtE,OAAO,EAAE,iBAAiB,EAC1B,GAAG,OAAO,EAAE,QAAQ,KAChB;IAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAA;CAAE,CAAC;AAElF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,oBAAoB,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,EAAE,QAAQ,SAAS,OAAO,EAAE,EAC7C,EAAE,EAAE,oBAAoB,EACxB,OAAO,EAAE,yBAAyB,CAAC,CAAC,EAAE,QAAQ,CAAC,EAC/C,GAAG,OAAO,EAAE,QAAQ,GAClB,CAAC,CAAC;CACL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"containerExtensions.js","sourceRoot":"","sources":["../../src/container-definitions/containerExtensions.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/presence/internal/core-interfaces\";\n\n/**\n * While connected, the id of a client within a session.\n *\n * @internal\n */\nexport type ClientConnectionId = string;\n\n/**\n * Common interface between incoming and outgoing extension signals.\n *\n * @sealed\n * @internal\n */\nexport interface IExtensionMessage<TType extends string = string, TContent = unknown> {\n\t/**\n\t * Message type\n\t */\n\ttype: TType;\n\n\t/**\n\t * Message content\n\t */\n\tcontent: JsonDeserialized<TContent>;\n\n\t/**\n\t * The client ID that submitted the message.\n\t * For server generated messages the clientId will be null.\n\t */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tclientId: ClientConnectionId | null;\n\n\t/**\n\t * Client ID of the singular client the message is being (or has been) sent to.\n\t * May only be specified when IConnect.supportedFeatures['submit_signals_v2'] is true, will throw otherwise.\n\t */\n\ttargetClientId?: ClientConnectionId;\n}\n\n/**\n * Defines requirements for a component to register with container as an extension.\n *\n * @internal\n */\nexport interface IContainerExtension<TContext extends unknown[]> {\n\t/**\n\t * Notifies the extension of a new use context.\n\t *\n\t * @param context - Context new reference to extension is acquired within\n\t */\n\tonNewContext(...context: TContext): void;\n\n\t/**\n\t * Callback for signal sent by this extension.\n\t *\n\t * @param address - Address of the signal\n\t * @param signal - Signal content and metadata\n\t * @param local - True if signal was sent by this client\n\t */\n\tprocessSignal?(address: string, signal: IExtensionMessage, local: boolean): void;\n}\n\n/**\n * Defines the runtime interface an extension may access.\n * In most cases this is a subset of {@link @fluidframework/container-runtime-definitions#IContainerRuntime}.\n *\n * @sealed\n * @internal\n */\nexport interface IExtensionRuntime {\n\t/**\n\t * {@inheritdoc @fluidframework/container-runtime-definitions#IContainerRuntime.clientId}\n\t */\n\tget clientId(): ClientConnectionId | undefined;\n\n\t/**\n\t * Submits a signal to be sent to other clients.\n\t * @param address - Custom address for the signal.\n\t * @param type - Custom type of the signal.\n\t * @param content - Custom content of the signal. Should be a JSON serializable object or primitive via {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify|JSON.stringify}.\n\t * @param targetClientId - When specified, the signal is only sent to the provided client id.\n\t *\n\t * Upon receipt of signal, {@link IContainerExtension.processSignal} will be called with the same\n\t * address, type, and content (less any non-{@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify|JSON.stringify}-able data).\n\t */\n\tsubmitAddressedSignal<T>(\n\t\taddress: string,\n\t\ttype: string,\n\t\tcontent: JsonSerializable<T>,\n\t\ttargetClientId?: ClientConnectionId,\n\t): void;\n}\n\n/**\n * Factory method to create an extension instance.\n *\n * Any such method provided to {@link ContainerExtensionStore.acquireExtension}\n * must use the same value for a given {@link ContainerExtensionId} so that an\n * `instanceof` check may be performed at runtime.\n *\n * @typeParam T - Type of extension to create\n * @typeParam TContext - Array of optional custom context\n *\n * @param runtime - Runtime for extension to work against\n * @param context - Custom context for extension.\n * @returns Record providing:\n * `interface` instance (type `T`) that is provided to caller of\n * {@link ContainerExtensionStore.acquireExtension} and\n * `extension` store/runtime uses to interact with extension.\n *\n * @internal\n */\nexport type ContainerExtensionFactory<T, TContext extends unknown[]> = new (\n\truntime: IExtensionRuntime,\n\t...context: TContext\n) => { readonly interface: T; readonly extension: IContainerExtension<TContext> };\n\n/**\n * Unique identifier for extension\n *\n * @remarks\n * A string known to all clients working with a certain ContainerExtension and unique\n * among ContainerExtensions. Not `/` may be used in the string. Recommend using\n * concatenation of: type of unique identifier, `:` (required), and unique identifier.\n *\n * @example Examples\n * ```typescript\n * \"guid:g0fl001d-1415-5000-c00l-g0fa54g0b1g1\"\n * \"name:@foo-scope_bar:v1\"\n * ```\n *\n * @internal\n */\nexport type ContainerExtensionId = `${string}:${string}`;\n\n/**\n * @sealed\n * @internal\n */\nexport interface ContainerExtensionStore {\n\t/**\n\t * Acquires an extension from store or adds new one.\n\t *\n\t * @param id - Identifier for the requested extension\n\t * @param factory - Factory to create the extension if not found\n\t * @returns The extension\n\t */\n\tacquireExtension<T, TContext extends unknown[]>(\n\t\tid: ContainerExtensionId,\n\t\tfactory: ContainerExtensionFactory<T, TContext>,\n\t\t...context: TContext\n\t): T;\n}\n"]}
|