anear-js-api 0.3.35 → 0.3.37
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.
|
@@ -82,11 +82,7 @@ class AnearMessaging {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
async getAnearEventFromStorage(eventId) {
|
|
85
|
-
return await this.AnearEventClass.getFromStorage(eventId, this
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
async getAnearParticipantFromStorage(participantId, anearEvent) {
|
|
89
|
-
return await this.AnearParticipantClass.getFromStorage(participantId, anearEvent)
|
|
85
|
+
return await this.AnearEventClass.getFromStorage(eventId, this)
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
async initEventRealtimeMessaging(anearEvent) {
|
|
@@ -121,47 +117,41 @@ class AnearMessaging {
|
|
|
121
117
|
|
|
122
118
|
try {
|
|
123
119
|
const eventJson = JSON.parse(message.data)
|
|
124
|
-
const anearEvent = new this.AnearEventClass(eventJson, this
|
|
120
|
+
const anearEvent = new this.AnearEventClass(eventJson, this)
|
|
125
121
|
|
|
126
122
|
//
|
|
127
123
|
// if we are getting this event create message from history after a quick restart,
|
|
128
124
|
// we just return if the event already exists
|
|
129
125
|
//
|
|
130
|
-
await
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
126
|
+
const eventExists = await anearEvent.exists()
|
|
127
|
+
|
|
128
|
+
logger.info(`Event ${anearEvent.id} ${eventExists ? "already exists" : "does not exist"} in Storage`)
|
|
129
|
+
|
|
130
|
+
let loadedEvent = anearEvent
|
|
131
|
+
|
|
132
|
+
if (!eventExists) {
|
|
133
|
+
await anearEvent.runExclusive(`createEventCallback ${anearEvent.id}`, async () => {
|
|
134
|
+
await anearEvent.createdEventCallback()
|
|
135
|
+
await anearEvent.persist()
|
|
136
|
+
// start the state machine before initialiing Realtime Messaging
|
|
137
|
+
// as REFRESH events come in and the state machine should be ready
|
|
138
|
+
// to handle those XState events
|
|
139
|
+
anearEvent.startStateMachine()
|
|
140
|
+
await this.initEventRealtimeMessaging(anearEvent)
|
|
141
|
+
})
|
|
142
|
+
} else {
|
|
143
|
+
loadedEvent = await this.getAnearEventFromStorage(anearEvent.id)
|
|
144
|
+
await this.initEventRealtimeMessaging(loadedEvent)
|
|
145
|
+
loadedEvent.startStateMachine()
|
|
146
|
+
}
|
|
139
147
|
|
|
140
|
-
|
|
148
|
+
logger.info(`New ${loadedEvent.constructor.name} Event: `, loadedEvent.toJSON())
|
|
141
149
|
|
|
142
|
-
|
|
150
|
+
this.anearEvents[loadedEvent.id] = loadedEvent
|
|
143
151
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
await anearEvent.createdEventCallback()
|
|
147
|
-
await anearEvent.persist()
|
|
148
|
-
// start the state machine before initialiing Realtime Messaging
|
|
149
|
-
// as REFRESH events come in and the state machine should be ready
|
|
150
|
-
// to handle those XState events
|
|
151
|
-
anearEvent.startStateMachine()
|
|
152
|
-
await this.initEventRealtimeMessaging(anearEvent)
|
|
153
|
-
})
|
|
154
|
-
} else {
|
|
155
|
-
loadedEvent = await this.getAnearEventFromStorage(anearEvent.id)
|
|
156
|
-
await this.initEventRealtimeMessaging(loadedEvent)
|
|
157
|
-
loadedEvent.startStateMachine()
|
|
152
|
+
} catch(err) {
|
|
153
|
+
logger.error(err)
|
|
158
154
|
}
|
|
159
|
-
|
|
160
|
-
logger.info(`New ${loadedEvent.constructor.name} Event: `, loadedEvent.toJSON())
|
|
161
|
-
|
|
162
|
-
this.anearEvents[loadedEvent.id] = loadedEvent
|
|
163
|
-
|
|
164
|
-
return loadedEvent
|
|
165
155
|
}
|
|
166
156
|
|
|
167
157
|
async reloadAnyEventsInProgress(appId) {
|
|
@@ -173,14 +163,16 @@ class AnearMessaging {
|
|
|
173
163
|
|
|
174
164
|
for (const eventData of events) {
|
|
175
165
|
const eventJson = await this.api.getEvent(eventData.id)
|
|
176
|
-
const anearEvent = new this.AnearEventClass(eventJson, this
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// to
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
166
|
+
const anearEvent = new this.AnearEventClass(eventJson, this)
|
|
167
|
+
await this.initEventRealtimeMessaging(anearEvent)
|
|
168
|
+
|
|
169
|
+
const attachedParticipants = this.getPresentParticipants(anearEvent)
|
|
170
|
+
// TBD: might want to change the attach and presence logic on
|
|
171
|
+
// the actions channel. The Ably docs show subscribing to the
|
|
172
|
+
// presence events on the actions channel, and instead of using History,
|
|
173
|
+
// it does a get() to fetch all of the current members. This behavior
|
|
174
|
+
// is useful for both event start, and event restart within this function
|
|
175
|
+
// anearEvent.startStateMachine()
|
|
184
176
|
//
|
|
185
177
|
}
|
|
186
178
|
}
|
|
@@ -189,12 +181,6 @@ class AnearMessaging {
|
|
|
189
181
|
}
|
|
190
182
|
}
|
|
191
183
|
|
|
192
|
-
async refreshActiveParticipants(anearEvent) {
|
|
193
|
-
await this.participants.reloadFromStorage(
|
|
194
|
-
p => this.processParticipantEnter(anearEvent, p.id)
|
|
195
|
-
)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
184
|
async setupCreateEventChannel() {
|
|
199
185
|
logger.info(`attaching to channel ${AnearCreateEventChannelName}`)
|
|
200
186
|
|
|
@@ -242,6 +228,13 @@ class AnearMessaging {
|
|
|
242
228
|
return members.length
|
|
243
229
|
}
|
|
244
230
|
|
|
231
|
+
async getPresentParticipants(anearEvent) {
|
|
232
|
+
// returns the participant presence data for each member who is present on
|
|
233
|
+
// the event's actions channel
|
|
234
|
+
const channel = this.eventChannels[anearEvent.id].actions
|
|
235
|
+
return await channel.presence.get()
|
|
236
|
+
}
|
|
237
|
+
|
|
245
238
|
async setupActionsChannel(anearEvent) {
|
|
246
239
|
const actionsChannel = this.getChannel(anearEvent.actionsChannelName())
|
|
247
240
|
|
|
@@ -340,7 +333,7 @@ class AnearMessaging {
|
|
|
340
333
|
const participantJson = await this.api.getEventParticipantJson(participantId)
|
|
341
334
|
const participant = new this.AnearParticipantClass(participantJson, anearEvent)
|
|
342
335
|
|
|
343
|
-
const persistedAnearParticipant = await this.
|
|
336
|
+
const persistedAnearParticipant = await this.AnearParticipantClass.getFromStorage(participantId, anearEvent)
|
|
344
337
|
|
|
345
338
|
if (persistedAnearParticipant) {
|
|
346
339
|
participant.context = persistedAnearParticipant.context
|
|
@@ -375,15 +368,12 @@ class AnearMessaging {
|
|
|
375
368
|
}
|
|
376
369
|
|
|
377
370
|
async participantLeaveMessagingCallback(anearEvent, message) {
|
|
378
|
-
// this can be just a temporary leave
|
|
379
|
-
//
|
|
371
|
+
// this can be just a temporary leave from a participant refreshing their browser.
|
|
372
|
+
// currently, no action taken
|
|
380
373
|
const userId = message.clientId
|
|
381
374
|
const participantId = message.data.id
|
|
382
|
-
const participant = anearEvent.participants.getById(participantId)
|
|
383
|
-
|
|
384
|
-
logger.debug(`**** LEAVE PARTICIPANT **** participantLeaveMessagingCallback(participant: ${participant.id})`)
|
|
385
375
|
|
|
386
|
-
|
|
376
|
+
logger.debug(`**** LEAVE PARTICIPANT **** participantLeaveMessagingCallback(participant: ${participantId})`)
|
|
387
377
|
}
|
|
388
378
|
|
|
389
379
|
async closeParticipant(anearEvent, participantId, callback = null) {
|
package/lib/models/AnearEvent.js
CHANGED
|
@@ -13,11 +13,10 @@ const PrivateDisplayMessageType = 'private_display'
|
|
|
13
13
|
|
|
14
14
|
class AnearEvent extends JsonApiResource {
|
|
15
15
|
|
|
16
|
-
constructor(json,
|
|
16
|
+
constructor(json, messaging) {
|
|
17
17
|
super(json)
|
|
18
18
|
this.zone = this.findIncluded(this.relationships.zone)
|
|
19
19
|
this.app = this.findIncluded(this.zone.relationships.app)
|
|
20
|
-
this.anearParticipantClass = anearParticipantClass
|
|
21
20
|
this.messaging = messaging
|
|
22
21
|
this.anearStateMachine = this.initStateMachine(json.previousState)
|
|
23
22
|
this.participants = new Participants(this, json.participants)
|
|
@@ -256,10 +255,6 @@ class AnearEvent extends JsonApiResource {
|
|
|
256
255
|
this.anearStateMachine.sendTimeoutEvent({ participant })
|
|
257
256
|
}
|
|
258
257
|
|
|
259
|
-
cancelParticipantTimers() {
|
|
260
|
-
this.messaging.resetAllParticipantTimers()
|
|
261
|
-
}
|
|
262
|
-
|
|
263
258
|
async eventBroadcast(message) {
|
|
264
259
|
await this.eventBroadcastEventCallback(message)
|
|
265
260
|
}
|
|
@@ -339,14 +334,6 @@ class AnearEvent extends JsonApiResource {
|
|
|
339
334
|
)
|
|
340
335
|
}
|
|
341
336
|
|
|
342
|
-
async reloadParticipantsFromStorage() {
|
|
343
|
-
// rehydrate the anearEvent participants and host from storage
|
|
344
|
-
const participants = await Promise.all(
|
|
345
|
-
this.participants.ids.map(pid => this.anearParticipantClass.getFromStorage(pid, this))
|
|
346
|
-
)
|
|
347
|
-
this.participants.load(participants)
|
|
348
|
-
}
|
|
349
|
-
|
|
350
337
|
eventChannelName () {
|
|
351
338
|
return this.getChannelName('event')
|
|
352
339
|
}
|
package/package.json
CHANGED
package/tests/AnearEvent.test.js
CHANGED
|
@@ -331,11 +331,13 @@ test('can be retrieved back from storage with participants, not hosted', async (
|
|
|
331
331
|
await testEvent.participantEnter(p2)
|
|
332
332
|
await testEvent.persist()
|
|
333
333
|
|
|
334
|
-
const rehydratedTestEvent = await TestEvent.getFromStorage(testEvent.id,
|
|
335
|
-
await rehydratedTestEvent.reloadParticipantsFromStorage()
|
|
334
|
+
const rehydratedTestEvent = await TestEvent.getFromStorage(testEvent.id, MessagingStub)
|
|
336
335
|
|
|
337
336
|
rehydratedTestEvent.startStateMachine()
|
|
338
337
|
|
|
338
|
+
await rehydratedTestEvent.participantEnter(p1)
|
|
339
|
+
await rehydratedTestEvent.participantEnter(p2)
|
|
340
|
+
|
|
339
341
|
expect(rehydratedTestEvent.participants.numActive).toBe(2)
|
|
340
342
|
expect(rehydratedTestEvent.id).toBe(testEvent.id)
|
|
341
343
|
expect(rehydratedTestEvent.relationships['user'].data.type).toBe("users")
|
|
@@ -382,23 +384,3 @@ test('can update state machine context via Action events', async () => {
|
|
|
382
384
|
await t.closeOutParticipants()
|
|
383
385
|
await t.remove()
|
|
384
386
|
})
|
|
385
|
-
|
|
386
|
-
test('can reset All ParticipantTimers', async () => {
|
|
387
|
-
const t = newTestEvent(false)
|
|
388
|
-
const p1 = new TestPlayer(chatParticipant1, t)
|
|
389
|
-
const p2 = new TestPlayer(chatParticipant2, t)
|
|
390
|
-
|
|
391
|
-
const resetMock = jest.spyOn(MessagingStub, "resetAllParticipantTimers");
|
|
392
|
-
|
|
393
|
-
await t.participantEnter(p1)
|
|
394
|
-
await t.participantEnter(p2)
|
|
395
|
-
await t.persist()
|
|
396
|
-
|
|
397
|
-
t.cancelParticipantTimers()
|
|
398
|
-
|
|
399
|
-
expect(resetMock).toHaveBeenCalledTimes(1)
|
|
400
|
-
|
|
401
|
-
await t.participantExit(p1)
|
|
402
|
-
await t.participantExit(p2)
|
|
403
|
-
await t.remove()
|
|
404
|
-
})
|