anear-js-api 0.6.5 → 1.1.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.
- package/jest.config.js +6 -0
- package/lib/AnearService.js +1 -1
- package/lib/api/AnearApi.js +6 -5
- package/lib/api/ApiService.js +70 -3
- package/lib/models/AnearEvent.js +15 -11
- package/lib/state_machines/AnearCoreServiceMachine.js +59 -77
- package/lib/state_machines/AnearEventMachine.js +299 -243
- package/lib/state_machines/AnearParticipantMachine.js +106 -97
- package/lib/utils/AppMachineTransition.js +57 -5
- package/lib/utils/DisplayEventProcessor.js +2 -1
- package/lib/utils/RealtimeMessaging.js +4 -4
- package/package.json +2 -2
- package/tests/AnearEvent.test.js +8 -13
- package/tests/AnearParticipant.test.js +2 -2
- package/tests/AnearService.test.js +2 -1
- package/tests/RealtimeMessaging.test.js +6 -6
package/jest.config.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
require('dotenv').config({ path: '.env.test' })
|
|
2
|
+
|
|
3
|
+
// Provide sane defaults so unit tests don't depend on local machine env.
|
|
4
|
+
process.env.ANEARAPP_API_KEY = process.env.ANEARAPP_API_KEY || 'test-api-key'
|
|
5
|
+
process.env.ANEARAPP_API_SECRET = process.env.ANEARAPP_API_SECRET || 'test-api-secret'
|
|
6
|
+
process.env.ANEARAPP_API_VERSION = process.env.ANEARAPP_API_VERSION || 'v1'
|
|
7
|
+
|
|
2
8
|
module.exports = {
|
|
3
9
|
}
|
|
4
10
|
|
package/lib/AnearService.js
CHANGED
|
@@ -7,6 +7,6 @@ const AnearService = (appEventMachineFactory, appParticipantMachineFactory = nul
|
|
|
7
7
|
// appEventMachineFactory = anearEvent => { returns XState Machine) }
|
|
8
8
|
// optional appParticipantMachineFactory = anearParticipant => { returns XState Machine) }
|
|
9
9
|
//
|
|
10
|
-
AnearCoreServiceMachine(appEventMachineFactory, appParticipantMachineFactory)
|
|
10
|
+
return AnearCoreServiceMachine(appEventMachineFactory, appParticipantMachineFactory)
|
|
11
11
|
}
|
|
12
12
|
module.exports = AnearService
|
package/lib/api/AnearApi.js
CHANGED
|
@@ -3,8 +3,8 @@ const logger = require('../utils/Logger')
|
|
|
3
3
|
const ApiService = require('./ApiService')
|
|
4
4
|
|
|
5
5
|
class AnearApi extends ApiService {
|
|
6
|
-
constructor(apiKey, apiVersion) {
|
|
7
|
-
super(apiKey, apiVersion)
|
|
6
|
+
constructor(apiKey, apiSecret, apiVersion) {
|
|
7
|
+
super(apiKey, apiSecret, apiVersion)
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
getAccount() {
|
|
@@ -105,12 +105,13 @@ class AnearApi extends ApiService {
|
|
|
105
105
|
|
|
106
106
|
// Instantiate and export the API immediately
|
|
107
107
|
const apiKey = process.env.ANEARAPP_API_KEY
|
|
108
|
+
const apiSecret = process.env.ANEARAPP_API_SECRET
|
|
108
109
|
const apiVersion = process.env.ANEARAPP_API_VERSION
|
|
109
110
|
|
|
110
|
-
if (!apiKey || !apiVersion) {
|
|
111
|
-
throw new Error("
|
|
111
|
+
if (!apiKey || !apiSecret || !apiVersion) {
|
|
112
|
+
throw new Error("ANEARAPP_API_KEY, ANEARAPP_API_SECRET, and ANEARAPP_API_VERSION must be defined in environment variables")
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
const anearApiInstance = new AnearApi(apiKey, apiVersion)
|
|
115
|
+
const anearApiInstance = new AnearApi(apiKey, apiSecret, apiVersion)
|
|
115
116
|
|
|
116
117
|
module.exports = anearApiInstance
|
package/lib/api/ApiService.js
CHANGED
|
@@ -13,19 +13,81 @@ const logger = require('../utils/Logger')
|
|
|
13
13
|
const DEFAULT_DEVELOPER_API_URL = 'https://api.anear.me/developer'
|
|
14
14
|
|
|
15
15
|
class ApiService {
|
|
16
|
-
constructor(apiKey, apiVersion) {
|
|
16
|
+
constructor(apiKey, apiSecret, apiVersion) {
|
|
17
17
|
const baseUrl = (process.env.ANEARAPP_API_URL || DEFAULT_DEVELOPER_API_URL).replace(/\/+$/, '')
|
|
18
18
|
const versionSegment = apiVersion ? `/${apiVersion}` : ''
|
|
19
19
|
this.api_base_url = `${baseUrl}${versionSegment}`
|
|
20
20
|
logger.debug(`ApiService configured api_base_url=${this.api_base_url}`)
|
|
21
|
+
|
|
22
|
+
this.api_key = apiKey
|
|
23
|
+
this.api_secret = apiSecret
|
|
24
|
+
this.developer_auth = null
|
|
25
|
+
this._authPromise = null
|
|
26
|
+
|
|
21
27
|
this.defaultHeaderObject = {
|
|
22
28
|
'Accept': 'application/json',
|
|
23
|
-
'Content-Type': 'application/json'
|
|
24
|
-
'X-Api-Key': apiKey
|
|
29
|
+
'Content-Type': 'application/json'
|
|
25
30
|
}
|
|
26
31
|
this.default_headers = new fetch.Headers(this.defaultHeaderObject)
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
async ensureDeveloperAuth() {
|
|
35
|
+
const now = Math.floor(Date.now() / 1000)
|
|
36
|
+
if (this.developer_auth && this.developer_auth.expires_at && this.developer_auth.expires_at > now) {
|
|
37
|
+
return this.developer_auth
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (this._authPromise) return this._authPromise
|
|
41
|
+
|
|
42
|
+
this._authPromise = this.loginDeveloper()
|
|
43
|
+
.finally(() => {
|
|
44
|
+
this._authPromise = null
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return this._authPromise
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async loginDeveloper() {
|
|
51
|
+
if (!this.api_key || !this.api_secret) {
|
|
52
|
+
throw new Error("Developer API credentials must be provided (api_key + secret)")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const payload = {
|
|
56
|
+
data: {
|
|
57
|
+
type: "sessions",
|
|
58
|
+
attributes: {
|
|
59
|
+
api_key: this.api_key,
|
|
60
|
+
secret: this.api_secret
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const request = new fetch.Request(
|
|
66
|
+
`${this.api_base_url}/sessions`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: this.default_headers,
|
|
69
|
+
body: JSON.stringify(payload)
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
logger.debug(`HTTP ${request.method} ${request.url} (developer session)`)
|
|
74
|
+
const resp = await fetch(request)
|
|
75
|
+
logger.debug(`HTTP response status=${resp.status} url=${request.url}`)
|
|
76
|
+
const json = await this.checkStatus(resp)
|
|
77
|
+
|
|
78
|
+
this.developer_auth = {
|
|
79
|
+
auth_token: json.auth_token,
|
|
80
|
+
expires_at: json.expires_at,
|
|
81
|
+
developer_id: json.developer_id
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const bearer = `Bearer ${this.developer_auth.auth_token}`
|
|
85
|
+
this.default_headers.set('Authorization', bearer)
|
|
86
|
+
// Keep the plain-object form in sync for consumers like Ably authHeaders.
|
|
87
|
+
this.defaultHeaderObject['Authorization'] = bearer
|
|
88
|
+
return this.developer_auth
|
|
89
|
+
}
|
|
90
|
+
|
|
29
91
|
idParamUrlString(resource, params) {
|
|
30
92
|
let idParam = ''
|
|
31
93
|
if (params.id) {
|
|
@@ -103,6 +165,11 @@ class ApiService {
|
|
|
103
165
|
}
|
|
104
166
|
|
|
105
167
|
async issueRequest(request) {
|
|
168
|
+
await this.ensureDeveloperAuth()
|
|
169
|
+
// Ensure each request has the latest Authorization header
|
|
170
|
+
if (this.developer_auth && this.developer_auth.auth_token) {
|
|
171
|
+
request.headers.set('Authorization', `Bearer ${this.developer_auth.auth_token}`)
|
|
172
|
+
}
|
|
106
173
|
logger.debug(`HTTP ${request.method} ${request.url}`)
|
|
107
174
|
const resp = await fetch(request)
|
|
108
175
|
logger.debug(`HTTP response status=${resp.status} url=${request.url}`)
|
package/lib/models/AnearEvent.js
CHANGED
|
@@ -32,37 +32,37 @@ class AnearEvent extends JsonApiResource {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
announceEvent() {
|
|
35
|
-
this.send("ANNOUNCE")
|
|
35
|
+
this.send({ type: "ANNOUNCE" })
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
startEvent() {
|
|
39
|
-
this.send("START")
|
|
39
|
+
this.send({ type: "START" })
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
cancelEvent() {
|
|
43
|
-
this.send("CANCEL")
|
|
43
|
+
this.send({ type: "CANCEL" })
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
closeEvent() {
|
|
47
|
-
this.send("CLOSE")
|
|
47
|
+
this.send({ type: "CLOSE" })
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
restartEvent() {
|
|
51
|
-
this.send("RESTART")
|
|
51
|
+
this.send({ type: "RESTART" })
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
pauseEvent(context, resumeEvent = { type: 'RESUME' }) {
|
|
55
55
|
// Persist via AEM and acknowledge with PAUSED
|
|
56
|
-
this.send('PAUSE',
|
|
56
|
+
this.send({ type: 'PAUSE', appmContext: { context, resumeEvent } })
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
saveEvent(context, resumeEvent = { type: 'RESUME' }) {
|
|
60
60
|
// Delegate save to the AEM; AEM will persist via ANAPI and acknowledge with SAVED
|
|
61
|
-
this.send('SAVE',
|
|
61
|
+
this.send({ type: 'SAVE', appmContext: { context, resumeEvent } })
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
bootParticipant(participantId, reason) {
|
|
65
|
-
this.send("BOOT_PARTICIPANT", { participantId, reason })
|
|
65
|
+
this.send({ type: "BOOT_PARTICIPANT", data: { participantId, reason } })
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
render(viewPath, displayType, appContext, event, timeout = null, props = {}) {
|
|
@@ -91,7 +91,8 @@ class AnearEvent extends JsonApiResource {
|
|
|
91
91
|
Object.assign(appRenderContext.meta, props)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
this.send(
|
|
94
|
+
this.send({
|
|
95
|
+
type: "RENDER_DISPLAY",
|
|
95
96
|
displayEvents: [{
|
|
96
97
|
viewPath,
|
|
97
98
|
appRenderContext
|
|
@@ -157,12 +158,15 @@ class AnearEvent extends JsonApiResource {
|
|
|
157
158
|
return this.attributes.flags.includes(flagName)
|
|
158
159
|
}
|
|
159
160
|
|
|
160
|
-
|
|
161
|
+
spectatorsAllowed() {
|
|
161
162
|
//
|
|
162
163
|
// Canonical spectators decision uses the ANAPI-provided boolean when present.
|
|
163
164
|
// Fallback to legacy negative flag for older payloads.
|
|
164
165
|
//
|
|
165
|
-
|
|
166
|
+
const allowedDasherized = this.attributes['spectators-allowed']
|
|
167
|
+
if (typeof allowedDasherized === 'boolean') return allowedDasherized
|
|
168
|
+
|
|
169
|
+
return !this.hasFlag('no_spectators')
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
isParticipantEventCreator(participant) {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* app developer’s AppEventMachine (AppM) and any participant machines.
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
|
-
const { assign, createMachine,
|
|
47
|
+
const { assign, createMachine, createActor, fromPromise } = require('xstate')
|
|
48
48
|
const logger = require('../utils/Logger')
|
|
49
49
|
const { version: anearJsApiVersion } = require('../../package.json')
|
|
50
50
|
|
|
@@ -63,7 +63,6 @@ const DefaultTemplatesRootDir = "./views"
|
|
|
63
63
|
|
|
64
64
|
const AnearCoreServiceMachineContext = (appId, appEventMachineFactory, appParticipantMachineFactory) => ({
|
|
65
65
|
appId,
|
|
66
|
-
coreServiceMachine: null,
|
|
67
66
|
appData: null,
|
|
68
67
|
appEventMachineFactory,
|
|
69
68
|
appParticipantMachineFactory,
|
|
@@ -75,33 +74,19 @@ const AnearCoreServiceMachineContext = (appId, appEventMachineFactory, appPartic
|
|
|
75
74
|
retryDelay: 0
|
|
76
75
|
})
|
|
77
76
|
|
|
78
|
-
const GlobalEventConfig = {
|
|
79
|
-
// This wildcard will catch done.invoke.anearEventMachine_<id>
|
|
80
|
-
'done.invoke.anearEventMachine_*': {
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
77
|
const AnearCoreServiceMachineConfig = appId => ({
|
|
85
78
|
id: `AnearCoreServiceMachine_${appId}`,
|
|
86
|
-
initial: '
|
|
87
|
-
|
|
79
|
+
initial: 'fetchAppDataWithRetry',
|
|
80
|
+
context: ({ input }) => input,
|
|
88
81
|
states: {
|
|
89
|
-
waitForContextUpdate: {
|
|
90
|
-
id: 'waitForContextUpdate',
|
|
91
|
-
on: {
|
|
92
|
-
UPDATE_CONTEXT: {
|
|
93
|
-
actions: ['updateContextWithMachineRef'],
|
|
94
|
-
target: 'fetchAppDataWithRetry'
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
82
|
fetchAppDataWithRetry: {
|
|
99
|
-
entry:
|
|
83
|
+
entry: _ => logger.info('anear-js-api version: ', anearJsApiVersion),
|
|
100
84
|
initial: 'fetchAppData',
|
|
101
85
|
states: {
|
|
102
86
|
fetchAppData: {
|
|
103
87
|
invoke: {
|
|
104
88
|
src: 'fetchAppData',
|
|
89
|
+
input: ({ context }) => ({ appId: context.appId }),
|
|
105
90
|
onDone: {
|
|
106
91
|
actions: ['setAppData'],
|
|
107
92
|
target: '#initRealtimeMessaging'
|
|
@@ -134,10 +119,11 @@ const AnearCoreServiceMachineConfig = appId => ({
|
|
|
134
119
|
uploadNewImageAssets: {
|
|
135
120
|
invoke: {
|
|
136
121
|
src: 'uploadNewImageAssets',
|
|
122
|
+
input: ({ context }) => ({ appId: context.appId }),
|
|
137
123
|
onDone: {
|
|
138
124
|
actions: assign({
|
|
139
|
-
// event.
|
|
140
|
-
imageAssetsUrl: (
|
|
125
|
+
// v5: `event.output` is the resolved promise value
|
|
126
|
+
imageAssetsUrl: ({ event }) => event.output
|
|
141
127
|
}),
|
|
142
128
|
target: 'uploadNewFontAssets'
|
|
143
129
|
},
|
|
@@ -147,9 +133,10 @@ const AnearCoreServiceMachineConfig = appId => ({
|
|
|
147
133
|
uploadNewFontAssets: {
|
|
148
134
|
invoke: {
|
|
149
135
|
src: 'uploadNewFontAssets',
|
|
136
|
+
input: ({ context }) => ({ appId: context.appId }),
|
|
150
137
|
onDone: {
|
|
151
138
|
actions: assign({
|
|
152
|
-
fontAssetsUrl: (
|
|
139
|
+
fontAssetsUrl: ({ event }) => event.output
|
|
153
140
|
}),
|
|
154
141
|
target: 'minifyCssAndUpload'
|
|
155
142
|
},
|
|
@@ -160,6 +147,11 @@ const AnearCoreServiceMachineConfig = appId => ({
|
|
|
160
147
|
invoke: {
|
|
161
148
|
id: 'minifyCssAndUpload',
|
|
162
149
|
src: 'minifyCssAndUpload',
|
|
150
|
+
input: ({ context }) => ({
|
|
151
|
+
appId: context.appId,
|
|
152
|
+
imageAssetsUrl: context.imageAssetsUrl,
|
|
153
|
+
fontAssetsUrl: context.fontAssetsUrl
|
|
154
|
+
}),
|
|
163
155
|
onDone: {
|
|
164
156
|
target: 'loadAndCompilePugTemplates'
|
|
165
157
|
},
|
|
@@ -176,7 +168,7 @@ const AnearCoreServiceMachineConfig = appId => ({
|
|
|
176
168
|
// The Anear API backend will send CREATE_EVENT or LOAD_EVENT messages with the event JSON data
|
|
177
169
|
// to this createEventMessages Channel when it needs to create a new instance of an
|
|
178
170
|
// Event
|
|
179
|
-
entry: (context) => logger.debug(`Waiting on ${context.appData.data.attributes['short-name']} lifecycle command`),
|
|
171
|
+
entry: ({ context }) => logger.debug(`Waiting on ${context.appData.data.attributes['short-name']} lifecycle command`),
|
|
180
172
|
on: {
|
|
181
173
|
CREATE_EVENT: {
|
|
182
174
|
actions: ['startNewEventMachine']
|
|
@@ -193,50 +185,40 @@ const AnearCoreServiceMachineConfig = appId => ({
|
|
|
193
185
|
},
|
|
194
186
|
failure: {
|
|
195
187
|
id: 'failure',
|
|
196
|
-
entry: (
|
|
188
|
+
entry: ({ event }) => logger.debug("Failure! ", event.error),
|
|
197
189
|
type: 'final'
|
|
198
190
|
}
|
|
199
191
|
}
|
|
200
192
|
})
|
|
201
193
|
|
|
202
194
|
const AnearCoreServiceMachineFunctions = {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
)
|
|
195
|
+
actors: {
|
|
196
|
+
// v5 pattern: async "services" become Promise Actors via `fromPromise`.
|
|
197
|
+
// The invoked actor receives `input` from the invoking state's `invoke.input`.
|
|
198
|
+
fetchAppData: fromPromise(({ input }) => AnearApi.getApp(input.appId)),
|
|
199
|
+
uploadNewImageAssets: fromPromise(({ input }) => {
|
|
200
|
+
const uploader = new ImageAssetsUploader(C.ImagesDirPath, input.appId)
|
|
210
201
|
return uploader.uploadAssets()
|
|
211
|
-
},
|
|
212
|
-
uploadNewFontAssets:
|
|
213
|
-
const uploader = new FontAssetsUploader(
|
|
214
|
-
C.FontsDirPath,
|
|
215
|
-
context.appId
|
|
216
|
-
)
|
|
202
|
+
}),
|
|
203
|
+
uploadNewFontAssets: fromPromise(({ input }) => {
|
|
204
|
+
const uploader = new FontAssetsUploader(C.FontsDirPath, input.appId)
|
|
217
205
|
return uploader.uploadAssets()
|
|
218
|
-
},
|
|
219
|
-
minifyCssAndUpload: (
|
|
206
|
+
}),
|
|
207
|
+
minifyCssAndUpload: fromPromise(({ input }) => {
|
|
220
208
|
const uploader = new CssUploader(
|
|
221
209
|
C.CssDirPath,
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
210
|
+
input.imageAssetsUrl,
|
|
211
|
+
input.fontAssetsUrl,
|
|
212
|
+
input.appId
|
|
225
213
|
)
|
|
226
|
-
|
|
227
214
|
return uploader.uploadCss()
|
|
228
|
-
}
|
|
215
|
+
})
|
|
229
216
|
},
|
|
230
217
|
actions: {
|
|
231
|
-
|
|
232
|
-
{
|
|
233
|
-
coreServiceMachine: (_, event) => event.coreServiceMachine
|
|
234
|
-
}
|
|
235
|
-
),
|
|
236
|
-
initRealtime: context => RealtimeMessaging.initRealtime(context.appId, context.coreServiceMachine),
|
|
218
|
+
initRealtime: ({ context, self }) => RealtimeMessaging.initRealtime(context.appId, self),
|
|
237
219
|
loadPugFiles: assign(
|
|
238
220
|
{
|
|
239
|
-
pugTemplates: () => {
|
|
221
|
+
pugTemplates: (_args) => {
|
|
240
222
|
const pugLoader = new PugLoader(DefaultTemplatesRootDir)
|
|
241
223
|
const templates = pugLoader.compiledPugTemplates()
|
|
242
224
|
logger.debug(`loaded pug templates ${Object.keys(templates)}`)
|
|
@@ -245,7 +227,7 @@ const AnearCoreServiceMachineFunctions = {
|
|
|
245
227
|
}
|
|
246
228
|
),
|
|
247
229
|
incrementRetryDelay: assign({
|
|
248
|
-
retryDelay: (context,
|
|
230
|
+
retryDelay: ({ context }, _params) => {
|
|
249
231
|
const retryTimesBeforeReset = 6
|
|
250
232
|
const increment = 5000
|
|
251
233
|
const start = increment
|
|
@@ -256,35 +238,36 @@ const AnearCoreServiceMachineFunctions = {
|
|
|
256
238
|
}),
|
|
257
239
|
setAppData: assign(
|
|
258
240
|
{
|
|
259
|
-
appData: (
|
|
260
|
-
|
|
261
|
-
|
|
241
|
+
appData: ({ event }) => {
|
|
242
|
+
const output = event.output
|
|
243
|
+
logger.debug(`fetched ${output.data.attributes["short-name"]} app data`)
|
|
244
|
+
return output
|
|
262
245
|
}
|
|
263
246
|
}
|
|
264
247
|
),
|
|
265
248
|
createEventsCreationChannel: assign(
|
|
266
249
|
{
|
|
267
|
-
newEventCreationChannel: context => {
|
|
250
|
+
newEventCreationChannel: ({ context, self }) => {
|
|
268
251
|
const channelName = CreateEventChannelNameTemplate(context.appId)
|
|
269
|
-
return RealtimeMessaging.getChannel(channelName,
|
|
252
|
+
return RealtimeMessaging.getChannel(channelName, self)
|
|
270
253
|
}
|
|
271
254
|
}
|
|
272
255
|
),
|
|
273
|
-
subscribeCreateEventMessages: context => {
|
|
256
|
+
subscribeCreateEventMessages: ({ context, self }) => {
|
|
274
257
|
RealtimeMessaging.subscribe(
|
|
275
258
|
context.newEventCreationChannel,
|
|
276
|
-
|
|
259
|
+
self,
|
|
277
260
|
'CREATE_EVENT'
|
|
278
261
|
)
|
|
279
262
|
RealtimeMessaging.subscribe(
|
|
280
263
|
context.newEventCreationChannel,
|
|
281
|
-
|
|
264
|
+
self,
|
|
282
265
|
'LOAD_EVENT'
|
|
283
266
|
)
|
|
284
267
|
},
|
|
285
268
|
startNewEventMachine: assign(
|
|
286
269
|
{
|
|
287
|
-
anearEventMachines: (context, event) => {
|
|
270
|
+
anearEventMachines: ({ context, event, self }) => {
|
|
288
271
|
const eventJSON = JSON.parse(event.data)
|
|
289
272
|
const anearEvent = new AnearEvent(eventJSON)
|
|
290
273
|
|
|
@@ -294,16 +277,22 @@ const AnearCoreServiceMachineFunctions = {
|
|
|
294
277
|
}
|
|
295
278
|
|
|
296
279
|
const isLoadEvent = event.type === 'LOAD_EVENT'
|
|
297
|
-
const
|
|
280
|
+
const actor = AnearEventMachine(anearEvent, {
|
|
281
|
+
...context,
|
|
282
|
+
// AEM expects a reference back to its supervisor; in v5 we can pass `self`
|
|
283
|
+
// directly rather than storing a "coreServiceMachine" reference in context.
|
|
284
|
+
coreServiceMachine: self,
|
|
285
|
+
rehydrate: isLoadEvent
|
|
286
|
+
})
|
|
298
287
|
|
|
299
288
|
return {
|
|
300
289
|
...context.anearEventMachines,
|
|
301
|
-
[anearEvent.id]:
|
|
290
|
+
[anearEvent.id]: actor.start()
|
|
302
291
|
}
|
|
303
292
|
}
|
|
304
293
|
}
|
|
305
294
|
),
|
|
306
|
-
cleanupEventMachine: assign((context, event) => {
|
|
295
|
+
cleanupEventMachine: assign(({ context, event }) => {
|
|
307
296
|
const { [event.eventId]: dropped, ...remaining } = context.anearEventMachines
|
|
308
297
|
logger.debug(`ACSM ${event.eventId} is ${dropped ? "done → cleaning up" : "NOT FOUND"}`)
|
|
309
298
|
|
|
@@ -313,16 +302,16 @@ const AnearCoreServiceMachineFunctions = {
|
|
|
313
302
|
})
|
|
314
303
|
},
|
|
315
304
|
delays: {
|
|
316
|
-
retry_with_backoff_delay: (context
|
|
305
|
+
retry_with_backoff_delay: ({ context }) => context.retryDelay
|
|
317
306
|
},
|
|
318
307
|
guards: {
|
|
319
|
-
noImageAssetFilesFound: (
|
|
308
|
+
noImageAssetFilesFound: ({ event }) => event.output === null
|
|
320
309
|
}
|
|
321
310
|
}
|
|
322
311
|
|
|
323
312
|
const AnearCoreServiceMachine = (appEventMachineFactory, appParticipantMachineFactory = null) => {
|
|
324
313
|
const appId = process.env.ANEARAPP_APP_ID
|
|
325
|
-
const
|
|
314
|
+
const machineConfig = AnearCoreServiceMachineConfig(appId)
|
|
326
315
|
|
|
327
316
|
const anearCoreServiceMachineContext = AnearCoreServiceMachineContext(
|
|
328
317
|
appId,
|
|
@@ -330,16 +319,9 @@ const AnearCoreServiceMachine = (appEventMachineFactory, appParticipantMachineFa
|
|
|
330
319
|
appParticipantMachineFactory
|
|
331
320
|
)
|
|
332
321
|
|
|
333
|
-
const coreServiceMachine = createMachine(
|
|
334
|
-
expandedConfig,
|
|
335
|
-
AnearCoreServiceMachineFunctions
|
|
336
|
-
).withContext(anearCoreServiceMachineContext)
|
|
337
|
-
|
|
338
|
-
const coreServiceMachineStarted = interpret(coreServiceMachine).start()
|
|
339
|
-
|
|
340
|
-
coreServiceMachineStarted.send('UPDATE_CONTEXT', { coreServiceMachine: coreServiceMachineStarted })
|
|
322
|
+
const coreServiceMachine = createMachine(machineConfig, AnearCoreServiceMachineFunctions)
|
|
341
323
|
|
|
342
|
-
return
|
|
324
|
+
return createActor(coreServiceMachine, { input: anearCoreServiceMachineContext }).start()
|
|
343
325
|
}
|
|
344
326
|
|
|
345
327
|
module.exports = AnearCoreServiceMachine
|