@raydiant/playlist-window-manager 0.24.1 → 0.25.1-canary.0

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.
@@ -10,35 +10,11 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- var desc = Object.getOwnPropertyDescriptor(m, k);
16
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
- desc = { enumerable: true, get: function() { return m[k]; } };
18
- }
19
- Object.defineProperty(o, k2, desc);
20
- }) : (function(o, m, k, k2) {
21
- if (k2 === undefined) k2 = k;
22
- o[k2] = m[k];
23
- }));
24
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
- Object.defineProperty(o, "default", { enumerable: true, value: v });
26
- }) : function(o, v) {
27
- o["default"] = v;
28
- });
29
- var __importStar = (this && this.__importStar) || function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
14
  return new (P || (P = Promise))(function (resolve, reject) {
39
15
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
40
16
  function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
41
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
42
18
  step((generator = generator.apply(thisArg, _arguments || [])).next());
43
19
  });
44
20
  };
@@ -48,7 +24,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
48
24
  function verb(n) { return function (v) { return step([n, v]); }; }
49
25
  function step(op) {
50
26
  if (f) throw new TypeError("Generator is already executing.");
51
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
27
+ while (_) try {
52
28
  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
53
29
  if (y = 0, t) op = [op[0] & 2, t.value];
54
30
  switch (op[0]) {
@@ -69,37 +45,28 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
69
45
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
70
46
  }
71
47
  };
48
+ var __importStar = (this && this.__importStar) || function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
52
+ result["default"] = mod;
53
+ return result;
54
+ };
72
55
  var __importDefault = (this && this.__importDefault) || function (mod) {
73
56
  return (mod && mod.__esModule) ? mod : { "default": mod };
74
57
  };
75
58
  Object.defineProperty(exports, "__esModule", { value: true });
76
59
  var RE = __importStar(require("@raydiant/playlist-rule-engine"));
77
60
  var fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
78
- var uuid_1 = require("uuid");
79
61
  var embeddedApps_1 = __importDefault(require("./embeddedApps"));
80
62
  var PlaylistWindowManager_1 = __importDefault(require("./PlaylistWindowManager"));
81
63
  var WindowTimeoutError_1 = __importDefault(require("./WindowTimeoutError"));
82
64
  var WindowLoadError_1 = __importDefault(require("./WindowLoadError"));
83
65
  // TODO: Automatically inject latest version when building in CI.
84
- var defaultAppRendererUrl = 'https://apps.raydiant.com/3.0.7/index.html';
66
+ var defaultAppRendererUrl = 'https://apps.raydiant.com/1.4.7/index.html';
85
67
  var isValidNumber = function (value) {
86
68
  return typeof value === 'number' && !isNaN(value);
87
69
  };
