anear-js-api 0.3.33 → 0.3.35

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.
@@ -1,7 +1,6 @@
1
1
  "use strict"
2
2
  const Ably = require('ably/promises')
3
3
  const AnearApi = require('../api/AnearApi')
4
- const ParticipantTimer = require('../utils/ParticipantTimer')
5
4
  const logger = require('../utils/Logger')
6
5
 
7
6
  const AppId = process.env.ANEARAPP_APP_ID
@@ -51,7 +50,6 @@ class AnearMessaging {
51
50
  }
52
51
 
53
52
  this.eventChannels = {}
54
- this.participantTimers = {}
55
53
 
56
54
  this.initRealtime(clientOptions)
57
55
  }
@@ -83,75 +81,6 @@ class AnearMessaging {
83
81
  return this.realtime.channels.get(channelName, channelParams)
84
82
  }
85
83
 
86
- ensureParticipantTimer(anearEvent, participant, timeoutMsecs) {
87
- // this is called when a new timer is being started for a privateMessage
88
- // sent to a participant, or public message to all participants
89
- // If the timer already exists and is paused, it is resumed with the timeRemaining
90
- // [a starter function, timeRemaining] is returned
91
- let timeRemaining = timeoutMsecs
92
- let timerStarter = () => {}
93
-
94
- if (timeoutMsecs > 0) {
95
- const timer = this.participantTimers[participant.id] || this.createTimer(anearEvent, participant, timeoutMsecs)
96
-
97
- if (timer.isRunning) {
98
- timeRemaining = timer.interrupt()
99
- } else {
100
- timerStarter = () => timer.start(timeoutMsecs)
101
- }
102
- }
103
- logger.debug(`ensureParticipantTimer(timeRemaining: ${timeRemaining})`)
104
-
105
- return [timerStarter, timeRemaining]
106
- }
107
-
108
- createTimer(anearEvent, participant, timeoutMsecs) {
109
- const timer = new ParticipantTimer(
110
- participant.id,
111
- async () => await this.timerExpired(anearEvent, participant, timeoutMsecs)
112
- )
113
- this.participantTimers[participant.id] = timer
114
-
115
- return timer
116
- }
117
-
118
- destroyParticipantTimer(participantId) {
119
- // participant will not be receiving any more display messages
120
- // so we close out and delete the ParticipantTimer
121
- const timer = this.participantTimers[participantId]
122
-
123
- if (timer) {
124
- timer.reset()
125
- delete this.participantTimers[participantId]
126
- }
127
- }
128
-
129
- resetAllParticipantTimers() {
130
- // turns off all participant timers
131
- Object.values(this.participantTimers).forEach(timer => timer.reset())
132
- }
133
-
134
- interruptParticipantTimer(participantId) {
135
- const timer = this.participantTimers[participantId]
136
-
137
- if (timer && timer.isRunning) timer.interrupt()
138
- }
139
-
140
- resetParticipantTimer(participantId) {
141
- // called after participant takes Action before timer expires
142
- const timer = this.participantTimers[participantId]
143
- if (timer) timer.reset()
144
- }
145
-
146
- async timerExpired(anearEvent, participant, timeoutMsecs) {
147
- logger.debug(`participant (${anearEvent.id}, ${participant.id}) TIMED OUT after ${timeoutMsecs} msecs`)
148
-
149
- delete this.participantTimers[participant.id]
150
-
151
- await anearEvent.participantTimedOut(participant)
152
- await anearEvent.update()
153
- }
154
-
155
84
  async getAnearEventFromStorage(eventId) {
156
85
  return await this.AnearEventClass.getFromStorage(eventId, this.AnearParticipantClass, this)
157
86
  }
