anear-js-api 0.5.6 → 0.5.7

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.
@@ -106,7 +106,7 @@ const ActiveEventGlobalEvents = {
106
106
  target: '#canceled'
107
107
  },
108
108
  APPM_FINAL: {
109
- // AppM reached a root-level final → cleanup only (no ANAPI transition)
109
+ actions: ['logImplicitShutdownWarning'],
110
110
  target: '#activeEvent.shutdownOnly'
111
111
  }
112
112
  }
@@ -329,6 +329,15 @@ const ActiveEventStatesConfig = {
329
329
  RENDER_DISPLAY: {
330
330
  target: '#announceRendering'
331
331
  },
332
+ PARTICIPANT_UPDATE: [
333
+ {
334
+ cond: 'isReconnectUpdate',
335
+ actions: 'processReconnectEvents'
336
+ },
337
+ {
338
+ actions: ['updateParticipantGeoLocation', 'processUpdateEvents']
339
+ }
340
+ ],
332
341
  PARTICIPANT_LEAVE: [
333
342
  {
334
343
  cond: 'isPermanentLeave',
@@ -448,6 +457,15 @@ const ActiveEventStatesConfig = {
448
457
  RENDER_DISPLAY: {
449
458
  target: '#liveRendering'
450
459
  },
460
+ PARTICIPANT_UPDATE: [
461
+ {
462
+ cond: 'isReconnectUpdate',
463
+ actions: 'processReconnectEvents'
464
+ },
465
+ {
466
+ actions: ['updateParticipantGeoLocation', 'processUpdateEvents']
467
+ }
468
+ ],
451
469
  PARTICIPANT_LEAVE: [
452
470
  {
453
471
  cond: 'isPermanentLeave',
@@ -607,13 +625,30 @@ const ActiveEventStatesConfig = {
607
625
  closeEvent: {
608
626
  id: 'closeEvent',
609
627
  initial: 'notifyingParticipants',
628
+ on: {
629
+ APPM_FINAL: {
630
+ actions: () => logger.debug('[AEM] Ignoring APPM_FINAL during closeEvent.')
631
+ }
632
+ },
610
633
  states: {
611
634
  notifyingParticipants: {
612
635
  entry: 'sendParticipantExitEvents',
613
- always: 'waitForParticipantsToExit'
636
+ always: [
637
+ {
638
+ cond: context => getAllParticipantIds(context).length === 0,
639
+ target: 'finalizing'
640
+ },
641
+ {
642
+ target: 'waitForParticipantsToExit'
643
+ }
644
+ ]
614
645
  },
615
646
  waitForParticipantsToExit: {
616
647
  entry: context => logger.debug(`[AEM] Entering waitForParticipantsToExit with ${getAllParticipantIds(context).length} participants`),
648
+ after: {
649
+ // Wait up to 2 seconds for participants to exit cleanly, then force shutdown
650
+ 2000: 'finalizing'
651
+ },
617
652
  always: [
618
653
  {
619
654
  cond: context => getAllParticipantIds(context).length === 0,
@@ -621,9 +656,18 @@ const ActiveEventStatesConfig = {
621
656
  }
622
657
  ],
623
658
  on: {
624
- PARTICIPANT_LEAVE: {
625
- actions: () => logger.debug('[AEM] Ignoring PARTICIPANT_LEAVE during orchestrated shutdown.')
626
- }
659
+ PARTICIPANT_LEAVE: [
660
+ {
661
+ // The user has explicitly left (type: PARTICIPANT_EXIT).
662
+ // This implies they are not waiting for any game-over screen.
663
+ // Clean them up immediately without waiting.
664
+ cond: 'isPermanentLeave',
665
+ actions: ['cleanupExitingParticipant', (c, e) => logger.debug(`[AEM] Participant ${e.data.id} permanently left during closeEvent shutdown.`)]
666
+ },
667
+ {
668
+ actions: ['cleanupExitingParticipant', (c, e) => logger.debug(`[AEM] Participant ${e.data.id} left during closeEvent shutdown.`)]
669
+ }
670
+ ]
627
671
  }
628
672
  },
629
673
  finalizing: {
@@ -651,15 +695,30 @@ const ActiveEventStatesConfig = {
651
695
  on: {
652
696
  CLOSE: {
653
697
  actions: () => logger.debug('[AEM] Ignoring CLOSE during cancel.')
698
+ },
699
+ APPM_FINAL: {
700
+ actions: () => logger.debug('[AEM] Ignoring APPM_FINAL during cancel.')
654
701
  }
655
702
  },
656
703
  states: {
657
704
  notifyingParticipants: {
658
705
  entry: 'sendParticipantExitEvents',
659
- always: 'waitForParticipantsToExit'
706
+ always: [
707
+ {
708
+ cond: context => getAllParticipantIds(context).length === 0,
709
+ target: 'finalizing'
710
+ },
711
+ {
712
+ target: 'waitForParticipantsToExit'
713
+ }
714
+ ]
660
715
  },
661
716
  waitForParticipantsToExit: {
662
717
  entry: context => logger.debug(`[AEM] Entering waitForParticipantsToExit with ${getAllParticipantIds(context).length} participants`),
718
+ after: {
719
+ // Wait up to 2 seconds for participants to exit cleanly, then force shutdown
720
+ 2000: 'finalizing'
721
+ },
663
722
  always: [
664
723
  {
665
724
  cond: context => getAllParticipantIds(context).length === 0,
@@ -667,9 +726,19 @@ const ActiveEventStatesConfig = {
667
726
  }
668
727
  ],
669
728
  on: {
670
- PARTICIPANT_LEAVE: {
671
- actions: () => logger.debug('[AEM] Ignoring PARTICIPANT_LEAVE during orchestrated shutdown.')
672
- }
729
+ PARTICIPANT_LEAVE: [
730
+ {
731
+ // The user has explicitly left (type: PARTICIPANT_EXIT).
732
+ // This implies they are not waiting for any game-over screen.
733
+ // Clean them up immediately without waiting.
734
+ cond: 'isPermanentLeave',
735
+ actions: ['cleanupExitingParticipant', (c, e) => logger.debug(`[AEM] Participant ${e.data.id} permanently left during canceled shutdown.`)]
736
+ },
737
+ {
738
+ // Standard leave (e.g. disconnect). Clean them up too.
739
+ actions: ['cleanupExitingParticipant', (c, e) => logger.debug(`[AEM] Participant ${e.data.id} left during canceled shutdown.`)]
740
+ }
741
+ ]
673
742
  }
674
743
  },
675
744
  finalizing: {
@@ -697,23 +766,53 @@ const ActiveEventStatesConfig = {
697
766
  shutdownOnly: {
698
767
  id: 'shutdownOnly',
699
768
  initial: 'notifyingParticipants',
769
+ on: {
770
+ APPM_FINAL: {
771
+ actions: () => logger.debug('[AEM] Ignoring APPM_FINAL during shutdownOnly.')
772
+ }
773
+ },
700
774
  states: {
701
775
  notifyingParticipants: {
702
776
  entry: 'sendParticipantExitEvents',
703
- always: 'waitForParticipantsToExit'
777
+ always: [
778
+ {
779
+ cond: context => getAllParticipantIds(context).length === 0,
780
+ target: 'finalizing'
781
+ },
782
+ {
783
+ target: 'waitForParticipantsToExit'
784
+ }
785
+ ]
704
786
  },
705
787
  waitForParticipantsToExit: {
706
788
  entry: context => logger.debug(`[AEM] Entering waitForParticipantsToExit with ${getAllParticipantIds(context).length} participants`),
789
+ after: {
790
+ // Wait up to 2 seconds for participants to exit cleanly, then force shutdown
791
+ 2000: 'finalizing'
792
+ },
707
793
  always: [
708
794
  {
709
795
  cond: context => getAllParticipantIds(context).length === 0,
710
- target: 'detaching'
796
+ target: 'finalizing'
711
797
  }
712
798
  ],
713
799
  on: {
714
- PARTICIPANT_LEAVE: {
715
- actions: () => logger.debug('[AEM] Ignoring PARTICIPANT_LEAVE during orchestrated shutdown.')
716
- }
800
+ PARTICIPANT_LEAVE: [
801
+ {
802
+ cond: 'isPermanentLeave',
803
+ actions: ['cleanupExitingParticipant', (c, e) => logger.debug(`[AEM] Participant ${e.data.id} permanently left during shutdownOnly.`)]
804
+ },
805
+ {
806
+ actions: ['cleanupExitingParticipant', (c, e) => logger.debug(`[AEM] Participant ${e.data.id} left during shutdownOnly.`)]
807
+ }
808
+ ]
809
+ }
810
+ },
811
+ finalizing: {
812
+ invoke: {
813
+ src: 'eventTransitionCanceled',
814
+ onDone: 'detaching',
815
+ onError: '#activeEvent.failure'
717
816
  }
718
817
  },
719
818
  detaching: {
@@ -1313,6 +1412,14 @@ const AnearEventMachineFunctions = ({
1313
1412
  logCreatorEnter: (_c, event) => logger.debug("[AEM] got creator PARTICIPANT_ENTER: ", event.data.id),
1314
1413
  logAPMReady: (c, e) => logger.debug("[AEM] PARTICIPANT_MACHINE_READY for: ", e.data.anearParticipant.id),
1315
1414
  logInvalidParticipantEnter: (c, e) => logger.info("[AEM] Error: Unexepected PARTICIPANT_ENTER with id: ", e.data.id),
1415
+ logDeferringAppmFinal: (_c, _e) => logger.info("[AEM] Deferring APPM_FINAL event because AEM is already transitioning to terminated state."),
1416
+ logImplicitShutdownWarning: (_c, _e) => {
1417
+ logger.error("********************************************************************************");
1418
+ logger.error("[AEM] WARNING: AppMachine reached a 'final' state without explicitly calling anearEvent.closeEvent() or anearEvent.cancelEvent().");
1419
+ logger.error("[AEM] The event is being force-transitioned to 'canceled' to ensure cleanup.");
1420
+ logger.error("[AEM] Please update your AppMachine to invoke an explicit exit action.");
1421
+ logger.error("********************************************************************************");
1422
+ },
1316
1423
  },
1317
1424
  services: {
1318
1425
  saveAppEventContext: async (context, event) => {
@@ -181,6 +181,10 @@ const AnearParticipantMachineConfig = participantId => ({
181
181
  }
182
182
  },
183
183
  on: {
184
+ PARTICIPANT_EXIT: {
185
+ actions: 'logExit',
186
+ target: '#cleanupAndExit'
187
+ },
184
188
  ACTION: {
185
189
  actions: [
186
190
  'updateLastSeen',
@@ -206,6 +210,7 @@ const AnearParticipantMachineConfig = participantId => ({
206
210
  },
207
211
  cleanupAndExit: {
208
212
  id: 'cleanupAndExit',
213
+ entry: 'nullActionTimeout',
209
214
  // Ignore most events during cleanup, but allow exit displays
210
215
  on: {
211
216
  RENDER_DISPLAY: { actions: 'logIgnoringRenderDisplayCleanup' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anear-js-api",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "description": "Javascript Developer API for Anear Apps",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {