@raydiant/playlist-window-manager 0.27.0 → 0.27.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.
- package/build/PresentationWindow.d.ts +1 -0
- package/build/PresentationWindow.js +30 -9
- package/build/PresentationWindow.test.js +26 -5
- package/build/embeddedApps.js +2 -0
- package/build/embeddedApps.test.js +8 -0
- package/build/testUtils.js +3 -0
- package/package.json +1 -1
- package/src/PresentationWindow.test.ts +27 -5
- package/src/PresentationWindow.ts +27 -2
- package/src/embeddedApps.test.ts +15 -0
- package/src/embeddedApps.ts +1 -0
- package/src/testUtils.ts +3 -0
|
@@ -659,17 +659,30 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
659
659
|
this.forceMute = forceMute;
|
|
660
660
|
};
|
|
661
661
|
PresentationWindow.prototype.reload = function () {
|
|
662
|
+
var _a;
|
|
662
663
|
return __awaiter(this, void 0, void 0, function () {
|
|
663
|
-
var
|
|
664
|
-
return __generator(this, function (
|
|
665
|
-
switch (
|
|
664
|
+
var _b, applicationVersion, windowId, updatedInputs, url;
|
|
665
|
+
return __generator(this, function (_c) {
|
|
666
|
+
switch (_c.label) {
|
|
666
667
|
case 0:
|
|
667
|
-
|
|
668
|
+
_b = this.options, applicationVersion = _b.applicationVersion, windowId = _b.windowId;
|
|
668
669
|
if (!this.isEmbeddedApp()) return [3 /*break*/, 4];
|
|
669
670
|
if (!applicationVersion.embeddedUrlFormat) return [3 /*break*/, 3];
|
|
670
671
|
if (!this.previewSubscriptions.has('inputs')) return [3 /*break*/, 1];
|
|
671
672
|
this.logInfo("Reload window '".concat(windowId, "' for embedded app preview state"));
|
|
672
673
|
updatedInputs = transformInputValues(this.presentation.applicationVariables);
|
|
674
|
+
// Add metadata to inputs if they exist in the URL template. These need to be
|
|
675
|
+
// consistent with metadata keys in embeddedApps.ts.
|
|
676
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$renderMode')) {
|
|
677
|
+
updatedInputs['$renderMode'] = this.getRenderMode();
|
|
678
|
+
}
|
|
679
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$token')) {
|
|
680
|
+
updatedInputs['$token'] = this.presentation.token;
|
|
681
|
+
}
|
|
682
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$deviceId')) {
|
|
683
|
+
updatedInputs['$deviceId'] = (_a = this.options.device) === null || _a === void 0 ? void 0 : _a.id;
|
|
684
|
+
}
|
|
685
|
+
// Send the updated inputs to the embedded app if they have changed.
|
|
673
686
|
if (!(0, fast_deep_equal_1.default)(updatedInputs, this.previewState.inputs)) {
|
|
674
687
|
this.sendMessageObject('preview-inputs', updatedInputs);
|
|
675
688
|
}
|
|
@@ -680,13 +693,13 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
680
693
|
this.logInfo("Reload window '".concat(windowId, "' for embedded app url '").concat(url, "'"));
|
|
681
694
|
return [4 /*yield*/, this.loadWindow(url)];
|
|
682
695
|
case 2:
|
|
683
|
-
|
|
684
|
-
|
|
696
|
+
_c.sent();
|
|
697
|
+
_c.label = 3;
|
|
685
698
|
case 3: return [3 /*break*/, 5];
|
|
686
699
|
case 4:
|
|
687
700
|
this.logInfo("Reload window '".concat(windowId, "'"));
|
|
688
701
|
this.sendRenderMessage();
|
|
689
|
-
|
|
702
|
+
_c.label = 5;
|
|
690
703
|
case 5: return [2 /*return*/];
|
|
691
704
|
}
|
|
692
705
|
});
|
|
@@ -1146,7 +1159,7 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
1146
1159
|
PresentationWindow.prototype.getEmbeddedAppUrl = function () {
|
|
1147
1160
|
var _a = this.options, windowId = _a.windowId, appRendererOfflineSupport = _a.appRendererOfflineSupport, device = _a.device;
|
|
1148
1161
|
var metadata = {
|
|
1149
|
-
renderMode: this.
|
|
1162
|
+
renderMode: this.getRenderMode(),
|
|
1150
1163
|
};
|
|
1151
1164
|
if (device) {
|
|
1152
1165
|
metadata.deviceId = device.id;
|
|
@@ -1378,6 +1391,9 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
1378
1391
|
}
|
|
1379
1392
|
this.previouslyLocked = currentlyLocked;
|
|
1380
1393
|
};
|
|
1394
|
+
PresentationWindow.prototype.getRenderMode = function () {
|
|
1395
|
+
return this.options.isPreview ? 'preview' : 'live';
|
|
1396
|
+
};
|
|
1381
1397
|
return PresentationWindow;
|
|
1382
1398
|
}());
|
|
1383
1399
|
exports.default = PresentationWindow;
|
|
@@ -1408,7 +1424,12 @@ var transformInputValues = function (inputs) {
|
|
|
1408
1424
|
transformed[key] = [];
|
|
1409
1425
|
for (var _c = 0, value_1 = value; _c < value_1.length; _c++) {
|
|
1410
1426
|
var item = value_1[_c];
|
|
1411
|
-
|
|
1427
|
+
if (typeof item === 'object' && item !== null) {
|
|
1428
|
+
transformed[key].push(transformInputValues(item));
|
|
1429
|
+
}
|
|
1430
|
+
else {
|
|
1431
|
+
transformed[key].push(item);
|
|
1432
|
+
}
|
|
1412
1433
|
}
|
|
1413
1434
|
}
|
|
1414
1435
|
else {
|
|
@@ -111,12 +111,21 @@ describe('embedded apps', function () {
|
|
|
111
111
|
window = (0, testUtils_1.createPresentationWindow)({
|
|
112
112
|
windowId: 'test-reload-message',
|
|
113
113
|
presentation: (0, testUtils_1.createPresentation)({
|
|
114
|
-
applicationVariables: {
|
|
114
|
+
applicationVariables: {
|
|
115
|
+
input: 'test',
|
|
116
|
+
multi: [],
|
|
117
|
+
},
|
|
118
|
+
token: 'token',
|
|
115
119
|
}),
|
|
116
120
|
applicationVersion: (0, testUtils_1.createApplicationVersion)({
|
|
117
|
-
embeddedUrlFormat: 'http://test.local/:input',
|
|
118
|
-
presentationProperties: [
|
|
121
|
+
embeddedUrlFormat: 'http://test.local/:input?renderMode=:$renderMode&token=:$token&deviceId=:$deviceId',
|
|
122
|
+
presentationProperties: [
|
|
123
|
+
{ name: 'input', type: 'string' },
|
|
124
|
+
{ name: 'multi', type: 'select' },
|
|
125
|
+
],
|
|
119
126
|
}),
|
|
127
|
+
isPreview: true,
|
|
128
|
+
device: { id: 'device-id', name: 'device-name' },
|
|
120
129
|
renderer: testRenderer,
|
|
121
130
|
});
|
|
122
131
|
return [4 /*yield*/, window.load()];
|
|
@@ -124,13 +133,25 @@ describe('embedded apps', function () {
|
|
|
124
133
|
_a.sent();
|
|
125
134
|
// Subscribe to receive input updates via message.
|
|
126
135
|
testRenderer.runReceiveMessageCallback('preview-subscribe', 'inputs');
|
|
127
|
-
window.setPresentation((0, testUtils_1.createPresentation)({
|
|
136
|
+
window.setPresentation((0, testUtils_1.createPresentation)({
|
|
137
|
+
applicationVariables: {
|
|
138
|
+
input: 'updated',
|
|
139
|
+
multi: ['a', 'b', 'c'],
|
|
140
|
+
},
|
|
141
|
+
token: 'token',
|
|
142
|
+
}), (0, testUtils_1.createPlaylistWindowManagerState)(), (0, testUtils_1.createRuleEngineState)());
|
|
128
143
|
return [4 /*yield*/, window.reload()];
|
|
129
144
|
case 2:
|
|
130
145
|
_a.sent();
|
|
131
146
|
// loadWindow should only be called once for the initial load.
|
|
132
147
|
expect(testRenderer.loadWindow).toHaveBeenCalledTimes(1);
|
|
133
|
-
expect(testRenderer.sendMessageObject).toHaveBeenCalledWith('test-reload-message', 'preview-inputs', {
|
|
148
|
+
expect(testRenderer.sendMessageObject).toHaveBeenCalledWith('test-reload-message', 'preview-inputs', {
|
|
149
|
+
$renderMode: 'preview',
|
|
150
|
+
$token: 'token',
|
|
151
|
+
$deviceId: 'device-id',
|
|
152
|
+
input: 'updated',
|
|
153
|
+
multi: ['a', 'b', 'c'],
|
|
154
|
+
});
|
|
134
155
|
// sendMessageObject should not be called again for the same inputs.
|
|
135
156
|
return [4 /*yield*/, window.reload()];
|
|
136
157
|
case 3:
|
package/build/embeddedApps.js
CHANGED
|
@@ -56,6 +56,8 @@ function createEmbeddedApp(presentation, applicationVersion, metadata) {
|
|
|
56
56
|
value = presentation.applicationVariables[queryParamName];
|
|
57
57
|
if (value === undefined)
|
|
58
58
|
value = '';
|
|
59
|
+
if (value === null)
|
|
60
|
+
value = '';
|
|
59
61
|
if (Array.isArray(value)) {
|
|
60
62
|
value = JSON.stringify(value);
|
|
61
63
|
}
|
|
@@ -149,3 +149,11 @@ test('Replaces $deviceId with empty string when in the query string and metadata
|
|
|
149
149
|
});
|
|
150
150
|
expect((0, embeddedApps_1.default)(presentation, applicationVersion, createMetadata())).toBe("https://example.com/content?device=");
|
|
151
151
|
});
|
|
152
|
+
test('Replaces null with empty string', function () {
|
|
153
|
+
expect((0, embeddedApps_1.default)(createPresentation({
|
|
154
|
+
applicationVariables: { file: null },
|
|
155
|
+
}), createApplicationVersion({
|
|
156
|
+
embeddedUrlFormat: "https://example.come?image=:file",
|
|
157
|
+
presentationProperties: [{ type: 'file', name: 'file' }],
|
|
158
|
+
}), createMetadata())).toBe("https://example.come?image=");
|
|
159
|
+
});
|
package/build/testUtils.js
CHANGED
|
@@ -99,6 +99,8 @@ function createPresentationWindow(overrides) {
|
|
|
99
99
|
unMuteWindow: function () { },
|
|
100
100
|
},
|
|
101
101
|
getTerminal: overrides.getTerminal,
|
|
102
|
+
isPreview: overrides.isPreview,
|
|
103
|
+
device: overrides.device,
|
|
102
104
|
});
|
|
103
105
|
}
|
|
104
106
|
exports.createPresentationWindow = createPresentationWindow;
|
|
@@ -113,6 +115,7 @@ function createPresentation(overrides) {
|
|
|
113
115
|
applicationVariables: (_e = overrides.applicationVariables) !== null && _e !== void 0 ? _e : {},
|
|
114
116
|
duration: (_f = overrides.duration) !== null && _f !== void 0 ? _f : 1,
|
|
115
117
|
r: createPresentationRelationships(overrides.r),
|
|
118
|
+
token: overrides.token,
|
|
116
119
|
};
|
|
117
120
|
}
|
|
118
121
|
exports.createPresentation = createPresentation;
|
package/package.json
CHANGED
|
@@ -81,12 +81,22 @@ describe('embedded apps', () => {
|
|
|
81
81
|
const window = createPresentationWindow({
|
|
82
82
|
windowId: 'test-reload-message',
|
|
83
83
|
presentation: createPresentation({
|
|
84
|
-
applicationVariables: {
|
|
84
|
+
applicationVariables: {
|
|
85
|
+
input: 'test',
|
|
86
|
+
multi: [],
|
|
87
|
+
},
|
|
88
|
+
token: 'token',
|
|
85
89
|
}),
|
|
86
90
|
applicationVersion: createApplicationVersion({
|
|
87
|
-
embeddedUrlFormat:
|
|
88
|
-
|
|
91
|
+
embeddedUrlFormat:
|
|
92
|
+
'http://test.local/:input?renderMode=:$renderMode&token=:$token&deviceId=:$deviceId',
|
|
93
|
+
presentationProperties: [
|
|
94
|
+
{ name: 'input', type: 'string' },
|
|
95
|
+
{ name: 'multi', type: 'select' },
|
|
96
|
+
],
|
|
89
97
|
}),
|
|
98
|
+
isPreview: true,
|
|
99
|
+
device: { id: 'device-id', name: 'device-name' },
|
|
90
100
|
renderer: testRenderer,
|
|
91
101
|
});
|
|
92
102
|
|
|
@@ -96,7 +106,13 @@ describe('embedded apps', () => {
|
|
|
96
106
|
testRenderer.runReceiveMessageCallback('preview-subscribe', 'inputs');
|
|
97
107
|
|
|
98
108
|
window.setPresentation(
|
|
99
|
-
createPresentation({
|
|
109
|
+
createPresentation({
|
|
110
|
+
applicationVariables: {
|
|
111
|
+
input: 'updated',
|
|
112
|
+
multi: ['a', 'b', 'c'],
|
|
113
|
+
},
|
|
114
|
+
token: 'token',
|
|
115
|
+
}),
|
|
100
116
|
createPlaylistWindowManagerState(),
|
|
101
117
|
createRuleEngineState()
|
|
102
118
|
);
|
|
@@ -109,7 +125,13 @@ describe('embedded apps', () => {
|
|
|
109
125
|
expect(testRenderer.sendMessageObject).toHaveBeenCalledWith(
|
|
110
126
|
'test-reload-message',
|
|
111
127
|
'preview-inputs',
|
|
112
|
-
{
|
|
128
|
+
{
|
|
129
|
+
$renderMode: 'preview',
|
|
130
|
+
$token: 'token',
|
|
131
|
+
$deviceId: 'device-id',
|
|
132
|
+
input: 'updated',
|
|
133
|
+
multi: ['a', 'b', 'c'],
|
|
134
|
+
}
|
|
113
135
|
);
|
|
114
136
|
|
|
115
137
|
// sendMessageObject should not be called again for the same inputs.
|
|
@@ -427,6 +427,8 @@ export default class PresentationWindow {
|
|
|
427
427
|
|
|
428
428
|
if (this.isEmbeddedApp()) {
|
|
429
429
|
if (applicationVersion.embeddedUrlFormat) {
|
|
430
|
+
// If the embedded app has subscribed to inputs event, send it the updated inputs
|
|
431
|
+
// with postMessage. Otherwise, reload the window with the new inputs.
|
|
430
432
|
if (this.previewSubscriptions.has('inputs')) {
|
|
431
433
|
this.logInfo(
|
|
432
434
|
`Reload window '${windowId}' for embedded app preview state`
|
|
@@ -436,6 +438,21 @@ export default class PresentationWindow {
|
|
|
436
438
|
this.presentation.applicationVariables
|
|
437
439
|
);
|
|
438
440
|
|
|
441
|
+
// Add metadata to inputs if they exist in the URL template. These need to be
|
|
442
|
+
// consistent with metadata keys in embeddedApps.ts.
|
|
443
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$renderMode')) {
|
|
444
|
+
updatedInputs['$renderMode'] = this.getRenderMode();
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$token')) {
|
|
448
|
+
updatedInputs['$token'] = this.presentation.token;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$deviceId')) {
|
|
452
|
+
updatedInputs['$deviceId'] = this.options.device?.id;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Send the updated inputs to the embedded app if they have changed.
|
|
439
456
|
if (!deepEqual(updatedInputs, this.previewState.inputs)) {
|
|
440
457
|
this.sendMessageObject('preview-inputs', updatedInputs);
|
|
441
458
|
}
|
|
@@ -956,7 +973,7 @@ export default class PresentationWindow {
|
|
|
956
973
|
const { windowId, appRendererOfflineSupport, device } = this.options;
|
|
957
974
|
|
|
958
975
|
const metadata: EmbeddedAppMetadata = {
|
|
959
|
-
renderMode: this.
|
|
976
|
+
renderMode: this.getRenderMode(),
|
|
960
977
|
};
|
|
961
978
|
|
|
962
979
|
if (device) {
|
|
@@ -1630,6 +1647,10 @@ export default class PresentationWindow {
|
|
|
1630
1647
|
|
|
1631
1648
|
this.previouslyLocked = currentlyLocked;
|
|
1632
1649
|
}
|
|
1650
|
+
|
|
1651
|
+
private getRenderMode() {
|
|
1652
|
+
return this.options.isPreview ? 'preview' : 'live';
|
|
1653
|
+
}
|
|
1633
1654
|
}
|
|
1634
1655
|
|
|
1635
1656
|
const isValidCreateObjectURLResultPayload = (
|
|
@@ -1661,7 +1682,11 @@ const transformInputValues = (inputs: Record<string, any>) => {
|
|
|
1661
1682
|
// Value is an array input, traverse each item in the array for file input values.
|
|
1662
1683
|
transformed[key] = [];
|
|
1663
1684
|
for (const item of value) {
|
|
1664
|
-
|
|
1685
|
+
if (typeof item === 'object' && item !== null) {
|
|
1686
|
+
transformed[key].push(transformInputValues(item));
|
|
1687
|
+
} else {
|
|
1688
|
+
transformed[key].push(item);
|
|
1689
|
+
}
|
|
1665
1690
|
}
|
|
1666
1691
|
} else {
|
|
1667
1692
|
transformed[key] = value;
|
package/src/embeddedApps.test.ts
CHANGED
|
@@ -277,3 +277,18 @@ test('Replaces $deviceId with empty string when in the query string and metadata
|
|
|
277
277
|
createEmbeddedApp(presentation, applicationVersion, createMetadata())
|
|
278
278
|
).toBe(`https://example.com/content?device=`);
|
|
279
279
|
});
|
|
280
|
+
|
|
281
|
+
test('Replaces null with empty string', () => {
|
|
282
|
+
expect(
|
|
283
|
+
createEmbeddedApp(
|
|
284
|
+
createPresentation({
|
|
285
|
+
applicationVariables: { file: null },
|
|
286
|
+
}),
|
|
287
|
+
createApplicationVersion({
|
|
288
|
+
embeddedUrlFormat: `https://example.come?image=:file`,
|
|
289
|
+
presentationProperties: [{ type: 'file', name: 'file' }],
|
|
290
|
+
}),
|
|
291
|
+
createMetadata()
|
|
292
|
+
)
|
|
293
|
+
).toBe(`https://example.come?image=`);
|
|
294
|
+
});
|
package/src/embeddedApps.ts
CHANGED
package/src/testUtils.ts
CHANGED
|
@@ -39,6 +39,8 @@ export function createPresentationWindow(
|
|
|
39
39
|
unMuteWindow() {},
|
|
40
40
|
},
|
|
41
41
|
getTerminal: overrides.getTerminal,
|
|
42
|
+
isPreview: overrides.isPreview,
|
|
43
|
+
device: overrides.device,
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -54,6 +56,7 @@ export function createPresentation(
|
|
|
54
56
|
applicationVariables: overrides.applicationVariables ?? {},
|
|
55
57
|
duration: overrides.duration ?? 1,
|
|
56
58
|
r: createPresentationRelationships(overrides.r),
|
|
59
|
+
token: overrides.token,
|
|
57
60
|
};
|
|
58
61
|
}
|
|
59
62
|
|