@@ -213,7 +142,7 @@ class AnearMessaging {
213
142
  let loadedEvent = anearEvent
214
143
 
215
144
  if (!eventExists) {
216
- await anearEvent.runExclusive("createEventCallback", async () => {
145
+ await anearEvent.runExclusive(`createEventCallback ${anearEvent.id}`, async () => {
217
146
  await anearEvent.createdEventCallback()
218
147
  await anearEvent.persist()
219
148
  // start the state machine before initialiing Realtime Messaging
@@ -247,6 +176,8 @@ class AnearMessaging {
247
176
  const anearEvent = new this.AnearEventClass(eventJson, this.AnearParticipantClass, this)
248
177
  // This needs work!!
249
178
  // loadedEvent = await this.getAnearEventFromStorage(anearEvent.id)
179
+ // NOTE: there should be existing presence state to read from action channel
180
+ // to drive this...not a reload from storage
250
181
  // await this.refreshActiveParticipants(loadedEvent)
251
182
  // await this.initEventRealtimeMessaging(loadedEvent)
252
183
  // loadedEvent.startStateMachine()
@@ -260,7 +191,7 @@ class AnearMessaging {
260
191
 
261
192
  async refreshActiveParticipants(anearEvent) {
262
193
  await this.participants.reloadFromStorage(
263
- p => this.processParticipantEnter(anearEvent, p.id, p.geoLocation)
194
+ p => this.processParticipantEnter(anearEvent, p.id)
264
195
  )
265
196
  }
266
197
 
@@ -397,7 +328,7 @@ class AnearMessaging {
397
328
  await this.processParticipantEnter(anearEvent, participantId, geoLocation)
398
329
  }
399
330
 
400
- async processParticipantEnter(anearEvent, participantId, geoLocation) {
331
+ async processParticipantEnter(anearEvent, participantId, geoLocation = null) {
401
332
 
402
333
  logger.debug(`processing Participant Enter for event: ${anearEvent.id}, participant: ${participantId}`)
403
334
  //
@@ -409,15 +340,15 @@ class AnearMessaging {
409
340
  const participantJson = await this.api.getEventParticipantJson(participantId)
410
341
  const participant = new this.AnearParticipantClass(participantJson, anearEvent)
411
342
 
412
- participant.geoLocation = geoLocation // stored in-memory only
413
-
414
343
  const persistedAnearParticipant = await this.getAnearParticipantFromStorage(participantId, anearEvent)
415
344
 
416
345
  if (persistedAnearParticipant) {
417
346
  participant.context = persistedAnearParticipant.context
418
347
  }
419
348
 
420
- await anearEvent.runExclusive("participantEnterCallback", async () => {
349
+ await anearEvent.runExclusive(`participantEnterCallback ${participant.id}`, async () => {
350
+ participant.geoLocation = geoLocation
351
+
421
352
  await this.setupPrivatePublishingChannel(participant)
422
353
  await anearEvent.participantEnter(participant)
423
354
  await anearEvent.update()
@@ -444,13 +375,15 @@ class AnearMessaging {
444
375
  }
445
376
 
446
377
  async participantLeaveMessagingCallback(anearEvent, message) {
447
- // this can be just a temporary leave (a participant refreshing their browser for example), so pause any participant timers
378
+ // this can be just a temporary leave (a participant refreshing their browser for example),
379
+ // so pause any participant timers
448
380
  const userId = message.clientId
449
381
  const participantId = message.data.id
382
+ const participant = anearEvent.participants.getById(participantId)
450
383
 
451
- logger.debug(`**** LEAVE PARTICIPANT **** participantLeaveMessagingCallback(participant: ${participantId})`)
384
+ logger.debug(`**** LEAVE PARTICIPANT **** participantLeaveMessagingCallback(participant: ${participant.id})`)
452
385
 
453
- this.interruptParticipantTimer(participantId)
386
+ participant.interruptTimer()
454
387
  }
455
388
 
456
389
  async closeParticipant(anearEvent, participantId, callback = null) {
@@ -460,14 +393,14 @@ class AnearMessaging {
460
393
  // and cleaning out any remaining participants.
461
394
  logger.debug(`closeParticipant(${participantId})`)
462
395
 
463
- this.destroyParticipantTimer(participantId)
464
-
465
- const participant = await this.getAnearParticipantFromStorage(participantId, anearEvent)
396
+ const participant = anearEvent.participants.getById(participantId)
466
397
 
467
398
  if (participant) {
399
+ participant.destroyTimer()
400
+
468
401
  await this.detachParticipantPrivateChannel(anearEvent.id, participant)
469
402
 
470
- await anearEvent.runExclusive("closeParticipant", async () => {
403
+ await anearEvent.runExclusive(`closeParticipant ${participant.id}`, async () => {
471
404
  if (callback) {
472
405
  await callback(anearEvent, participant)
473
406
  }
@@ -499,16 +432,16 @@ class AnearMessaging {
499
432
  const participantId = message.data.participantId
500
433
  const payload = message.data.payload
501
434
 
502
- this.resetParticipantTimer(participantId) // participant responded in time, reset any running timer
435
+ const participant = anearEvent.participants.getById(participantId)
436
+
437
+ participant.resetTimer() // participant responded in time, reset any running timer
503
438
 
504
439
  logger.debug(`participantActionMessagingCallback(${anearEvent.id}, ${participantId})`)
505
440
 
506
441
  const actionJSON = JSON.parse(payload)
507
442
  const [actionEventName, actionPayload] = Object.entries(actionJSON)[0]
508
443
 
509
- const participant = anearEvent.participants.getById(participantId)
510
-
511
- await anearEvent.runExclusive("participantActionCallback", async () => {
444
+ await anearEvent.runExclusive(`participantActionCallback ${participant.id}`, async () => {
512
445
  await anearEvent.participantAction(participant, actionEventName, actionPayload)
513
446
  await anearEvent.update()
514
447
  await participant.update()
@@ -579,14 +512,14 @@ class AnearMessaging {
579
512
  )
580
513
  }
581
514
 
582
- setMultipleParticipantTimers(anearEvent, participants, timeoutMsecs) {
515
+ setMultipleParticipantTimers(participants, timeoutMsecs) {
583
516
  if (timeoutMsecs === 0) return [() => {}, 0]
584
517
 
585
518
  const participantTimers = []
586
519
 
587
520
  participants.forEach(
588
521
  participant => {
589
- const [startTimer, _timeRemaining] = this.ensureParticipantTimer(anearEvent, participant, timeoutMsecs)
522
+ const [startTimer, _timeRemaining] = participant.ensureTimer(timeoutMsecs)
590
523
  participantTimers.push(startTimer)
591
524
  }
592
525
  )
@@ -598,7 +531,7 @@ class AnearMessaging {
598
531
  const eventId = anearEvent.id
599
532
  const channel = this.eventChannels[eventId].participants
600
533
 
601
- const [startTimers, timeRemaining] = this.setMultipleParticipantTimers(eventId, participants, timeoutMsecs)
534
+ const [startTimers, timeRemaining] = this.setMultipleParticipantTimers(participants, timeoutMsecs)
602
535
 
603
536
  await this.publishMessage(
604
537
  channel,
@@ -623,7 +556,7 @@ class AnearMessaging {
623
556
  const channel = this.eventChannels[anearEvent.id].privates[userId]
624
557
  if (!channel) throw new Error(`private channel not found. invalid user id ${userId}`)
625
558
 
626
- const [startTimer, timeRemaining] = this.ensureParticipantTimer(anearEvent, participant, timeoutMsecs)
559
+ const [startTimer, timeRemaining] = participant.ensureTimer(timeoutMsecs)
627
560
 
628
561
  await this.publishMessage(
629
562
  channel,
@@ -1,11 +1,16 @@
1
1
  "use strict"
2
+
2
3
  const JsonApiResource = require('./JsonApiResource')
4
+ const ParticipantTimer = require('../utils/ParticipantTimer')
5
+ const logger = require('../utils/Logger')
6
+
3
7
  const HostUserType = "host"
4
8
 
5
9
  class AnearParticipant extends JsonApiResource {
6
10
  constructor(json, anearEvent) {
7
11
  super(json)
8
12
  this.anearEvent = anearEvent
13
+ this.timer = null
9
14
  this._state = json.state
10
15
  this._timestamp = json.timestamp
11
16
  this._geoLocation = null
@@ -78,6 +83,59 @@ class AnearParticipant extends JsonApiResource {
78
83
  get privateChannelName() {
79
84
  return this.attributes['private-channel-name']
80
85
  }
86
+
87
+ ensureTimer(timeoutMsecs) {
88
+ // this is called when a new timer is being started for a privateMessage
89
+ // sent to a participant, or public message to all participants
90
+ // If the timer already exists and is paused, it is resumed with the timeRemaining
91
+ // [a starter function, timeRemaining] is returned
92
+ let timeRemaining = timeoutMsecs
93
+ let timerStarter = () => {}
94
+
95
+ if (timeoutMsecs > 0) {
96
+
97
+ this.timer ||= new ParticipantTimer(
98
+ this.id,
99
+ async () => await this.timerExpired(timeoutMsecs)
100
+ )
101
+
102
+ if (this.timer.isRunning) {
103
+ timeRemaining = this.timer.interrupt()
104
+ } else {
105
+ timerStarter = () => this.timer.start(timeoutMsecs)
106
+ }
107
+ }
108
+ logger.debug(`ensureTimer(timeRemaining: ${timeRemaining})`)
109
+
110
+ return [timerStarter, timeRemaining]
111
+ }
112
+
113
+ destroyTimer() {
114
+ // participant will not be receiving any more display messages
115
+ // so we close out and delete the timer
116
+ if (this.timer) {
117
+ this.timer.reset()
118
+ this.timer = null
119
+ }
120
+ }
121
+
122
+ async timerExpired(timeoutMsecs) {
123
+ logger.debug(`participant (${this.anearEvent.id}, ${this.id}) TIMED OUT after ${timeoutMsecs} msecs`)
124
+
125
+ this.timer = null
126
+
127
+ await this.anearEvent.participantTimedOut(this)
128
+ await this.anearEvent.update()
129
+ }
130
+
131
+ interruptTimer() {
132
+ if (this.timer && this.timer.isRunning) this.timer.interrupt()
133
+ }
134
+
135
+ resetTimer() {
136
+ // called after participant takes Action before timer expires
137
+ if (this.timer) this.timer.reset()
138
+ }
81
139
  }
82
140
 
83
141
  module.exports = AnearParticipant
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anear-js-api",
3
- "version": "0.3.33",
3
+ "version": "0.3.35",
4
4
  "description": "Javascript Developer API for Anear Apps",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {