anear-js-api 0.6.0 → 0.6.2

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.
@@ -154,7 +154,11 @@ class AnearEvent extends JsonApiResource {
154
154
  }
155
155
 
156
156
  allowsSpectators() {
157
- return !this.hasFlag("no_spectators")
157
+ //
158
+ // Canonical spectators decision uses the ANAPI-provided boolean when present.
159
+ // Fallback to legacy negative flag for older payloads.
160
+ //
161
+ return this.attributes['spectators-allowed']
158
162
  }
159
163
 
160
164
  isParticipantEventCreator(participant) {
@@ -1087,10 +1087,21 @@ const CreateEventChannelsAndAppMachineConfig = {
1087
1087
  }
1088
1088
  },
1089
1089
  on: {
1090
- ATTACHED: {
1091
- actions: ['enableParticipantPresenceEvents', 'subscribeToActionMessages'],
1092
- target: 'setupSpectatorsChannel'
1093
- }
1090
+ ATTACHED: [
1091
+ {
1092
+ // If the event supports spectators, continue to set up the
1093
+ // spectatorsDisplayChannel and related presence callbacks.
1094
+ cond: 'eventSupportsSpectators',
1095
+ actions: ['enableParticipantPresenceEvents', 'subscribeToActionMessages'],
1096
+ target: 'setupSpectatorsChannel'
1097
+ },
1098
+ {
1099
+ // Otherwise, skip spectator channel entirely and move directly
1100
+ // to creating the AppEventMachine.
1101
+ actions: ['enableParticipantPresenceEvents', 'subscribeToActionMessages'],
1102
+ target: 'createAppEventMachine'
1103
+ }
1104
+ ]
1094
1105
  }
1095
1106
  },
1096
1107
  setupSpectatorsChannel: {
@@ -1178,12 +1189,23 @@ const AnearEventMachineFunctions = ({
1178
1189
  )
1179
1190
  }),
1180
1191
  createSpectatorsChannel: assign({
1181
- spectatorsDisplayChannel: context => RealtimeMessaging.getChannel(
1182
- context.anearEvent.spectatorsChannelName,
1183
- context.anearEvent
1184
- )
1192
+ spectatorsDisplayChannel: context => {
1193
+ const channelName = context.anearEvent.spectatorsChannelName
1194
+ if (!channelName) {
1195
+ logger.debug('[AEM] spectatorsChannelName is undefined; skipping spectators channel creation')
1196
+ return null
1197
+ }
1198
+ return RealtimeMessaging.getChannel(
1199
+ channelName,
1200
+ context.anearEvent
1201
+ )
1202
+ }
1185
1203
  }),
1186
1204
  enableSpectatorPresenceEvents: context => {
1205
+ if (!context.spectatorsDisplayChannel) {
1206
+ logger.debug('[AEM] spectatorsDisplayChannel is null; spectator presence events disabled for this event')
1207
+ return
1208
+ }
1187
1209
  // future spectators who (un)attach to the spectatorsDisplayChannel will
1188
1210
  // trigger presence events to the anearEventMachine
1189
1211
  RealtimeMessaging.enablePresenceCallbacks(
@@ -1641,6 +1663,7 @@ const AnearEventMachineFunctions = ({
1641
1663
  return { anearParticipant }
1642
1664
  },
1643
1665
  getAttachedSpectators: async (context, event) => {
1666
+ if (!context.spectatorsDisplayChannel) return []
1644
1667
  const members = await RealtimeMessaging.getPresenceOnChannel(context.spectatorsDisplayChannel)
1645
1668
  return members
1646
1669
  },
@@ -1666,6 +1689,14 @@ const AnearEventMachineFunctions = ({
1666
1689
  },
1667
1690
  transitionAndGetAttachedSpectators: async (context, event) => {
1668
1691
  const transitionPromise = AnearApi.transitionEvent(context.anearEvent.id, 'announce')
1692
+
1693
+ // If there is no spectators channel (event/app does not support spectators),
1694
+ // just transition state and return an empty spectator list.
1695
+ if (!context.spectatorsDisplayChannel) {
1696
+ await transitionPromise
1697
+ return []
1698
+ }
1699
+
1669
1700
  const membersPromise = RealtimeMessaging.getPresenceOnChannel(context.spectatorsDisplayChannel)
1670
1701
  const [_, members] = await Promise.all([transitionPromise, membersPromise])
1671
1702
  return members
@@ -1723,6 +1754,15 @@ const AnearEventMachineFunctions = ({
1723
1754
  participantExists: (context, event) => !!context.participants[event.data.id],
1724
1755
  eventCreatorIsHost: (context, _e) => context.anearEvent.hosted,
1725
1756
  isOpenHouseEvent: (context, _e) => context.anearEvent.openHouse || false,
1757
+ eventSupportsSpectators: (context, _e) => {
1758
+ try {
1759
+ // True only when ANAPI has indicated spectators are allowed for this event.
1760
+ // JSAPI AnearEvent#allowsSpectators reads the canonical spectators-allowed flag.
1761
+ return !!(context.anearEvent && context.anearEvent.allowsSpectators && context.anearEvent.allowsSpectators())
1762
+ } catch (_e) {
1763
+ return false
1764
+ }
1765
+ },
1726
1766
  isParticipantsTimeoutActive: (context, event) => {
1727
1767
  const isStartingNewTimeout = event.data && event.data.participantsTimeout && event.data.participantsTimeout.msecs > 0;
1728
1768
  const isTimeoutAlreadyRunning = context.participantsActionTimeout !== null;
@@ -176,6 +176,14 @@ class DisplayEventProcessor {
176
176
  case 'spectators':
177
177
  logger.debug(`[DisplayEventProcessor] Publishing ${viewPath} to SPECTATORS_DISPLAY`)
178
178
 
179
+ // If this event/app does not support spectators, the spectatorsDisplayChannel
180
+ // will be null. In that case, skip publishing instead of throwing.
181
+ if (!this.spectatorsDisplayChannel) {
182
+ logger.debug('[DisplayEventProcessor] spectatorsDisplayChannel is null; skipping SPECTATORS_DISPLAY publish')
183
+ publishPromise = Promise.resolve()
184
+ break
185
+ }
186
+
179
187
  // Spectators never have action timeouts; they can display a visual bar only.
180
188
  // Prefer their own configured timeout for visuals, otherwise mirror the
181
189
  // allParticipants collective timeout (remaining time) if one is running.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anear-js-api",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Javascript Developer API for Anear Apps",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {