anear-js-api 2.1.1 → 2.2.1

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,5 +1,7 @@
1
1
  # The `eachParticipant` Display Lifecycle
2
2
 
3
+ > Breaking vNext note: `AnearParticipantMachine` has been removed. `AnearEventMachine` now owns participant private channel lifecycle and `DisplayEventProcessor` publishes `PRIVATE_DISPLAY` directly to participant private channels.
4
+
3
5
  This document provides a detailed, step-by-by-step breakdown of how a display targeted at `eachParticipant` travels from the application's state machine (AppM) to an individual participant's browser client.
4
6
 
5
7
  ### The Goal
@@ -10,7 +12,7 @@ We want to render a specific view (`QuestionScreen.pug`) for a single user (`par
10
12
 
11
13
  The core idea is to translate a declarative `meta` block in your application's state machine (AppM) into concrete HTML content that gets delivered to a specific participant's device. This process involves a chain of components:
12
14
 
13
- `AppMachineTransition` -> `AnearEventMachine` -> `DisplayEventProcessor` -> `AnearParticipantMachine` -> **Ably Message**
15
+ `AppMachineTransition` -> `AnearEventMachine` -> `DisplayEventProcessor` -> **Ably Message**
14
16
 
15
17
  Let's break down each step.
16
18
 
package/README.md CHANGED
@@ -18,7 +18,7 @@ The anear-js-api abstracts away:
18
18
  - Participant presence tracking and coordination
19
19
  - Display rendering and template compilation
20
20
  - Asset management (CSS, images) and CDN uploads
21
- - Timeout management for participant actions
21
+ - Timeout orchestration for `allParticipants` action windows
22
22
  - Reconnection handling and error recovery
23
23
 
24
24
  ## Architecture
@@ -28,9 +28,7 @@ The anear-js-api abstracts away:
28
28
  ```
29
29
  AnearCoreServiceMachine (Root)
30
30
  ├── AnearEventMachine (Per Event)
31
- │ ├── AnearParticipantMachine (Per Participant)
32
31
  │ └── AppEventMachine (Developer's App Logic)
33
- └── AppParticipantMachine (Optional, Per Participant)
34
32
  ```
35
33
 
36
34
  ### Core Components
@@ -52,30 +50,26 @@ AnearCoreServiceMachine (Root)
52
50
  - Route messages between participants and app logic
53
51
  - Manage participant presence (enter/leave/exit)
54
52
  - Coordinate display rendering for all channels
55
- - Handle individual participant timeouts
53
+ - Handle allParticipants timeout orchestration
56
54
  - **Key States**: `registerCreator` → `eventCreated` → `announce` → `live` → `closeEvent`
57
55
 
58
- #### AnearParticipantMachine (APM)
59
- - **Purpose**: Manages individual participant state and private communications
60
- - **Responsibilities**:
61
- - Handle participant private channel communications
62
- - Manage participant timeouts and reconnection logic
63
- - Track participant activity and idle states
64
- - Route participant-specific actions to app logic
65
- - **Key States**: `setup` → `live` → `waitReconnect` → `cleanupAndExit`
56
+ #### Breaking vNext: APM Removed
57
+ - Participant-machine orchestration is removed from JSAPI.
58
+ - AEM now manages participant private channel lifecycle and private display publishing directly.
59
+ - JSAPI no longer emits `PARTICIPANT_TIMEOUT`; participant-local timeout UX is owned by browser runtime (`<anear-timeout>`).
66
60
 
67
61
  ### Separation of Concerns: JSAPI vs. AppM
68
62
 
69
63
  A key architectural principle is the clear separation of concerns between the Anear JSAPI (the "engine") and the App Event Machine (the "application").
70
64
 
71
- #### JSAPI (AEM & APM): The Engine Room
65
+ #### JSAPI (AEM): The Engine Room
72
66
 
73
67
  The JSAPI is responsible for all the underlying infrastructure and communication mechanics. Its concerns are purely technical:
74
68
 
75
69
  - **Event Lifecycle & State:** Manages the low-level state transitions of an event (`created` → `announce` → `live` → `closed`) and the lifecycle of participants.
76
70
  - **Real-time Communication:** Handles all Ably channel setup, messaging, presence events, and connection state.
77
71
  - **Orderly Operations:** Ensures smooth, reliable startup and shutdown of all services and participant connections.
78
- - **Notifier:** The JSAPI acts as a notifier. It informs the AppM of important events (`PARTICIPANT_ENTER`, `PARTICIPANT_DISCONNECT`, `ACTION`, `PARTICIPANT_TIMEOUT`) but does not decide what these events mean for the application.
72
+ - **Notifier:** The JSAPI acts as a notifier. It informs the AppM of important events (`PARTICIPANT_ENTER`, `PARTICIPANT_DISCONNECT`, `ACTION`, `ACTIONS_TIMEOUT`) but does not decide what these events mean for the application.
79
73
 
80
74
  #### AppM: The Application & User Experience
81
75
 
@@ -185,7 +179,6 @@ The JSAPI handles participant lifecycle through presence events:
185
179
  | `PARTICIPANT_RECONNECT` | Participant rejoins after disconnect | `HOST_RECONNECT` or `PARTICIPANT_RECONNECT` |
186
180
  | `PARTICIPANT_EXIT` | Participant permanently leaves | `HOST_EXIT` or `PARTICIPANT_EXIT` |
187
181
  | `PARTICIPANT_DISCONNECT` | Temporary connection loss | `HOST_DISCONNECT` or `PARTICIPANT_DISCONNECT` |
188
- | `PARTICIPANT_TIMEOUT` | Participant fails to respond in time | `PARTICIPANT_TIMEOUT` |
189
182
  | `ACTION` | Participant performs an action | Custom event (e.g., `MOVE`, `ANSWER`) |
190
183
 
191
184
  **Key Point**: The AEM uses role-specific events (`HOST_*` vs `PARTICIPANT_*`) based on whether the user is the event creator/host. Your AppM never needs to check `isHost` - it just reacts to the specific events it receives.
@@ -236,9 +229,9 @@ PUG templates receive rich context including:
236
229
 
237
230
  ## Timeout Management
238
231
 
239
- ### Individual Timeouts
232
+ ### Participant-local Timeouts
240
233
 
241
- For turn-based actions where each participant has their own timer:
234
+ Participant-local timeout UX is handled by browser runtime (`<anear-timeout>`). JSAPI does not emit `PARTICIPANT_TIMEOUT`.
242
235
 
243
236
  ```javascript
244
237
  meta: {
@@ -251,8 +244,7 @@ meta: {
251
244
  }
252
245
  },
253
246
  on: {
254
- MOVE: 'nextTurn',
255
- PARTICIPANT_TIMEOUT: 'handleTimeout'
247
+ MOVE: 'nextTurn'
256
248
  }
257
249
  ```
258
250
 
@@ -287,6 +279,7 @@ The JSAPI automatically handles asset management:
287
279
  1. **CSS Upload**: All CSS files in `assets/css/` are uploaded to CloudFront
288
280
  2. **Image Upload**: All images in `assets/images/` are uploaded to CloudFront
289
281
  3. **Template Preloading**: All PUG templates are preloaded and cached
282
+ 4. **Hash-based dedupe**: Asset uploads are decided by SHA-256 content hash comparison against S3 metadata (not file timestamps)
290
283
 
291
284
  ### CI-Managed Assets Mode
292
285
 
@@ -1,12 +1,12 @@
1
1
  const AnearCoreServiceMachine = require('./state_machines/AnearCoreServiceMachine')
2
2
 
3
- const AnearService = (appEventMachineFactory, appParticipantMachineFactory = null) => {
3
+ const AnearService = (appEventMachineFactory) => {
4
4
  //
5
5
  // developer provides appEventMachineFactory:
6
6
  //
7
7
  // appEventMachineFactory = anearEvent => { returns XState Machine) }
8
- // optional appParticipantMachineFactory = anearParticipant => { returns XState Machine) }
8
+ // participant-level machines are no longer managed by JSAPI.
9
9
  //
10
- return AnearCoreServiceMachine(appEventMachineFactory, appParticipantMachineFactory)
10
+ return AnearCoreServiceMachine(appEventMachineFactory)
11
11
  }
12
12
  module.exports = AnearService
@@ -111,10 +111,8 @@ class AnearEvent extends JsonApiResource {
111
111
  }
112
112
 
113
113
  cancelAllParticipantTimeouts() {
114
- // Cancel all active participant-level timeouts. This sends CANCEL_TIMEOUT
115
- // to all APMs, which will benignly clear any active timeout timers.
116
- // Useful for scenarios where a game event (e.g., LIAR call) should immediately
117
- // cancel all individual participant timeouts.
114
+ // Cancels active allParticipants timeout tracking in AEM.
115
+ // Participant-local timeout ownership now lives in the browser runtime.
118
116
  this.send({ type: "CANCEL_ALL_PARTICIPANT_TIMEOUTS" })
119
117
  }
120
118
 
@@ -82,11 +82,10 @@ function scheduleExit(code, message) {
82
82
  setTimeout(() => process.exit(code), delayMs)
83
83
  }
84
84
 
85
- const AnearCoreServiceMachineContext = (appId, appEventMachineFactory, appParticipantMachineFactory) => ({
85
+ const AnearCoreServiceMachineContext = (appId, appEventMachineFactory) => ({
86
86
  appId,
87
87
  appData: null,
88
88
  appEventMachineFactory,
89
- appParticipantMachineFactory,
90
89
  anearEventMachines: {}, // All concurrent anear events handled by this core service
91
90
  pugTemplates: {},
92
91
  imageAssetsUrl: null,
@@ -493,14 +492,13 @@ function normalizeVersionToken(value) {
493
492
  return String(value).replace(/[^A-Za-z0-9_.-]/g, '_')
494
493
  }
495
494
 
496
- const AnearCoreServiceMachine = (appEventMachineFactory, appParticipantMachineFactory = null) => {
495
+ const AnearCoreServiceMachine = (appEventMachineFactory) => {
497
496
  const appId = process.env.ANEARAPP_APP_ID
498
497
  const machineConfig = AnearCoreServiceMachineConfig(appId)
499
498
 
500
499
  const anearCoreServiceMachineContext = AnearCoreServiceMachineContext(
501
500
  appId,
502
- appEventMachineFactory,
503
- appParticipantMachineFactory
501
+ appEventMachineFactory
504
502
  )
505
503
 
506
504
  const coreServiceMachine = createMachine(machineConfig, AnearCoreServiceMachineFunctions)