88
- var isValidAnalyticsEvent = function (value) {
89
- return value &&
90
- typeof value === 'object' &&
91
- typeof value.type === 'string' &&
92
- typeof value.source === 'string' &&
93
- (typeof value.productCategory === 'string' ||
94
- value.productCategory === undefined ||
95
- value.productCategory === null);
96
- };
97
- var isValidChargeRequest = function (value) {
98
- return value &&
99
- typeof value === 'object' &&
100
- typeof value.requestId === 'string' &&
101
- typeof value.amount === 'number';
102
- };
103
70
  var PresentationWindow = /** @class */ (function () {
104
71
  function PresentationWindow(options) {
105
72
  var _this = this;
@@ -110,6 +77,7 @@ var PresentationWindow = /** @class */ (function () {
110
77
  this.completeCallback = null;
111
78
  this.errorCallback = null;
112
79
  this.readyTimeout = null;
80
+ // private completeThrottleTimeout: ReturnType<typeof setTimeout> | null = null;
113
81
  this.windowManagers = {};
114
82
  this.focusedWindowManager = null;
115
83
  this.didEmbeddedAppLoad = false;
@@ -119,222 +87,44 @@ var PresentationWindow = /** @class */ (function () {
119
87
  this.isChildWindowLocked = {};
120
88
  this.enableInterruptLockCallback = null;
121
89
  this.disableInterruptLockCallback = null;
122
- this.analyticsEventCallback = null;
123
- this.chargeRequestCallback = null;
124
90
  this.forceMute = false;
125
91
  this.error = null;
126
- this.workerState = {};
127
- this.workerSubscriptions = new Set();
128
- this.runtimeSubscriptions = new Set();
129
- this.previewSubscriptions = new Set();
130
- this.previewState = { inputs: {} };
131
- this.paymentSubscriptions = new Set();
132
- this.createObjectURLResolvers = {};
133
- this.createObjectURLTimeouts = {};
134
- this.handleEmbeddedMessage = function (type, payload) { return __awaiter(_this, void 0, void 0, function () {
135
- var windowId, workerState;
136
- return __generator(this, function (_a) {
137
- windowId = this.options.windowId;
138
- switch (type) {
139
- case 'ready': {
140
- this.logInfo("Received 'ready' from window '".concat(windowId, "'"));
141
- this.handleReady();
142
- break;
143
- }
144
- case 'complete': {
145
- if (payload === undefined) {
146
- this.logInfo("Received 'complete' from window '".concat(windowId, "'"));
147
- this.handleComplete();
148
- }
149
- else {
150
- this.logInfo("Received 'complete' with error from window '".concat(windowId, ", error=").concat(payload, "'"));
151
- this.handleError(payload);
152
- }
153
- break;
154
- }
155
- case 'runtime-subscribe': {
156
- if (typeof payload === 'string') {
157
- this.logInfo("Received 'runtime-subscribe' from window '".concat(windowId, "'"));
158
- // The payload is the event name (ex. 'play').
159
- this.runtimeSubscriptions.add(payload);
160
- // Immediately send play if the app if already playing.
161
- if (this.isPlaying()) {
162
- this.sendMessageString('play');
163
- }
164
- }
165
- else {
166
- this.logWarning("Invalid payload for runtime-subscribe message: ".concat(payload));
167
- }
168
- break;
169
- }
170
- case 'runtime-unsubscribe': {
171
- if (typeof payload === 'string') {
172
- this.logInfo("Received 'runtime-unsubscribe' from window '".concat(windowId, "'"));
173
- // The payload is the event name (ex. 'play').
174
- this.runtimeSubscriptions.delete(payload);
175
- }
176
- else {
177
- this.logWarning("Invalid payload for runtime-subscribe message: ".concat(payload));
178
- }
179
- break;
180
- }
181
- case 'worker-subscribe': {
182
- if (typeof payload === 'string') {
183
- this.logInfo("Received 'worker-subscribe' from window '".concat(windowId, "'"));
184
- // The payload is the worker name.
185
- this.workerSubscriptions.add(payload);
186
- workerState = this.workerState[payload];
187
- if (workerState !== undefined) {
188
- this.sendMessageString('worker-state', {
189
- name: payload,
190
- state: workerState,
191
- });
192
- }
193
- }
194
- else {
195
- this.logWarning("Invalid payload for worker-subscribe message: ".concat(payload));
196
- }
197
- break;
198
- }
199
- case 'worker-unsubscribe': {
200
- if (typeof payload === 'string') {
201
- this.logInfo("Received 'worker-unsubscribe' from window '".concat(windowId, "'"));
202
- // The payload is the worker name.
203
- this.workerSubscriptions.delete(payload);
204
- }
205
- else {
206
- this.logWarning("Invalid payload for worker-unsubscribe message: ".concat(payload));
207
- }
208
- break;
209
- }
210
- case 'analytics-event': {
211
- if (isValidAnalyticsEvent(payload)) {
212
- if (this.analyticsEventCallback) {
213
- this.analyticsEventCallback(payload);
214
- }
215
- }
216
- else {
217
- this.logWarning("Invalid payload for analytics-event message: ".concat(payload));
218
- }
219
- break;
220
- }
221
- case 'create-object-url-result': {
222
- if (isValidCreateObjectURLResultPayload(payload)) {
223
- // Resolve promise with the local blob URL.
224
- if (this.createObjectURLResolvers[payload.requestId]) {
225
- this.createObjectURLResolvers[payload.requestId](payload.url);
226
- delete this.createObjectURLResolvers[payload.requestId];
227
- }
228
- // Clear the timeout for the request.
229
- if (this.createObjectURLTimeouts[payload.requestId]) {
230
- clearTimeout(this.createObjectURLTimeouts[payload.requestId]);
231
- delete this.createObjectURLTimeouts[payload.requestId];
232
- }
233
- }
234
- else {
235
- this.logWarning("Invalid payload for create-object-url-result message: ".concat(payload));
236
- }
237
- break;
238
- }
239
- case 'preview-subscribe': {
240
- if (typeof payload === 'string') {
241
- this.logInfo("Received 'preview-subscribe' from window '".concat(windowId, "'"));
242
- // The payload is the event name (ex. 'inputs').
243
- this.previewSubscriptions.add(payload);
244
- }
245
- else {
246
- this.logWarning("Invalid payload for preview-subscribe message: ".concat(payload));
247
- }
248
- break;
249
- }
250
- case 'preview-unsubscribe': {
251
- if (typeof payload === 'string') {
252
- this.logInfo("Received 'preview-unsubscribe' from window '".concat(windowId, "'"));
253
- // The payload is the event name (ex. 'inputs').
254
- this.previewSubscriptions.delete(payload);
255
- }
256
- else {
257
- this.logWarning("Invalid payload for preview-subscribe message: ".concat(payload));
258
- }
259
- break;
260
- }
261
- case 'payments-charge-request': {
262
- if (isValidChargeRequest(payload)) {
263
- if (this.chargeRequestCallback) {
264
- this.chargeRequestCallback(payload);
265
- }
266
- }
267
- else {
268
- this.logWarning("Invalid payload for payments-charge-request message: ".concat(payload));
269
- }
270
- break;
271
- }
272
- case 'payments-subscribe': {
273
- if (typeof payload === 'string') {
274
- this.logInfo("Received 'worker-subscribe' from window '".concat(windowId, "'"));
275
- // The payload is the payment subscription type (ex. 'charge', 'terminal')
276
- this.paymentSubscriptions.add(payload);
277
- // Immediately send terminal when subscribing.
278
- if (payload === 'terminal' && this.options.getTerminal) {
279
- this.sendMessageObject('payments-terminal-event', {
280
- terminal: this.options.getTerminal(),
281
- });
282
- }
283
- }
284
- else {
285
- this.logWarning("Invalid payload for payments-subscribe message: ".concat(payload));
286
- }
287
- break;
288
- }
289
- case 'payments-unsubscribe': {
290
- if (typeof payload === 'string') {
291
- this.logInfo("Received 'payments-unsubscribe' from window '".concat(windowId, "'"));
292
- this.paymentSubscriptions.delete(payload);
293
- }
294
- else {
295
- this.logWarning("Invalid payload for payments-unsubscribe message: ".concat(payload));
296
- }
297
- break;
298
- }
299
- default: {
300
- this.logWarning("Received unknown embedded message type: ".concat(type));
301
- }
302
- }
303
- return [2 /*return*/];
304
- });
305
- }); };
306
- this.handleLegacyMessage = function (type, payload) { return __awaiter(_this, void 0, void 0, function () {
92
+ this.handleMessage = function (type, payload) { return __awaiter(_this, void 0, void 0, function () {
307
93
  var _a, windowId, onPresentationProperties;
308
94
  return __generator(this, function (_b) {
309
95
  _a = this.options, windowId = _a.windowId, onPresentationProperties = _a.onPresentationProperties;
310
96
  if (type === 'loaded') {
311
- this.logInfo("Received 'loaded' from window '".concat(windowId, "'"));
97
+ this.logInfo("Received 'loaded' from window '" + windowId + "'");
312
98
  this.sendRenderMessage();
313
99
  }
314
100
  if (type === 'presentation_ready') {
315
- this.logInfo("Received 'presentation_ready' from window '".concat(windowId, "'"));
316
- this.handleReady();
101
+ this.logInfo("Received 'presentation_ready' from window '" + windowId + "'");
102
+ this.didReceiveReady = true;
103
+ this.checkIsReadyCallback();
317
104
  }
318
105
  if (type === 'presentation_complete') {
319
- this.logInfo("Received 'presentation_complete' from window '".concat(windowId, "'"));
320
- this.handleComplete();
106
+ this.logInfo("Received 'presentation_complete' from window '" + windowId + "'");
107
+ this.didReceiveComplete = true;
108
+ if (this.completeCallback) {
109
+ this.completeCallback();
110
+ }
321
111
  }
322
112
  if (type === 'enable_interrupt_lock') {
323
- this.logInfo("Received 'enable_interrupt_lock' from window '".concat(windowId, "'"));
113
+ this.logInfo("Received 'enable_interrupt_lock' from window '" + windowId + "'");
324
114
  this.enableInteruptLock();
325
115
  }
326
116
  if (type === 'disable_interrupt_lock') {
327
- this.logInfo("Received 'disable_interrupt_lock' from window '".concat(windowId, "'"));
117
+ this.logInfo("Received 'disable_interrupt_lock' from window '" + windowId + "'");
328
118
  this.disableInteruptLock();
329
119
  }
330
120
  if (type === 'open_child_window') {
331
- this.logInfo("Received 'open_child_window' from window '".concat(windowId, "', windowId=").concat(payload.windowId, " playlistId=").concat(payload.playlistId, " isMuted=").concat(payload.isMuted, " x=").concat(payload.x, " y=").concat(payload.y, " width=").concat(payload.width, " height=").concat(payload.height));
121
+ this.logInfo("Received 'open_child_window' from window '" + windowId + "', windowId=" + payload.windowId + " playlistId=" + payload.playlistId + " isMuted=" + payload.isMuted + " x=" + payload.x + " y=" + payload.y + " width=" + payload.width + " height=" + payload.height);
332
122
  if (this.isValidOpenChildWindowPayload(payload)) {
333
123
  this.openChildWindow(payload.windowId, payload.playlistId, {
334
124
  x: Math.round(payload.x),
335
125
  y: Math.round(payload.y),
336
126
  width: Math.round(payload.width),
337
- height: Math.round(payload.height),
127
+ height: Math.round(payload.height)
338
128
  }, payload.isMuted, payload.isFocused, payload.theme);
339
129
  }
340
130
  else {
@@ -343,20 +133,20 @@ var PresentationWindow = /** @class */ (function () {
343
133
  }
344
134
  if (type === 'close_child_window') {
345
135
  // TODO: Validate close_child_window message payload.
346
- this.logInfo("Received 'close_child_window', windowId=".concat(payload.windowId));
136
+ this.logInfo("Received 'close_child_window', windowId=" + payload.windowId);
347
137
  this.closeChildWindow(payload.windowId);
348
138
  }
349
139
  if (type === 'log_error') {
350
- this.handleError("Received error from window '".concat(windowId, "', error=").concat(JSON.stringify(payload)));
140
+ this.handleError("Received error from window '" + windowId + "', error=" + JSON.stringify(payload));
351
141
  }
352
142
  if (type === 'log_info') {
353
- this.logInfo("Received info log from window '".concat(windowId, "', message=").concat(JSON.stringify(payload)));
143
+ this.logInfo("Received info log from window '" + windowId + "', message=" + JSON.stringify(payload));
354
144
  }
355
145
  if (type === 'log_debug') {
356
- this.logDebug("Received info debug from window '".concat(windowId, "', message=").concat(JSON.stringify(payload)));
146
+ this.logDebug("Received info debug from window '" + windowId + "', message=" + JSON.stringify(payload));
357
147
  }
358
148
  if (type === 'presentation_properties') {
359
- this.logInfo("Received 'presentation_properties' from window '".concat(windowId, "'"));
149
+ this.logInfo("Received 'presentation_properties' from window '" + windowId + "'");
360
150
  if (onPresentationProperties) {
361
151
  onPresentationProperties(payload.properties, payload.strings);
362
152
  }
@@ -378,13 +168,12 @@ var PresentationWindow = /** @class */ (function () {
378
168
  this.ruleEngineState = options.ruleEngineState;
379
169
  this.theme = options.theme;
380
170
  this.forceMute = options.forceMute || false;
381
- this.workerState = options.workerState;
382
171
  }
383
172
  PresentationWindow.prototype.load = function () {
384
173
  if (this.isEmbeddedApp()) {
385
174
  return this.loadEmbeddedApp();
386
175
  }
387
- return this.loadLegacyApp();
176
+ return this.loadRaydiantApp();
388
177
  };
389
178
  PresentationWindow.prototype.show = function (isFocused) {
390
179
  var _this = this;
@@ -415,7 +204,7 @@ var PresentationWindow = /** @class */ (function () {
415
204
  wm.show(false);
416
205
  }
417
206
  });
418
- this.logInfo("Show window '".concat(windowId, "' isMuted=").concat(isMuted, " isFocused=").concat(isFocused).concat(isChildWindowFocused ? " isChildWindowFocused=true" : ''));
207
+ this.logInfo("Show window '" + windowId + "' isMuted=" + isMuted + " isFocused=" + isFocused + (isChildWindowFocused ? " isChildWindowFocused=true" : ''));
419
208
  };
420
209
  PresentationWindow.prototype.hide = function () {
421
210
  var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
@@ -436,8 +225,6 @@ var PresentationWindow = /** @class */ (function () {
436
225
  this.errorCallback = null;
437
226
  this.enableInterruptLockCallback = null;
438
227
  this.disableInterruptLockCallback = null;
439
- // Clean up subscriptions
440
- this.workerSubscriptions.clear();
441
228
  // Clear timers
442
229
  if (this.readyTimeout) {
443
230
  clearTimeout(this.readyTimeout);
@@ -457,11 +244,11 @@ var PresentationWindow = /** @class */ (function () {
457
244
  return [4 /*yield*/, renderer.removeWindow(windowId)];
458
245
  case 2:
459
246
  _b.sent();
460
- this.logInfo("Removed window '".concat(windowId, "'"));
247
+ this.logInfo("Removed window '" + windowId + "'");
461
248
  return [3 /*break*/, 4];
462
249
  case 3:
463
250
  err_1 = _b.sent();
464
- this.logError("Failed to remove window '".concat(windowId, "' with '").concat(err_1.message, "'"));
251
+ this.logError("Failed to remove window '" + windowId + "' with '" + err_1.message + "'");
465
252
  return [3 /*break*/, 4];
466
253
  case 4: return [2 /*return*/];
467
254
  }
@@ -489,20 +276,16 @@ var PresentationWindow = /** @class */ (function () {
489
276
  }, durationMs);
490
277
  }
491
278
  if (!this.isEmbeddedApp()) {
492
- this.sendMessageString('play');
279
+ this.sendMessage('play');
493
280
  // Play any child window managers.
494
281
  Object.values(this.windowManagers).forEach(function (wm) {
495
- // We only want to trigger play on child windows the first play of the main window or if
282
+ // We only want trigger play on child windows the first play of the main window or if
496
283
  // the child window is paused.
497
284
  if (!wm.isPlaying() || wm.isPaused()) {
498
285
  wm.play();
499
286
  }
500
287
  });
501
288
  }
502
- else if (this.runtimeSubscriptions.has('play')) {
503
- // If the embedded app has subscribed to the play event, send it a play event.
504
- this.sendMessageString('play');
505
- }
506
289
  this.lastPlayedAt = new Date();
507
290
  };
508
291
  PresentationWindow.prototype.pause = function () {
@@ -528,16 +311,7 @@ var PresentationWindow = /** @class */ (function () {
528
311
  PresentationWindow.prototype.onDisableInterruptLock = function (callback) {
529
312
  this.disableInterruptLockCallback = callback;
530
313
  };
531
- PresentationWindow.prototype.onAnalyticsEvent = function (callback) {
532
- this.analyticsEventCallback = callback;
533
- };
534
- PresentationWindow.prototype.onChargeRequest = function (callback) {
535
- this.chargeRequestCallback = callback;
536
- };
537
314
  PresentationWindow.prototype.isReady = function () {
538
- // TODO: To support the 'ready' event in embedded apps, they will need to tell the
539
- // runtime that it should wait for ready instead of DOMLoaded. This could be a "wait
540
- // for ready" option in the Developer Portal.
541
315
  if (this.isEmbeddedApp()) {
542
316
  return this.didEmbeddedAppLoad;
543
317
  }
@@ -576,92 +350,36 @@ var PresentationWindow = /** @class */ (function () {
576
350
  };
577
351
  PresentationWindow.prototype.reload = function () {
578
352
  return __awaiter(this, void 0, void 0, function () {
579
- var _a, applicationVersion, windowId, updatedInputs, url;
353
+ var _a, applicationVersion, windowId, url;
580
354
  return __generator(this, function (_b) {
581
355
  switch (_b.label) {
582
356
  case 0:
583
357
  _a = this.options, applicationVersion = _a.applicationVersion, windowId = _a.windowId;
584
- if (!this.isEmbeddedApp()) return [3 /*break*/, 4];
585
- if (!applicationVersion.embeddedUrlFormat) return [3 /*break*/, 3];
586
- if (!this.previewSubscriptions.has('inputs')) return [3 /*break*/, 1];
587
- this.logInfo("Reload window '".concat(windowId, "' for embedded app preview state"));
588
- updatedInputs = transformInputValues(this.presentation.applicationVariables);
589
- if (!(0, fast_deep_equal_1.default)(updatedInputs, this.previewState.inputs)) {
590
- this.sendMessageObject('preview-inputs', updatedInputs);
591
- }
592
- this.previewState.inputs = updatedInputs;
593
- return [3 /*break*/, 3];
594
- case 1:
595
- url = this.getEmbeddedAppUrl();
596
- this.logInfo("Reload window '".concat(windowId, "' for embedded app url '").concat(url, "'"));
358
+ if (!this.isEmbeddedApp()) return [3 /*break*/, 3];
359
+ if (!applicationVersion.embeddedUrlFormat) return [3 /*break*/, 2];
360
+ url = embeddedApps_1.default(this.presentation, applicationVersion);
361
+ this.logInfo("Reload window '" + windowId + "' for embedded app url '" + url + "'");
597
362
  return [4 /*yield*/, this.loadWindow(url)];
598
- case 2:
363
+ case 1:
599
364
  _b.sent();
600
- _b.label = 3;
601
- case 3: return [3 /*break*/, 5];
602
- case 4:
603
- this.logInfo("Reload window '".concat(windowId, "'"));
365
+ _b.label = 2;
366
+ case 2: return [3 /*break*/, 4];
367
+ case 3:
368
+ this.logInfo("Reload window '" + windowId + "'");
604
369
  this.sendRenderMessage();
605
- _b.label = 5;
606
- case 5: return [2 /*return*/];
370
+ _b.label = 4;
371
+ case 4: return [2 /*return*/];
607
372
  }
608
373
  });
609
374
  });
610
375
  };
611
376
  PresentationWindow.prototype.runGetProperties = function (builderState) {
612
- // Do no support conditional properties for embedded apps. We will likely
613
- // change the way conditional properties work.
614
- if (!this.isEmbeddedApp()) {
615
- this.sendMessageString('run_get_properties', builderState);
616
- }
617
- };
618
- PresentationWindow.prototype.createObjectURL = function (blob) {
619
- return __awaiter(this, void 0, void 0, function () {
620
- return __generator(this, function (_a) {
621
- if (this.isEmbeddedApp()) {
622
- return [2 /*return*/, this.createObjectURLForEmbeddedApp(blob)];
623
- }
624
- return [2 /*return*/, URL.createObjectURL(blob)];
625
- });
626
- });
627
- };
628
- PresentationWindow.prototype.sendChargeResponse = function (response) {
629
- // TODO: Instead of sending the charge to all windows, we should only send it to the app
630
- // that requested the charge. We probably don't want to use the windowId to avoid missing
631
- // the events in case the window was closed/restarted. Since we are only sending the charge
632
- // id and status this seems ok for now but need to be mindful of sending any sensitive data.
633
- this.sendMessageObject('payments-charge-response', {
634
- requestId: response.requestId,
635
- charge: response.charge,
636
- error: response.error,
637
- });
638
- // Forward the event to the child window managers.
639
- Object.values(this.windowManagers).forEach(function (wm) {
640
- return wm.sendChargeResponse(response);
641
- });
642
- };
643
- PresentationWindow.prototype.sendCharge = function (charge) {
644
- // TODO: Instead of sending the charge to all windows, we should only send it to the app
645
- // that requested the charge.
646
- if (this.paymentSubscriptions.has('charge')) {
647
- this.sendMessageObject('payments-charge-event', { charge: charge });
648
- }
649
- // Forward the event to the child window managers.
650
- Object.values(this.windowManagers).forEach(function (wm) { return wm.sendCharge(charge); });
651
- };
652
- PresentationWindow.prototype.sendTerminal = function (terminal) {
653
- if (this.paymentSubscriptions.has('terminal')) {
654
- this.sendMessageObject('payments-terminal-event', { terminal: terminal });
655
- }
656
- // Forward the event to the child window managers.
657
- Object.values(this.windowManagers).forEach(function (wm) {
658
- return wm.sendTerminal(terminal);
659
- });
377
+ this.sendMessage('run_get_properties', builderState);
660
378
  };
661
379
  PresentationWindow.prototype.isEmbeddedApp = function () {
662
380
  var _a = this.options, applicationVersion = _a.applicationVersion, isPreview = _a.isPreview;
663
381
  // If the application has a source url, always use it for rendering the preview.
664
- // This fixes an issue with Hoopla which is an embedded app but uses a legacy app
382
+ // This fixes an issue with Hoopla which is an embedded app but uses a Raydiant app
665
383
  // for it's preview.
666
384
  if (isPreview && applicationVersion.sourceUrl) {
667
385
  return false;
@@ -690,17 +408,6 @@ var PresentationWindow = /** @class */ (function () {
690
408
  }
691
409
  }
692
410
  };
693
- PresentationWindow.prototype.getFullAppRendererUrl = function (_a) {
694
- var appRendererUrl = _a.appRendererUrl, windowId = _a.windowId, appRendererOfflineSupport = _a.appRendererOfflineSupport;
695
- var url = new URL(appRendererUrl);
696
- var hashParams = new URLSearchParams(url.hash.slice(1));
697
- hashParams.set('__raydiantWindowId', windowId);
698
- if (appRendererOfflineSupport === true) {
699
- hashParams.set('__raydiantOfflineSupport', 'true');
700
- }
701
- url.hash = hashParams.toString();
702
- return url.toString();
703
- };
704
411
  PresentationWindow.prototype.loadEmbeddedApp = function () {
705
412
  return __awaiter(this, void 0, void 0, function () {
706
413
  var _a, windowId, applicationVersion, url;
@@ -709,15 +416,20 @@ var PresentationWindow = /** @class */ (function () {
709
416
  case 0:
710
417
  _a = this.options, windowId = _a.windowId, applicationVersion = _a.applicationVersion;
711
418
  if (!applicationVersion.embeddedUrlFormat) {
712
- throw new Error("Error loading embedded app, missing embeddedUrlFormat for '".concat(applicationVersion.id, "'"));
713
- }
714
- url = this.getEmbeddedAppUrl();
715
- this.logInfo("Create window '".concat(windowId, "' for embedded app url '").concat(url, "'"));
716
- return [4 /*yield*/, this.createAndLoadWindow(url,
717
- // Embedded apps should not have a backgroundColor because some sites expect
718
- // the browser default of white will be applied.
719
- '#ffffff', this.handleEmbeddedMessage)];
419
+ throw new Error("Error loading embedded app, missing embeddedUrlFormat for '" + applicationVersion.id + "'");
420
+ }
421
+ url = embeddedApps_1.default(this.presentation, applicationVersion);
422
+ this.logInfo("Create window '" + windowId + "' for embedded app url '" + url + "'");
423
+ // Embedded apps should not have a backgroundColor bexcause some sites expect
424
+ // the browser default of white will be applied. We also don't attach the message
425
+ // listeners for embedded apps. We could eventually allow embedded apps to send
426
+ // lifecycle events but we should consider namespacing our message events.
427
+ return [4 /*yield*/, this.createAndLoadWindow(url, '#ffffff')];
720
428
  case 1:
429
+ // Embedded apps should not have a backgroundColor bexcause some sites expect
430
+ // the browser default of white will be applied. We also don't attach the message
431
+ // listeners for embedded apps. We could eventually allow embedded apps to send
432
+ // lifecycle events but we should consider namespacing our message events.
721
433
  _b.sent();
722
434
  this.didEmbeddedAppLoad = true;
723
435
  this.checkIsReadyCallback();
@@ -726,20 +438,17 @@ var PresentationWindow = /** @class */ (function () {
726
438
  });
727
439
  });
728
440
  };
729
- PresentationWindow.prototype.loadLegacyApp = function () {
441
+ PresentationWindow.prototype.loadRaydiantApp = function () {
730
442
  return __awaiter(this, void 0, void 0, function () {
731
- var _a, windowId, _b, appRendererUrl, appRendererOfflineSupport, backgroundColor;
443
+ var _a, windowId, _b, appRendererUrl, backgroundColor, url;
732
444
  return __generator(this, function (_c) {
733
445
  switch (_c.label) {
734
446
  case 0:
735
- _a = this.options, windowId = _a.windowId, _b = _a.appRendererUrl, appRendererUrl = _b === void 0 ? defaultAppRendererUrl : _b, appRendererOfflineSupport = _a.appRendererOfflineSupport, backgroundColor = _a.backgroundColor;
736
- this.logInfo("Create window '".concat(windowId, "'"));
737
- return [4 /*yield*/, this.createAndLoadWindow(this.getFullAppRendererUrl({
738
- appRendererUrl: appRendererUrl,
739
- windowId: windowId,
740
- appRendererOfflineSupport: appRendererOfflineSupport,
741
- }), backgroundColor || '#000000', // Default to black bg for Raydiant apps
742
- this.handleLegacyMessage)];
447
+ _a = this.options, windowId = _a.windowId, _b = _a.appRendererUrl, appRendererUrl = _b === void 0 ? defaultAppRendererUrl : _b, backgroundColor = _a.backgroundColor;
448
+ url = appRendererUrl + "#windowId=" + windowId;
449
+ this.logInfo("Create window '" + windowId + "'");
450
+ return [4 /*yield*/, this.createAndLoadWindow(url, backgroundColor || '#000000', // Default to black bg for Raydiant apps
451
+ this.handleMessage)];
743
452
  case 1:
744
453
  _c.sent();
745
454
  return [4 /*yield*/, this.waitForPesentationReady()];
@@ -763,14 +472,14 @@ var PresentationWindow = /** @class */ (function () {
763
472
  bounds: bounds,
764
473
  backgroundColor: backgroundColor,
765
474
  receiveMessageCallback: receiveMessageCallback,
766
- errorCallback: this.handleError,
475
+ errorCallback: this.handleError
767
476
  });
768
477
  // Mute new window. This ensures preloaded windows are muted by default and
769
478
  // prevents opening an audio channel on the device for SYB playback. When using
770
479
  // the BrowserWindowRenderer this will call setAudioMuted(true) but the IFrameRenderer
771
480
  // has no API for muting so we rely on apps that use mute presentation props to be
772
481
  // initially muted before playing.
773
- this.logInfo("Mute window ".concat(windowId));
482
+ this.logInfo("Mute window " + windowId);
774
483
  renderer.muteWindow(windowId);
775
484
  return [4 /*yield*/, this.loadWindow(url)];
776
485
  case 1:
@@ -793,31 +502,22 @@ var PresentationWindow = /** @class */ (function () {
793
502
  return [4 /*yield*/, renderer.loadWindow(windowId, url)];
794
503
  case 2:
795
504
  _b.sent();
796
- this.logInfo("Loaded window '".concat(windowId, "'"));
505
+ this.logInfo("Loaded window '" + windowId + "'");
797
506
  return [3 /*break*/, 4];
798
507
  case 3:
799
508
  err_2 = _b.sent();
800
- this.handleError(new WindowLoadError_1.default("Failed to load window with '".concat(err_2.message, "'")));
509
+ this.handleError(new WindowLoadError_1.default("Failed to load window with '" + err_2.message + "'"));
801
510
  return [3 /*break*/, 4];
802
511
  case 4: return [2 /*return*/];
803
512
  }
804
513
  });
805
514
  });
806
515
  };
807
- // Send a JSON stringified message to the renderer. This is the legacy way of sending
808
- // messages and should be deprecated in favor of sendMessageObject.
809
- PresentationWindow.prototype.sendMessageString = function (type, payload) {
516
+ PresentationWindow.prototype.sendMessage = function (type, payload) {
810
517
  var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
811
518
  var message = JSON.stringify({ type: type, payload: payload, windowId: windowId });
812
- this.logInfo("Sending '".concat(type, "' to window '").concat(windowId, "'"));
813
- renderer.sendMessageString(windowId, message);
814
- };
815
- // Send a message object to the renderer. This is the preferred way of sending messages
816
- // going forward since it allows for more complex payloads like ArrayBuffers (for File Inputs).
817
- PresentationWindow.prototype.sendMessageObject = function (type, payload) {
818
- var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
819
- this.logInfo("Sending '".concat(type, "' to window '").concat(windowId, "'"));
820
- renderer.sendMessageObject(windowId, type, payload);
519
+ this.logInfo("Sending '" + type + "' to window '" + windowId + "'");
520
+ renderer.sendMessage(windowId, message);
821
521
  };
822
522
  PresentationWindow.prototype.waitForPesentationReady = function () {
823
523
  var _this = this;
@@ -834,7 +534,7 @@ var PresentationWindow = /** @class */ (function () {
834
534
  clearTimeout(_this.readyTimeout);
835
535
  }
836
536
  _this.readyTimeout = setTimeout(function () {
837
- _this.handleError(new WindowTimeoutError_1.default("Window ".concat(windowId, " timed out after ").concat(readyTimeoutDurationSeconds, " seconds")));
537
+ _this.handleError(new WindowTimeoutError_1.default("Window " + windowId + " timed out after " + readyTimeoutDurationSeconds + " seconds"));
838
538
  // Resolve the promise is the window times out. This ensures windowManager.load() resolves
839
539
  // even if the current window times out. Fixes an issue where the boot screen isn't removed
840
540
  // if the first presentation times out.
@@ -870,26 +570,26 @@ var PresentationWindow = /** @class */ (function () {
870
570
  // IFrames do not have a mute/unmute API so we are overriding any mute properties
871
571
  // to support muting MZ zones when using the IFrameRenderer (SecondScreen).
872
572
  if (this.forceMute) {
873
- this.sendMessageString('render', {
573
+ this.sendMessage('render', {
874
574
  builderState: this.builderState,
875
- presentation: __assign(__assign({}, this.presentation), { applicationVariables: __assign(__assign({}, this.presentation.applicationVariables), {
575
+ presentation: __assign({}, this.presentation, { applicationVariables: __assign({}, this.presentation.applicationVariables, {
876
576
  // TODO: We need a better way to identify mute properties (ie. PropType.mute())
877
577
  // Force mute the presentation, existing apps use either mute or muted.
878
578
  mute: true, muted: true }) }),
879
579
  theme: this.buildTheme(),
880
580
  applicationVersion: applicationVersion,
881
581
  device: device,
882
- isPreview: isPreview,
582
+ isPreview: isPreview
883
583
  });
884
584
  }
885
585
  else {
886
- this.sendMessageString('render', {
586
+ this.sendMessage('render', {
887
587
  builderState: this.builderState,
888
588
  presentation: this.presentation,
889
589
  theme: this.buildTheme(),
890
590
  applicationVersion: applicationVersion,
891
591
  device: device,
892
- isPreview: isPreview,
592
+ isPreview: isPreview
893
593
  });
894
594
  }
895
595
  };
@@ -911,14 +611,14 @@ var PresentationWindow = /** @class */ (function () {
911
611
  prevRuleEngine = windowManager.getRuleEngine();
912
612
  prevForceMute = windowManager.getForceMute();
913
613
  didBoundsChange = prevBounds
914
- ? !(0, fast_deep_equal_1.default)(bounds, prevBounds)
614
+ ? !fast_deep_equal_1.default(bounds, prevBounds)
915
615
  : true;
916
616
  if (didBoundsChange) {
917
617
  windowManager.updateBounds(bounds);
918
618
  }
919
619
  didForceMuteChange = forceMute !== prevForceMute;
920
620
  didThemeOverrideChange = prevThemeOverride
921
- ? !(0, fast_deep_equal_1.default)(themeOverride, prevThemeOverride)
621
+ ? !fast_deep_equal_1.default(themeOverride, prevThemeOverride)
922
622
  : true;
923
623
  if (didForceMuteChange || didThemeOverrideChange) {
924
624
  windowManager.setThemeOverride(themeOverride);
@@ -946,15 +646,14 @@ var PresentationWindow = /** @class */ (function () {
946
646
  x: bounds.x,
947
647
  y: bounds.y,
948
648
  width: bounds.width,
949
- height: bounds.height,
649
+ height: bounds.height
950
650
  },
951
651
  backgroundColor: 'transparent',
952
652
  themeOverride: themeOverride,
953
653
  forceMute: forceMute,
954
654
  isPreview: isPreview,
955
655
  onEnableInterruptLock: function () { return _this.enableInteruptLock(windowName); },
956
- onDisableInterruptLock: function () { return _this.disableInteruptLock(windowName); },
957
- getTerminal: this.options.getTerminal,
656
+ onDisableInterruptLock: function () { return _this.disableInteruptLock(windowName); }
958
657
  });
959
658
  // Hook up child window manager events to bubble up to the parent.
960
659
  if (parentWindowManager) {
@@ -970,12 +669,6 @@ var PresentationWindow = /** @class */ (function () {
970
669
  windowManager.on('window_end_error', function (metadata) {
971
670
  parentWindowManager.emit('window_end_error', metadata);
972
671
  });
973
- windowManager.on('window_analytics_event', function (metadata) {
974
- parentWindowManager.emit('window_analytics_event', metadata);
975
- });
976
- windowManager.on('window_charge_request', function (metadata) {
977
- parentWindowManager.emit('window_charge_request', metadata);
978
- });
979
672
  }
980
673
  this.windowManagers[windowName] = windowManager;
981
674
  windowManager.setRenderer(renderer);
@@ -1012,7 +705,7 @@ var PresentationWindow = /** @class */ (function () {
1012
705
  delete this.windowManagers[windowName];
1013
706
  }
1014
707
  else {
1015
- this.logWarning("Failed to close child window manager for '".concat(windowName, "'."));
708
+ this.logWarning("Failed to close child window manager for '" + windowName + "'.");
1016
709
  }
1017
710
  };
1018
711
  PresentationWindow.prototype.enableInteruptLock = function (windowName) {
@@ -1041,28 +734,6 @@ var PresentationWindow = /** @class */ (function () {
1041
734
  this.disableInterruptLockCallback();
1042
735
  }
1043
736
  };
1044
- PresentationWindow.prototype.getEmbeddedAppUrl = function () {
1045
- var _a = this.options, windowId = _a.windowId, appRendererOfflineSupport = _a.appRendererOfflineSupport;
1046
- var metadata = {
1047
- renderMode: this.options.isPreview ? 'preview' : 'live',
1048
- };
1049
- var url = (0, embeddedApps_1.default)(this.presentation, this.options.applicationVersion, metadata);
1050
- return this.getFullAppRendererUrl({
1051
- appRendererUrl: url,
1052
- windowId: windowId,
1053
- appRendererOfflineSupport: appRendererOfflineSupport,
1054
- });
1055
- };
1056
- PresentationWindow.prototype.handleReady = function () {
1057
- this.didReceiveReady = true;
1058
- this.checkIsReadyCallback();
1059
- };
1060
- PresentationWindow.prototype.handleComplete = function () {
1061
- this.didReceiveComplete = true;
1062
- if (this.completeCallback) {
1063
- this.completeCallback();
1064
- }
1065
- };
1066
737
  PresentationWindow.prototype.logDebug = function (message) {
1067
738
  this.options.logger.debug(message, this.getLogContext());
1068
739
  };
@@ -1089,30 +760,12 @@ var PresentationWindow = /** @class */ (function () {
1089
760
  publishedAt: publishedAt,
1090
761
  playlistId: playlistId,
1091
762
  playlistName: playlistName,
1092
- rule: rule,
763
+ rule: rule
1093
764
  };
1094
765
  };
1095
766
  PresentationWindow.prototype.metadata = function () {
1096
767
  return this.getLogContext();
1097
768
  };
1098
- PresentationWindow.prototype.runWorkerSubscriptions = function (state) {
1099
- // For each worker subscription, compare the previous state to the new state.
1100
- // If the state has changed, send the new state to the subscription.
1101
- for (var _i = 0, _a = Array.from(this.workerSubscriptions); _i < _a.length; _i++) {
1102
- var workerName = _a[_i];
1103
- var workerState = state[workerName];
1104
- var previousWorkerState = this.workerState[workerName];
1105
- if (workerState !== undefined &&
1106
- !(0, fast_deep_equal_1.default)(workerState, previousWorkerState)) {
1107
- this.sendMessageString('worker-state', {
1108
- name: workerName,
1109
- state: workerState,
1110
- });
1111
- }
1112
- }
1113
- // Persist the new state so we can compare if the previous values have changed..
1114
- this.workerState = state;
1115
- };
1116
769
  PresentationWindow.prototype.createRuleEngine = function (playlistId) {
1117
770
  var globalRule = this.options.globalRule;
1118
771
  return new RE.RuleEngine(playlistId, this.ruleEngineState, globalRule
@@ -1125,15 +778,15 @@ var PresentationWindow = /** @class */ (function () {
1125
778
  {
1126
779
  type: 'equals',
1127
780
  left: { var: ['target', 'hasPlaylists'] },
1128
- right: { const: false },
1129
- },
1130
- ],
781
+ right: { const: false }
782
+ }
783
+ ]
1131
784
  }
1132
785
  : {
1133
786
  // A global rule was not provided so we don't need to combine the rule with an AND.
1134
787
  type: 'equals',
1135
788
  left: { var: ['target', 'hasPlaylists'] },
1136
- right: { const: false },
789
+ right: { const: false }
1137
790
  });
1138
791
  };
1139
792
  PresentationWindow.prototype.isValidOpenChildWindowPayload = function (payload) {
@@ -1170,72 +823,6 @@ var PresentationWindow = /** @class */ (function () {
1170
823
  var isMutedMultizone = appVars.muteZone1 === true && appVars.muteZone2 === true;
1171
824
  return isMutedMultizone;
1172
825
  };
1173
- PresentationWindow.prototype.createObjectURLForEmbeddedApp = function (blob) {
1174
- var _this = this;
1175
- return new Promise(function (resolve, reject) {
1176
- // Handle multiple concurrent createObjectURL calls by creating a request id for each
1177
- // call. We send the request id along with the message to the running app and the app
1178
- // sends the request id back with the result so we can resolve the correct promise.
1179
- var requestId = (0, uuid_1.v4)();
1180
- _this.createObjectURLResolvers[requestId] = resolve;
1181
- // Start a timer to reject the promise if the app doesn't respond with the create object
1182
- // url result within 1 second. This should be more or less instant.
1183
- _this.createObjectURLTimeouts[requestId] = setTimeout(function () {
1184
- var error = new Error("Timed out waiting for the create-object-url-result message for request id ".concat(requestId));
1185
- reject(error);
1186
- delete _this.createObjectURLResolvers[requestId];
1187
- delete _this.createObjectURLTimeouts[requestId];
1188
- }, 1000);
1189
- // Create a FileReader object to read the file data as an ArrayBuffer.
1190
- var reader = new FileReader();
1191
- reader.addEventListener('load', function () {
1192
- var buffer = reader.result;
1193
- // Check if buffer is an ArrayBuffer
1194
- if (buffer instanceof ArrayBuffer) {
1195
- // Send the ArrayBuffer to the running app to create the local file blob URL.
1196
- _this.sendMessageObject('create-object-url', { requestId: requestId, buffer: buffer });
1197
- }
1198
- }, false);
1199
- reader.readAsArrayBuffer(blob);
1200
- return '';
1201
- });
1202
- };
1203
826
  return PresentationWindow;
1204
827
  }());
1205
828
  exports.default = PresentationWindow;
1206
- var isValidCreateObjectURLResultPayload = function (payload) {
1207
- return (
1208
- // Ensure payload is an object.
1209
- typeof payload === 'object' &&
1210
- payload !== null &&
1211
- // Ensure requestId is a string.
1212
- 'requestId' in payload &&
1213
- typeof payload['requestId'] === 'string' &&
1214
- // Ensure payload.file is an object.
1215
- 'url' in payload &&
1216
- typeof payload['url'] === 'string');
1217
- };
1218
- var transformInputValues = function (inputs) {
1219
- var transformed = {};
1220
- // Recursively traverse inputs, transforming any file input values to remove internal
1221
- // properties like file_upload_id.
1222
- for (var _i = 0, _a = Object.entries(inputs); _i < _a.length; _i++) {
1223
- var _b = _a[_i], key = _b[0], value = _b[1];
1224
- if (typeof value === 'object' && value !== null && 'url' in value) {
1225
- // Value is a file input, strip out the file_upload_id property.
1226
- transformed[key] = { url: value.url };
1227
- }
1228
- else if (Array.isArray(value)) {
1229
- // Value is an array input, traverse each item in the array for file input values.
1230
- transformed[key] = [];
1231
- for (var _c = 0, value_1 = value; _c < value_1.length; _c++) {
1232
- var item = value_1[_c];
1233
- transformed[key].push(transformInputValues(item));
1234
- }
1235
- }
1236
- else {
1237
- transformed[key] = value;
1238
- }
1239
- }
1240
- return transformed;
1241
- };