@plattar/plattar-ar-adapter 1.154.2 → 1.155.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,168 @@
1
1
  (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PlattarARAdapter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ConfiguratorAR = void 0;
8
+ const plattar_analytics_1 = require("@plattar/plattar-analytics");
9
+ const plattar_api_1 = require("@plattar/plattar-api");
10
+ const plattar_services_1 = require("@plattar/plattar-services");
11
+ const util_1 = require("../util/util");
12
+ const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer"));
13
+ const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer"));
14
+ const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer"));
15
+ const launcher_ar_1 = require("./launcher-ar");
16
+ const version_1 = __importDefault(require("../version"));
17
+ /**
18
+ * Performs AR functionality related to Plattar Scenes
19
+ */
20
+ class ConfiguratorAR extends launcher_ar_1.LauncherAR {
21
+ constructor(state) {
22
+ super();
23
+ // analytics instance
24
+ this._analytics = null;
25
+ if (!state) {
26
+ throw new Error("ConfiguratorAR.constructor(state) - state must be defined");
27
+ }
28
+ this._state = state;
29
+ this._ar = null;
30
+ }
31
+ _SetupAnalytics() {
32
+ const scene = this._state.scene;
33
+ let analytics = null;
34
+ // setup scene stuff (if any)
35
+ if (scene) {
36
+ analytics = new plattar_analytics_1.Analytics(scene.attributes.application_id);
37
+ analytics.origin = plattar_api_1.Server.location().type;
38
+ this._analytics = analytics;
39
+ analytics.data.push("type", "scene-ar");
40
+ analytics.data.push("sdkVersion", version_1.default);
41
+ analytics.data.push("sceneId", scene.id);
42
+ analytics.data.push("sceneTitle", scene.attributes.title);
43
+ const application = scene.relationships.find(plattar_api_1.Project);
44
+ // setup application stuff (if any)
45
+ if (application) {
46
+ analytics.data.push("applicationId", application.id);
47
+ analytics.data.push("applicationTitle", application.attributes.title);
48
+ }
49
+ }
50
+ }
51
+ /**
52
+ * Composes a Scene into an AR Model (remote operation) that can be used to launch
53
+ * an AR File
54
+ */
55
+ async _Compose(output) {
56
+ const objects = this._state.state.array();
57
+ if (objects.length <= 0) {
58
+ throw new Error("ConfiguratorAR.Compose() - cannot proceed as scene does not contain AR components");
59
+ }
60
+ // define our configurator
61
+ const configurator = new plattar_services_1.Configurator();
62
+ configurator.server = plattar_api_1.Server.location().type;
63
+ configurator.output = output;
64
+ let totalARObjectCount = 0;
65
+ objects.forEach((object) => {
66
+ if (object.meta_data.augment) {
67
+ if (object.meta_data.type === "scenemodel") {
68
+ configurator.addModel(object.scene_product_id);
69
+ }
70
+ else {
71
+ configurator.addSceneProduct(object.scene_product_id, object.product_variation_id);
72
+ }
73
+ totalARObjectCount++;
74
+ }
75
+ });
76
+ if (totalARObjectCount <= 0) {
77
+ throw new Error("ConfiguratorAR.Compose() - cannot proceed as scene does not contain any enabled AR components");
78
+ }
79
+ const results = await configurator.get();
80
+ return results.filename;
81
+ }
82
+ /**
83
+ * Initialise the SceneAR instance. This returns a Promise that resolves
84
+ * successfully if initialisation is successful, otherwise it will fail.
85
+ *
86
+ * filure can occur for a number of reasons but it generally means that AR
87
+ * cannot be performed.
88
+ */
89
+ async init() {
90
+ if (!util_1.Util.canAugment()) {
91
+ throw new Error("ConfiguratorAR.init() - cannot proceed as AR not available in context");
92
+ }
93
+ const scene = this._state.scene;
94
+ this._SetupAnalytics();
95
+ const sceneOpt = scene.attributes.custom_json || {};
96
+ // we need to define our AR module here
97
+ // we are in Safari/Quicklook mode here
98
+ if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) {
99
+ // we need to launch a VTO experience here
100
+ // VTO requires Reality Support
101
+ if (sceneOpt.anchor === "face") {
102
+ if (util_1.Util.canRealityViewer()) {
103
+ const modelUrl = await this._Compose("vto");
104
+ this._ar = new reality_viewer_1.default();
105
+ this._ar.modelUrl = modelUrl;
106
+ return this;
107
+ }
108
+ else {
109
+ throw new Error("ConfiguratorAR.init() - cannot proceed as VTO AR requires Reality Viewer support");
110
+ }
111
+ }
112
+ // otherwise, load the USDZ stuff second if available
113
+ if (util_1.Util.canQuicklook()) {
114
+ const modelUrl = await this._Compose("usdz");
115
+ this._ar = new quicklook_viewer_1.default();
116
+ this._ar.modelUrl = modelUrl;
117
+ return this;
118
+ }
119
+ throw new Error("ConfiguratorAR.init() - cannot proceed as IOS device does not support AR Mode");
120
+ }
121
+ // check android
122
+ if (util_1.Util.canSceneViewer()) {
123
+ const modelUrl = await this._Compose("glb");
124
+ const arviewer = new scene_viewer_1.default();
125
+ arviewer.modelUrl = modelUrl;
126
+ arviewer.isVertical = this.options.anchor === "vertical" ? true : false;
127
+ if (sceneOpt.anchor === "vertical") {
128
+ arviewer.isVertical = true;
129
+ }
130
+ this._ar = arviewer;
131
+ return this;
132
+ }
133
+ // otherwise, we didn't have AR available - it should never really reach this stage as this should be caught
134
+ // earlier in the process
135
+ throw new Error("ConfiguratorAR.init() - could not initialise AR correctly, check values");
136
+ }
137
+ start() {
138
+ if (!this._ar) {
139
+ throw new Error("SceneAR.start() - cannot proceed as AR instance is null");
140
+ }
141
+ const analytics = this._analytics;
142
+ if (analytics) {
143
+ analytics.data.push("device", this._ar.device);
144
+ analytics.data.push("eventCategory", this._ar.nodeType);
145
+ analytics.data.push("eventAction", "Start Scene Augment");
146
+ analytics.write();
147
+ analytics.startRecordEngagement();
148
+ }
149
+ // this was initialised via the init() function
150
+ this._ar.start();
151
+ }
152
+ canQuicklook() {
153
+ return this._ar && this._ar.nodeType === "Quick Look" ? true : false;
154
+ }
155
+ canRealityViewer() {
156
+ return this._ar && this._ar.nodeType === "Reality Viewer" ? true : false;
157
+ }
158
+ canSceneViewer() {
159
+ return this._ar && this._ar.nodeType === "Scene Viewer" ? true : false;
160
+ }
161
+ }
162
+ exports.ConfiguratorAR = ConfiguratorAR;
163
+
164
+ },{"../util/util":15,"../version":16,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":2,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44,"@plattar/plattar-services":115}],2:[function(require,module,exports){
165
+ "use strict";
3
166
  Object.defineProperty(exports, "__esModule", { value: true });
4
167
  exports.LauncherAR = void 0;
5
168
  class LauncherAR {
@@ -12,13 +175,9 @@ class LauncherAR {
12
175
  * Initialise and launch with a single function call. this is mostly for convenience.
13
176
  * Use .init() and .start() separately for fine-grained control
14
177
  */
15
- launch() {
16
- return new Promise((accept, reject) => {
17
- this.init().then((value) => {
18
- value.start();
19
- return accept();
20
- }).catch(reject);
21
- });
178
+ async launch() {
179
+ const value = await this.init();
180
+ return value.start();
22
181
  }
23
182
  /**
24
183
  * AR Options used for launching AR
@@ -29,7 +188,7 @@ class LauncherAR {
29
188
  }
30
189
  exports.LauncherAR = LauncherAR;
31
190
 
32
- },{}],2:[function(require,module,exports){
191
+ },{}],3:[function(require,module,exports){
33
192
  "use strict";
34
193
  var __importDefault = (this && this.__importDefault) || function (mod) {
35
194
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -43,6 +202,7 @@ const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer"
43
202
  const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer"));
44
203
  const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer"));
45
204
  const launcher_ar_1 = require("./launcher-ar");
205
+ const version_1 = __importDefault(require("../version"));
46
206
  /**
47
207
  * Performs AT Functionality using Plattar FileModel types
48
208
  */
@@ -68,6 +228,7 @@ class ModelAR extends launcher_ar_1.LauncherAR {
68
228
  analytics = new plattar_analytics_1.Analytics(project.id);
69
229
  analytics.origin = plattar_api_1.Server.location().type;
70
230
  analytics.data.push("type", "model-ar");
231
+ analytics.data.push("sdkVersion", version_1.default);
71
232
  analytics.data.push("applicationId", project.id);
72
233
  analytics.data.push("applicationTitle", project.attributes.title);
73
234
  analytics.data.push("modelId", model.id);
@@ -154,7 +315,7 @@ class ModelAR extends launcher_ar_1.LauncherAR {
154
315
  }
155
316
  exports.ModelAR = ModelAR;
156
317
 
157
- },{"../util/util":15,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":1,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44}],3:[function(require,module,exports){
318
+ },{"../util/util":15,"../version":16,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":2,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44}],4:[function(require,module,exports){
158
319
  "use strict";
159
320
  var __importDefault = (this && this.__importDefault) || function (mod) {
160
321
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -168,6 +329,7 @@ const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer"
168
329
  const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer"));
169
330
  const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer"));
170
331
  const launcher_ar_1 = require("./launcher-ar");
332
+ const version_1 = __importDefault(require("../version"));
171
333
  /**
172
334
  * Performs AR functionality related to Plattar Products and Variation types
173
335
  */
@@ -202,6 +364,7 @@ class ProductAR extends launcher_ar_1.LauncherAR {
202
364
  analytics.origin = plattar_api_1.Server.location().type;
203
365
  this._analytics = analytics;
204
366
  analytics.data.push("type", "product-ar");
367
+ analytics.data.push("sdkVersion", version_1.default);
205
368
  analytics.data.push("sceneId", scene.id);
206
369
  analytics.data.push("sceneTitle", scene.attributes.title);
207
370
  const application = scene.relationships.find(plattar_api_1.Project);
@@ -345,7 +508,7 @@ class ProductAR extends launcher_ar_1.LauncherAR {
345
508
  }
346
509
  exports.ProductAR = ProductAR;
347
510
 
348
- },{"../util/util":15,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":1,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44}],4:[function(require,module,exports){
511
+ },{"../util/util":15,"../version":16,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":2,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44}],5:[function(require,module,exports){
349
512
  "use strict";
350
513
  var __importDefault = (this && this.__importDefault) || function (mod) {
351
514
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -359,6 +522,7 @@ const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer"
359
522
  const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer"));
360
523
  const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer"));
361
524
  const launcher_ar_1 = require("./launcher-ar");
525
+ const version_1 = __importDefault(require("../version"));
362
526
  /**
363
527
  * Allows launching AR Experiences provided a single remote 3D Model file
364
528
  */
@@ -396,6 +560,7 @@ class RawAR extends launcher_ar_1.LauncherAR {
396
560
  analytics.origin = plattar_api_1.Server.location().type;
397
561
  this._analytics = analytics;
398
562
  analytics.data.push("type", "scene-ar");
563
+ analytics.data.push("sdkVersion", version_1.default);
399
564
  analytics.data.push("sceneId", scene.id);
400
565
  analytics.data.push("sceneTitle", scene.attributes.title);
401
566
  const application = scene.relationships.find(plattar_api_1.Project);
@@ -490,7 +655,7 @@ class RawAR extends launcher_ar_1.LauncherAR {
490
655
  }
491
656
  exports.RawAR = RawAR;
492
657
 
493
- },{"../util/util":15,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":1,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44}],5:[function(require,module,exports){
658
+ },{"../util/util":15,"../version":16,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":2,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44}],6:[function(require,module,exports){
494
659
  "use strict";
495
660
  var __importDefault = (this && this.__importDefault) || function (mod) {
496
661
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -505,6 +670,7 @@ const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer"
505
670
  const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer"));
506
671
  const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer"));
507
672
  const launcher_ar_1 = require("./launcher-ar");
673
+ const version_1 = __importDefault(require("../version"));
508
674
  /**
509
675
  * Performs AR functionality related to Plattar Scenes
510
676
  */
@@ -531,6 +697,7 @@ class SceneAR extends launcher_ar_1.LauncherAR {
531
697
  analytics.origin = plattar_api_1.Server.location().type;
532
698
  this._analytics = analytics;
533
699
  analytics.data.push("type", "scene-ar");
700
+ analytics.data.push("sdkVersion", version_1.default);
534
701
  analytics.data.push("sceneId", scene.id);
535
702
  analytics.data.push("sceneTitle", scene.attributes.title);
536
703
  const application = scene.relationships.find(plattar_api_1.Project);
@@ -691,7 +858,7 @@ class SceneAR extends launcher_ar_1.LauncherAR {
691
858
  }
692
859
  exports.SceneAR = SceneAR;
693
860
 
694
- },{"../util/util":15,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":1,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44,"@plattar/plattar-services":115}],6:[function(require,module,exports){
861
+ },{"../util/util":15,"../version":16,"../viewers/quicklook-viewer":18,"../viewers/reality-viewer":19,"../viewers/scene-viewer":20,"./launcher-ar":2,"@plattar/plattar-analytics":40,"@plattar/plattar-api":44,"@plattar/plattar-services":115}],7:[function(require,module,exports){
695
862
  "use strict";
696
863
  Object.defineProperty(exports, "__esModule", { value: true });
697
864
  exports.SceneProductAR = void 0;
@@ -741,224 +908,215 @@ class SceneProductAR extends product_ar_1.ProductAR {
741
908
  }
742
909
  exports.SceneProductAR = SceneProductAR;
743
910
 
744
- },{"../util/util":15,"./product-ar":3,"@plattar/plattar-api":44}],7:[function(require,module,exports){
911
+ },{"../util/util":15,"./product-ar":4,"@plattar/plattar-api":44}],8:[function(require,module,exports){
745
912
  "use strict";
746
913
  Object.defineProperty(exports, "__esModule", { value: true });
747
914
  exports.ConfiguratorController = void 0;
748
915
  const plattar_api_1 = require("@plattar/plattar-api");
749
- const plattar_services_1 = require("@plattar/plattar-services");
750
- const raw_ar_1 = require("../../ar/raw-ar");
751
- const scene_ar_1 = require("../../ar/scene-ar");
752
916
  const scene_product_ar_1 = require("../../ar/scene-product-ar");
753
- const configurator_state_1 = require("../../util/configurator-state");
754
917
  const util_1 = require("../../util/util");
755
918
  const plattar_controller_1 = require("./plattar-controller");
919
+ const configurator_ar_1 = require("../../ar/configurator-ar");
756
920
  /**
757
921
  * Manages an instance of the <plattar-configurator> HTML Element
758
922
  */
759
923
  class ConfiguratorController extends plattar_controller_1.PlattarController {
760
- constructor(parent) {
761
- super(parent);
924
+ constructor() {
925
+ super(...arguments);
926
+ this._cachedConfigState = null;
927
+ }
928
+ async getConfiguratorState() {
929
+ if (this._cachedConfigState) {
930
+ return this._cachedConfigState;
931
+ }
932
+ this._cachedConfigState = this.createConfiguratorState();
933
+ return this._cachedConfigState;
762
934
  }
763
- onAttributesUpdated() {
935
+ async onAttributesUpdated(attributeName) {
764
936
  const state = this._state;
937
+ if (state === plattar_controller_1.ControllerState.Renderer) {
938
+ const viewer = this.element;
939
+ if (viewer) {
940
+ if (attributeName === "variation-id") {
941
+ const variationIDs = this.getAttribute("variation-id");
942
+ const variationIDsList = variationIDs ? variationIDs.split(",") : [];
943
+ if (variationIDsList.length > 0) {
944
+ await viewer.messenger.selectVariationID(variationIDsList);
945
+ }
946
+ }
947
+ if (attributeName === "variation-sku") {
948
+ const variationSKUs = this.getAttribute("variation-sku");
949
+ const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
950
+ if (variationSKUList.length > 0) {
951
+ await viewer.messenger.selectVariationSKU(variationSKUList);
952
+ }
953
+ }
954
+ }
955
+ return;
956
+ }
765
957
  // re-render the QR Code when attributes have changed
766
958
  if (state === plattar_controller_1.ControllerState.QRCode) {
959
+ if (attributeName === "variation-id") {
960
+ const configState = await this.getConfiguratorState();
961
+ const variationIDs = this.getAttribute("variation-id");
962
+ const variationIDsList = variationIDs ? variationIDs.split(",") : [];
963
+ variationIDsList.forEach((variationID) => {
964
+ configState.state.setVariationID(variationID);
965
+ });
966
+ }
967
+ if (attributeName === "variation-sku") {
968
+ const configState = await this.getConfiguratorState();
969
+ const variationSKUs = this.getAttribute("variation-sku");
970
+ const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
971
+ variationSKUList.forEach((variationSKU) => {
972
+ configState.state.setVariationSKU(variationSKU);
973
+ });
974
+ }
767
975
  this.startQRCode(this._prevQROpt);
768
976
  return;
769
977
  }
770
978
  }
771
- startViewerQRCode(options) {
979
+ async startViewerQRCode(options) {
980
+ // remove the old renderer instance if any
981
+ this.removeRenderer();
982
+ const sceneID = this.getAttribute("scene-id");
983
+ if (!sceneID) {
984
+ throw new Error("ConfiguratorController.startQRCode() - minimum required attributes not set, use scene-id as a minimum");
985
+ }
986
+ const opt = options || this._GetDefaultQROptions();
987
+ const viewer = document.createElement("plattar-qrcode");
988
+ this._element = viewer;
989
+ // required attributes with defaults for plattar-viewer node
990
+ const width = this.getAttribute("width") || "500px";
991
+ const height = this.getAttribute("height") || "500px";
992
+ viewer.setAttribute("width", width);
993
+ viewer.setAttribute("height", height);
994
+ if (opt.color) {
995
+ viewer.setAttribute("color", opt.color);
996
+ }
997
+ if (opt.margin) {
998
+ viewer.setAttribute("margin", "" + opt.margin);
999
+ }
1000
+ if (opt.qrType) {
1001
+ viewer.setAttribute("qr-type", opt.qrType);
1002
+ }
1003
+ viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
1004
+ let dst = plattar_api_1.Server.location().base + "renderer/configurator.html?scene_id=" + sceneID;
1005
+ // optional attributes
1006
+ let configState = null;
1007
+ const showAR = this.getAttribute("show-ar");
1008
+ const showUI = this.getAttribute("show-ui");
1009
+ try {
1010
+ configState = (await this.getConfiguratorState()).state.encode();
1011
+ }
1012
+ catch (_err) {
1013
+ // config state is not available
1014
+ configState = null;
1015
+ }
1016
+ if (showUI && showUI === "true") {
1017
+ dst = plattar_api_1.Server.location().base + "configurator/dist/index.html?scene_id=" + sceneID;
1018
+ }
1019
+ if (configState) {
1020
+ dst += "&config_state=" + configState;
1021
+ }
1022
+ if (showAR) {
1023
+ dst += "&show_ar=" + showAR;
1024
+ }
1025
+ viewer.setAttribute("url", opt.url || dst);
1026
+ this._state = plattar_controller_1.ControllerState.QRCode;
1027
+ this._prevQROpt = opt;
772
1028
  return new Promise((accept, reject) => {
773
- // remove the old renderer instance if any
774
- this.removeRenderer();
775
- const sceneID = this.getAttribute("scene-id");
776
- if (sceneID) {
777
- const opt = options || this._GetDefaultQROptions();
778
- const viewer = document.createElement("plattar-qrcode");
779
- // required attributes with defaults for plattar-viewer node
780
- const width = this.getAttribute("width") || "500px";
781
- const height = this.getAttribute("height") || "500px";
782
- viewer.setAttribute("width", width);
783
- viewer.setAttribute("height", height);
784
- if (opt.color) {
785
- viewer.setAttribute("color", opt.color);
786
- }
787
- if (opt.margin) {
788
- viewer.setAttribute("margin", "" + opt.margin);
789
- }
790
- if (opt.qrType) {
791
- viewer.setAttribute("qr-type", opt.qrType);
792
- }
793
- viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
794
- let dst = plattar_api_1.Server.location().base + "renderer/configurator.html?scene_id=" + sceneID;
795
- // optional attributes
796
- const configState = this.getAttribute("config-state");
797
- const showAR = this.getAttribute("show-ar");
798
- const showUI = this.getAttribute("show-ui");
799
- if (showUI && showUI === "true") {
800
- dst = plattar_api_1.Server.location().base + "configurator/dist/index.html?scene_id=" + sceneID;
801
- }
802
- if (configState) {
803
- dst += "&config_state=" + configState;
804
- }
805
- if (showAR) {
806
- dst += "&show_ar=" + showAR;
807
- }
808
- viewer.setAttribute("url", opt.url || dst);
809
- viewer.onload = () => {
810
- return accept(viewer);
811
- };
812
- this.append(viewer);
813
- this._element = viewer;
814
- this._state = plattar_controller_1.ControllerState.QRCode;
815
- this._prevQROpt = opt;
816
- return;
817
- }
818
- return reject(new Error("ConfiguratorController.startQRCode() - minimum required attributes not set, use scene-id as a minimum"));
1029
+ viewer.onload = () => {
1030
+ return accept(viewer);
1031
+ };
1032
+ this.append(viewer);
819
1033
  });
820
1034
  }
821
- startRenderer() {
1035
+ async startRenderer() {
1036
+ // remove the old renderer instance if any
1037
+ this.removeRenderer();
1038
+ const sceneID = this.getAttribute("scene-id");
1039
+ if (!sceneID) {
1040
+ throw new Error("ConfiguratorController.startRenderer() - minimum required attributes not set, use scene-id as a minimum");
1041
+ }
1042
+ // required attributes with defaults for plattar-configurator node
1043
+ const width = this.getAttribute("width") || "500px";
1044
+ const height = this.getAttribute("height") || "500px";
1045
+ const server = this.getAttribute("server") || "production";
1046
+ const viewer = document.createElement("plattar-configurator");
1047
+ this._element = viewer;
1048
+ viewer.setAttribute("width", width);
1049
+ viewer.setAttribute("height", height);
1050
+ viewer.setAttribute("server", server);
1051
+ viewer.setAttribute("scene-id", sceneID);
1052
+ // optional attributes
1053
+ let configState = null;
1054
+ try {
1055
+ configState = await this.getConfiguratorState();
1056
+ }
1057
+ catch (_err) {
1058
+ // config state is not available
1059
+ configState = null;
1060
+ }
1061
+ const showAR = this.getAttribute("show-ar");
1062
+ const showUI = this.getAttribute("show-ui");
1063
+ if (configState) {
1064
+ viewer.setAttribute("config-state", configState.state.encode());
1065
+ }
1066
+ if (showAR) {
1067
+ viewer.setAttribute("show-ar", showAR);
1068
+ }
1069
+ if (showUI) {
1070
+ viewer.setAttribute("show-ui", showUI);
1071
+ }
1072
+ this._state = plattar_controller_1.ControllerState.Renderer;
822
1073
  return new Promise((accept, reject) => {
823
- // remove the old renderer instance if any
824
- this.removeRenderer();
825
- const sceneID = this.getAttribute("scene-id");
826
- if (sceneID) {
827
- // required attributes with defaults for plattar-configurator node
828
- const width = this.getAttribute("width") || "500px";
829
- const height = this.getAttribute("height") || "500px";
830
- const server = this.getAttribute("server") || "production";
831
- const viewer = document.createElement("plattar-configurator");
832
- viewer.setAttribute("width", width);
833
- viewer.setAttribute("height", height);
834
- viewer.setAttribute("server", server);
835
- viewer.setAttribute("scene-id", sceneID);
836
- // optional attributes
837
- const configState = this.getAttribute("config-state");
838
- const showAR = this.getAttribute("show-ar");
839
- const showUI = this.getAttribute("show-ui");
840
- if (configState) {
841
- viewer.setAttribute("config-state", configState);
842
- }
843
- if (showAR) {
844
- viewer.setAttribute("show-ar", showAR);
845
- }
846
- if (showUI) {
847
- viewer.setAttribute("show-ui", showUI);
848
- }
849
- viewer.onload = () => {
850
- return accept(viewer);
851
- };
852
- this.append(viewer);
853
- this._element = viewer;
854
- this._state = plattar_controller_1.ControllerState.Renderer;
855
- return;
1074
+ this.append(viewer);
1075
+ if (configState) {
1076
+ this.setupMessengerObservers(viewer, configState);
856
1077
  }
857
- return reject(new Error("ConfiguratorController.startRenderer() - minimum required attributes not set, use scene-id as a minimum"));
1078
+ return accept(viewer);
858
1079
  });
859
1080
  }
860
- initAR() {
861
- return new Promise((accept, reject) => {
862
- if (!util_1.Util.canAugment()) {
863
- return reject(new Error("ConfiguratorController.initAR() - cannot proceed as AR not available in context"));
864
- }
865
- const arMode = this.getAttribute("ar-mode") || "generated";
866
- switch (arMode.toLowerCase()) {
867
- case "inherited":
868
- this._InitARInherited(accept, reject);
869
- return;
870
- case "generated":
871
- default:
872
- this._InitARGenerated(accept, reject);
873
- }
874
- });
1081
+ async initAR() {
1082
+ if (!util_1.Util.canAugment()) {
1083
+ throw new Error("ConfiguratorController.initAR() - cannot proceed as AR not available in context");
1084
+ }
1085
+ const arMode = this.getAttribute("ar-mode") || "generated";
1086
+ switch (arMode.toLowerCase()) {
1087
+ case "inherited":
1088
+ return this._InitARInherited();
1089
+ case "generated":
1090
+ default:
1091
+ return this._InitARGenerated();
1092
+ }
875
1093
  }
876
1094
  /**
877
1095
  * Private Function - This launches the Static/Inherited AR Mode
878
1096
  */
879
- _InitARInherited(accept, reject) {
1097
+ async _InitARInherited() {
880
1098
  const sceneID = this.getAttribute("scene-id");
881
- const configState = this.getAttribute("config-state");
882
- // use config-state if its available
883
- if (sceneID && configState) {
884
- const state = configurator_state_1.ConfiguratorState.decode(configState);
885
- const first = state.first();
886
- if (first) {
887
- const sceneProductAR = new scene_product_ar_1.SceneProductAR(first.scene_product_id, first.product_variation_id);
888
- sceneProductAR.init().then(accept).catch(reject);
889
- return;
890
- }
891
- return reject(new Error("ConfiguratorController.initAR() - invalid config-state does not have any product states"));
1099
+ if (!sceneID) {
1100
+ throw new Error("ConfiguratorController.initAR() - inherited AR minimum required attributes not set, use scene-id as a minimum");
892
1101
  }
893
- // otherwise fallback to using scene
894
- if (sceneID) {
895
- configurator_state_1.ConfiguratorState.decodeScene(sceneID).then((state) => {
896
- const first = state.first();
897
- if (first) {
898
- const sceneProductAR = new scene_product_ar_1.SceneProductAR(first.scene_product_id, first.product_variation_id);
899
- return sceneProductAR.init().then(accept).catch(reject);
900
- }
901
- return reject(new Error("ConfiguratorController.initAR() - invalid Scene does not have any product states"));
902
- }).catch(reject);
903
- return;
1102
+ const state = (await this.getConfiguratorState()).state;
1103
+ const first = state.first();
1104
+ if (first) {
1105
+ const sceneProductAR = new scene_product_ar_1.SceneProductAR(first.scene_product_id, first.product_variation_id);
1106
+ return sceneProductAR.init();
904
1107
  }
905
- return reject(new Error("ConfiguratorController.initAR() - minimum required attributes not set, use scene-id as a minimum"));
1108
+ throw new Error("ConfiguratorController.initAR() - invalid decoded config-state does not have any product states");
906
1109
  }
907
1110
  /**
908
1111
  * Private Function - This launches the Dynamic/Generated AR Mode
909
1112
  */
910
- _InitARGenerated(accept, reject) {
911
- // if scene ID is available and the state is a configurator viewer
912
- // we can use the real-time configurator state to launch the AR view
913
- const viewer = this.element;
1113
+ async _InitARGenerated() {
914
1114
  const sceneID = this.getAttribute("scene-id");
915
- if (viewer && sceneID && viewer.messenger) {
916
- let output = "glb";
917
- if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) {
918
- output = "usdz";
919
- }
920
- viewer.messenger.getARFile(output).then((result) => {
921
- const rawAR = new raw_ar_1.RawAR(result.filename, sceneID);
922
- return rawAR.init().then(accept).catch(reject);
923
- }).catch(reject);
924
- return;
925
- }
926
- const configState = this.getAttribute("config-state");
927
- // otherwise scene ID is available to the viewer is not launched
928
- // we can use the static configuration state to launch the AR view
929
- if (sceneID && configState) {
930
- const state = configurator_state_1.ConfiguratorState.decode(configState);
931
- if (state.length > 0) {
932
- const server = this.getAttribute("server") || "production";
933
- const configurator = new plattar_services_1.Configurator();
934
- configurator.server = server;
935
- if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) {
936
- configurator.output = "usdz";
937
- }
938
- if (util_1.Util.canSceneViewer()) {
939
- configurator.output = "glb";
940
- }
941
- state.forEach((productState) => {
942
- if (productState.meta_data.augment === true) {
943
- configurator.addSceneProduct(productState.scene_product_id, productState.product_variation_id);
944
- }
945
- });
946
- configurator.get().then((result) => {
947
- const rawAR = new raw_ar_1.RawAR(result.filename, sceneID);
948
- rawAR.init().then(accept).catch(reject);
949
- }).catch(reject);
950
- return;
951
- }
952
- return reject(new Error("ConfiguratorController.initAR() - invalid config-state does not have any product states"));
953
- }
954
- // otherwise no config-state or viewer is active
955
- // fallback to using default SceneAR implementation
956
- if (sceneID) {
957
- const sceneAR = new scene_ar_1.SceneAR(sceneID);
958
- sceneAR.init().then(accept).catch(reject);
959
- return;
1115
+ if (!sceneID) {
1116
+ throw new Error("VTOController.initAR() - generated AR minimum required attributes not set, use scene-id as a minimum");
960
1117
  }
961
- return reject(new Error("ConfiguratorController.initAR() - minimum required attributes not set, use scene-id as a minimum"));
1118
+ const configAR = new configurator_ar_1.ConfiguratorAR(await this.getConfiguratorState());
1119
+ return configAR.init();
962
1120
  }
963
1121
  removeRenderer() {
964
1122
  if (this._element) {
@@ -966,6 +1124,7 @@ class ConfiguratorController extends plattar_controller_1.PlattarController {
966
1124
  this._element = null;
967
1125
  return true;
968
1126
  }
1127
+ this.removeMessengerObservers();
969
1128
  return false;
970
1129
  }
971
1130
  get element() {
@@ -974,11 +1133,12 @@ class ConfiguratorController extends plattar_controller_1.PlattarController {
974
1133
  }
975
1134
  exports.ConfiguratorController = ConfiguratorController;
976
1135
 
977
- },{"../../ar/raw-ar":4,"../../ar/scene-ar":5,"../../ar/scene-product-ar":6,"../../util/configurator-state":14,"../../util/util":15,"./plattar-controller":8,"@plattar/plattar-api":44,"@plattar/plattar-services":115}],8:[function(require,module,exports){
1136
+ },{"../../ar/configurator-ar":1,"../../ar/scene-product-ar":7,"../../util/util":15,"./plattar-controller":9,"@plattar/plattar-api":44}],9:[function(require,module,exports){
978
1137
  "use strict";
979
1138
  Object.defineProperty(exports, "__esModule", { value: true });
980
1139
  exports.PlattarController = exports.ControllerState = void 0;
981
1140
  const plattar_api_1 = require("@plattar/plattar-api");
1141
+ const configurator_state_1 = require("../../util/configurator-state");
982
1142
  var ControllerState;
983
1143
  (function (ControllerState) {
984
1144
  ControllerState[ControllerState["None"] = 0] = "None";
@@ -1005,31 +1165,94 @@ class PlattarController {
1005
1165
  this._state = ControllerState.None;
1006
1166
  this._element = null;
1007
1167
  this._prevQROpt = null;
1168
+ this._selectVariationObserver = null;
1169
+ this._selectVariationSKUObserver = null;
1008
1170
  this._parent = parent;
1009
1171
  }
1010
1172
  /**
1011
- * Initialise and start AR mode if available
1173
+ * Generates a brand new Configurator State from the provided SceneID or inputted Configurator State
1012
1174
  */
1013
- startAR() {
1014
- return new Promise((accept, reject) => {
1015
- this.initAR().then((launcher) => {
1016
- launcher.start();
1017
- accept();
1018
- }).catch(reject);
1175
+ async createConfiguratorState() {
1176
+ // get our Scene ID
1177
+ const sceneID = this.getAttribute("scene-id");
1178
+ if (!sceneID) {
1179
+ throw new Error("PlattarController.createConfiguratorState() - cannot create as required attribute scene-id is not defined");
1180
+ }
1181
+ const configState = this.getAttribute("config-state");
1182
+ // get a list of variation ID's to use for initialising
1183
+ const variationIDs = this.getAttribute("variation-id");
1184
+ // get a list of variation SKU's to use for initialising
1185
+ const variationSKUs = this.getAttribute("variation-sku");
1186
+ // generate the decoded configurator state
1187
+ const decodedState = configState ? await configurator_state_1.ConfiguratorState.decodeState(sceneID, configState) : await configurator_state_1.ConfiguratorState.decodeScene(sceneID);
1188
+ // change the ID's and SKU's (if any) of the default configuration state
1189
+ const variationIDList = variationIDs ? variationIDs.split(",") : [];
1190
+ const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
1191
+ variationIDList.forEach((variationID) => {
1192
+ decodedState.state.setVariationID(variationID);
1019
1193
  });
1194
+ variationSKUList.forEach((variationSKU) => {
1195
+ decodedState.state.setVariationSKU(variationSKU);
1196
+ });
1197
+ // return fully modified configuration state
1198
+ return decodedState;
1020
1199
  }
1021
1200
  /**
1022
- * Decide which QR Code to render according to the qr-type attribute
1023
- * @param options
1024
- * @returns
1201
+ * Setup messenger observers to detect variation changes and apply to the internal
1202
+ * configuration state
1025
1203
  */
1026
- startQRCode(options) {
1027
- const qrType = this.getAttribute("qr-type") || "viewer";
1028
- switch (qrType.toLowerCase()) {
1029
- case "ar":
1030
- return this.startARQRCode(options);
1031
- case "viewer":
1032
- default:
1204
+ setupMessengerObservers(viewer, configState) {
1205
+ this._selectVariationObserver = viewer.messengerInstance.observer.subscribe("selectVariation", (cd) => {
1206
+ if (cd.type === "call") {
1207
+ const args = cd.data[0];
1208
+ const variations = args ? (Array.isArray(args) ? args : [args]) : [];
1209
+ variations.forEach((variationID) => {
1210
+ configState.state.setVariationID(variationID);
1211
+ });
1212
+ }
1213
+ });
1214
+ this._selectVariationSKUObserver = viewer.messengerInstance.observer.subscribe("selectVariationSKU", (cd) => {
1215
+ if (cd.type === "call") {
1216
+ const args = cd.data[0];
1217
+ const variations = args ? (Array.isArray(args) ? args : [args]) : [];
1218
+ variations.forEach((variationSKU) => {
1219
+ configState.state.setVariationSKU(variationSKU);
1220
+ });
1221
+ }
1222
+ });
1223
+ }
1224
+ /**
1225
+ * Remove all pre-existing observers
1226
+ */
1227
+ removeMessengerObservers() {
1228
+ if (this._selectVariationObserver) {
1229
+ this._selectVariationObserver();
1230
+ this._selectVariationObserver = null;
1231
+ }
1232
+ if (this._selectVariationSKUObserver) {
1233
+ this._selectVariationSKUObserver();
1234
+ this._selectVariationSKUObserver = null;
1235
+ }
1236
+ }
1237
+ /**
1238
+ * Initialise and start AR mode if available
1239
+ */
1240
+ async startAR() {
1241
+ const launcher = await this.initAR();
1242
+ return launcher.start();
1243
+ }
1244
+ /**
1245
+ * Decide which QR Code to render according to the qr-type attribute
1246
+ * @param options
1247
+ * @returns
1248
+ */
1249
+ async startQRCode(options) {
1250
+ const qrType = this.getAttribute("qr-type") || "viewer";
1251
+ switch (qrType.toLowerCase()) {
1252
+ case "ar":
1253
+ return this.startARQRCode(options);
1254
+ case "viewer":
1255
+ default:
1033
1256
  return this.startViewerQRCode(options);
1034
1257
  }
1035
1258
  }
@@ -1038,69 +1261,76 @@ class PlattarController {
1038
1261
  * @param options
1039
1262
  * @returns
1040
1263
  */
1041
- startARQRCode(options) {
1264
+ async startARQRCode(options) {
1265
+ // remove the old renderer instance if any
1266
+ this.removeRenderer();
1267
+ const opt = options || this._GetDefaultQROptions();
1268
+ const viewer = document.createElement("plattar-qrcode");
1269
+ this._element = viewer;
1270
+ // required attributes with defaults for plattar-viewer node
1271
+ const width = this.getAttribute("width") || "500px";
1272
+ const height = this.getAttribute("height") || "500px";
1273
+ viewer.setAttribute("width", width);
1274
+ viewer.setAttribute("height", height);
1275
+ if (opt.color) {
1276
+ viewer.setAttribute("color", opt.color);
1277
+ }
1278
+ if (opt.margin) {
1279
+ viewer.setAttribute("margin", "" + opt.margin);
1280
+ }
1281
+ if (opt.qrType) {
1282
+ viewer.setAttribute("qr-type", opt.qrType);
1283
+ }
1284
+ viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
1285
+ const qrOptions = btoa(JSON.stringify(opt));
1286
+ let dst = plattar_api_1.Server.location().base + "renderer/launcher.html?qr_options=" + qrOptions;
1287
+ let configState = null;
1288
+ const sceneID = this.getAttribute("scene-id");
1289
+ const embedType = this.getAttribute("embed-type");
1290
+ const productID = this.getAttribute("product-id");
1291
+ const sceneProductID = this.getAttribute("scene-product-id");
1292
+ const variationID = this.getAttribute("variation-id");
1293
+ const variationSKU = this.getAttribute("variation-sku");
1294
+ const arMode = this.getAttribute("ar-mode");
1295
+ try {
1296
+ configState = (await this.getConfiguratorState()).state.encode();
1297
+ }
1298
+ catch (_err) {
1299
+ // config state not available for some reason
1300
+ configState = null;
1301
+ }
1302
+ if (configState) {
1303
+ dst += "&config_state=" + configState;
1304
+ }
1305
+ if (embedType) {
1306
+ dst += "&embed_type=" + embedType;
1307
+ }
1308
+ if (productID) {
1309
+ dst += "&product_id=" + productID;
1310
+ }
1311
+ if (sceneProductID) {
1312
+ dst += "&scene_product_id=" + sceneProductID;
1313
+ }
1314
+ if (variationID) {
1315
+ dst += "&variation_id=" + variationID;
1316
+ }
1317
+ if (variationSKU) {
1318
+ dst += "&variation_sku=" + variationSKU;
1319
+ }
1320
+ if (arMode) {
1321
+ dst += "&ar_mode=" + arMode;
1322
+ }
1323
+ if (sceneID) {
1324
+ dst += "&scene_id=" + sceneID;
1325
+ }
1326
+ viewer.setAttribute("url", opt.url || dst);
1327
+ this._state = ControllerState.QRCode;
1328
+ this._prevQROpt = opt;
1042
1329
  return new Promise((accept, reject) => {
1043
- // remove the old renderer instance if any
1044
- this.removeRenderer();
1045
- const opt = options || this._GetDefaultQROptions();
1046
- const viewer = document.createElement("plattar-qrcode");
1047
- // required attributes with defaults for plattar-viewer node
1048
- const width = this.getAttribute("width") || "500px";
1049
- const height = this.getAttribute("height") || "500px";
1050
- viewer.setAttribute("width", width);
1051
- viewer.setAttribute("height", height);
1052
- if (opt.color) {
1053
- viewer.setAttribute("color", opt.color);
1054
- }
1055
- if (opt.margin) {
1056
- viewer.setAttribute("margin", "" + opt.margin);
1057
- }
1058
- if (opt.qrType) {
1059
- viewer.setAttribute("qr-type", opt.qrType);
1060
- }
1061
- viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
1062
- const qrOptions = btoa(JSON.stringify(opt));
1063
- let dst = plattar_api_1.Server.location().base + "renderer/launcher.html?qr_options=" + qrOptions;
1064
- const sceneID = this.getAttribute("scene-id");
1065
- const configState = this.getAttribute("config-state");
1066
- const embedType = this.getAttribute("embed-type");
1067
- const productID = this.getAttribute("product-id");
1068
- const sceneProductID = this.getAttribute("scene-product-id");
1069
- const variationID = this.getAttribute("variation-id");
1070
- const variationSKU = this.getAttribute("variation-sku");
1071
- const arMode = this.getAttribute("ar-mode");
1072
- if (configState) {
1073
- dst += "&config_state=" + configState;
1074
- }
1075
- if (embedType) {
1076
- dst += "&embed_type=" + embedType;
1077
- }
1078
- if (productID) {
1079
- dst += "&product_id=" + productID;
1080
- }
1081
- if (sceneProductID) {
1082
- dst += "&scene_product_id=" + sceneProductID;
1083
- }
1084
- if (variationID) {
1085
- dst += "&variation_id=" + variationID;
1086
- }
1087
- if (variationSKU) {
1088
- dst += "&variation_sku=" + variationSKU;
1089
- }
1090
- if (arMode) {
1091
- dst += "&ar_mode=" + arMode;
1092
- }
1093
- if (sceneID) {
1094
- dst += "&scene_id=" + sceneID;
1095
- }
1096
- viewer.setAttribute("url", opt.url || dst);
1330
+ this.append(viewer);
1097
1331
  viewer.onload = () => {
1098
1332
  return accept(viewer);
1099
1333
  };
1100
- this._element = viewer;
1101
- this._state = ControllerState.QRCode;
1102
- this._prevQROpt = opt;
1103
- this.append(viewer);
1104
1334
  });
1105
1335
  }
1106
1336
  /**
@@ -1128,7 +1358,7 @@ class PlattarController {
1128
1358
  }
1129
1359
  exports.PlattarController = PlattarController;
1130
1360
 
1131
- },{"@plattar/plattar-api":44}],9:[function(require,module,exports){
1361
+ },{"../../util/configurator-state":14,"@plattar/plattar-api":44}],10:[function(require,module,exports){
1132
1362
  "use strict";
1133
1363
  Object.defineProperty(exports, "__esModule", { value: true });
1134
1364
  exports.ProductController = void 0;
@@ -1138,12 +1368,20 @@ const util_1 = require("../../util/util");
1138
1368
  const plattar_controller_1 = require("./plattar-controller");
1139
1369
  /**
1140
1370
  * Manages an instance of the <plattar-product> HTML Element
1371
+ *
1372
+ * NOTE: As of 14th June 2023, this is now a legacy Controller and only used in legacy embeds
1373
+ * and should be deprecated from both documentation and previous integrations
1141
1374
  */
1142
1375
  class ProductController extends plattar_controller_1.PlattarController {
1376
+ async getConfiguratorState() {
1377
+ throw new Error("ProductController.getConfiguratorState() - legacy embeds do not support configurator states");
1378
+ }
1143
1379
  constructor(parent) {
1380
+ // this is a hack against DecodedConfiguratorState that's now stored in PlattarController
1381
+ // this is not used in legacy mode
1144
1382
  super(parent);
1145
1383
  }
1146
- onAttributesUpdated() {
1384
+ async onAttributesUpdated(attributeName) {
1147
1385
  const state = this._state;
1148
1386
  // re-render the QR Code when attributes have changed
1149
1387
  if (state === plattar_controller_1.ControllerState.QRCode) {
@@ -1159,7 +1397,6 @@ class ProductController extends plattar_controller_1.PlattarController {
1159
1397
  viewer.messenger.selectVariation(variationID);
1160
1398
  }
1161
1399
  }
1162
- return;
1163
1400
  }
1164
1401
  }
1165
1402
  startViewerQRCode(options) {
@@ -1280,434 +1517,234 @@ class ProductController extends plattar_controller_1.PlattarController {
1280
1517
  }
1281
1518
  exports.ProductController = ProductController;
1282
1519
 
1283
- },{"../../ar/product-ar":3,"../../util/util":15,"./plattar-controller":8,"@plattar/plattar-api":44}],10:[function(require,module,exports){
1520
+ },{"../../ar/product-ar":4,"../../util/util":15,"./plattar-controller":9,"@plattar/plattar-api":44}],11:[function(require,module,exports){
1284
1521
  "use strict";
1285
1522
  Object.defineProperty(exports, "__esModule", { value: true });
1286
- exports.ViewerController = void 0;
1523
+ exports.VTOController = void 0;
1287
1524
  const plattar_api_1 = require("@plattar/plattar-api");
1288
- const product_ar_1 = require("../../ar/product-ar");
1289
- const scene_ar_1 = require("../../ar/scene-ar");
1290
- const scene_product_ar_1 = require("../../ar/scene-product-ar");
1291
- const configurator_state_1 = require("../../util/configurator-state");
1525
+ const __1 = require("../..");
1292
1526
  const util_1 = require("../../util/util");
1293
1527
  const plattar_controller_1 = require("./plattar-controller");
1528
+ const configurator_ar_1 = require("../../ar/configurator-ar");
1294
1529
  /**
1295
- * Manages an instance of the <plattar-viewer> HTML Element
1530
+ * Manages an instance of the <plattar-configurator> HTML Element
1296
1531
  */
1297
- class ViewerController extends plattar_controller_1.PlattarController {
1298
- constructor(parent) {
1299
- super(parent);
1532
+ class VTOController extends plattar_controller_1.PlattarController {
1533
+ constructor() {
1534
+ super(...arguments);
1535
+ this._cachedConfigState = null;
1300
1536
  }
1301
- onAttributesUpdated() {
1302
- const state = this._state;
1303
- // re-render the QR Code when attributes have changed
1304
- if (state === plattar_controller_1.ControllerState.QRCode) {
1305
- this.startQRCode(this._prevQROpt);
1306
- return;
1537
+ async getConfiguratorState() {
1538
+ if (this._cachedConfigState) {
1539
+ return this._cachedConfigState;
1307
1540
  }
1308
- // use the messenger function to change variation when attributes have changed
1541
+ this._cachedConfigState = this.createConfiguratorState();
1542
+ return this._cachedConfigState;
1543
+ }
1544
+ async onAttributesUpdated(attributeName) {
1545
+ const state = this._state;
1309
1546
  if (state === plattar_controller_1.ControllerState.Renderer) {
1310
- const viewer = this._element;
1547
+ const viewer = this.element;
1311
1548
  if (viewer) {
1312
- const productID = (this.getAttribute("product-id") || this.getAttribute("scene-product-id"));
1313
- const variationID = this.getAttribute("variation-id");
1314
- if (productID && variationID && viewer.messenger) {
1315
- viewer.messenger.selectVariation(productID, variationID);
1316
- }
1317
- }
1318
- return;
1319
- }
1320
- }
1321
- startViewerQRCode(options) {
1322
- return new Promise((accept, reject) => {
1323
- // remove the old renderer instance if any
1324
- this.removeRenderer();
1325
- const sceneID = this.getAttribute("scene-id");
1326
- if (sceneID) {
1327
- const opt = options || this._GetDefaultQROptions();
1328
- const viewer = document.createElement("plattar-qrcode");
1329
- // required attributes with defaults for plattar-viewer node
1330
- const width = this.getAttribute("width") || "500px";
1331
- const height = this.getAttribute("height") || "500px";
1332
- viewer.setAttribute("width", width);
1333
- viewer.setAttribute("height", height);
1334
- if (opt.color) {
1335
- viewer.setAttribute("color", opt.color);
1336
- }
1337
- if (opt.margin) {
1338
- viewer.setAttribute("margin", "" + opt.margin);
1339
- }
1340
- if (opt.qrType) {
1341
- viewer.setAttribute("qr-type", opt.qrType);
1342
- }
1343
- viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
1344
- let dst = plattar_api_1.Server.location().base + "renderer/viewer.html?scene_id=" + sceneID;
1345
- // optional attributes
1346
- const productID = (this.getAttribute("product-id") || this.getAttribute("scene-product-id"));
1347
- const variationID = this.getAttribute("variation-id");
1348
- const variationSKU = this.getAttribute("variation-sku");
1349
- const showAR = this.getAttribute("show-ar");
1350
- if (productID) {
1351
- dst += "&productId=" + productID;
1352
- }
1353
- if (variationID) {
1354
- dst += "&variationId=" + variationID;
1355
- }
1356
- if (variationSKU) {
1357
- dst += "&variationSku=" + variationSKU;
1358
- }
1359
- if (showAR) {
1360
- dst += "&show_ar=" + showAR;
1361
- }
1362
- viewer.setAttribute("url", opt.url || dst);
1363
- viewer.onload = () => {
1364
- return accept(viewer);
1365
- };
1366
- this.append(viewer);
1367
- this._element = viewer;
1368
- this._state = plattar_controller_1.ControllerState.QRCode;
1369
- this._prevQROpt = opt;
1370
- return;
1371
- }
1372
- return reject(new Error("ViewerController.startQRCode() - minimum required attributes not set, use scene-id as a minimum"));
1373
- });
1374
- }
1375
- startRenderer() {
1376
- return new Promise((accept, reject) => {
1377
- // remove the old renderer instance if any
1378
- this.removeRenderer();
1379
- const sceneID = this.getAttribute("scene-id");
1380
- if (sceneID) {
1381
- // required attributes with defaults for plattar-viewer node
1382
- const width = this.getAttribute("width") || "500px";
1383
- const height = this.getAttribute("height") || "500px";
1384
- const server = this.getAttribute("server") || "production";
1385
- const viewer = document.createElement("plattar-viewer");
1386
- viewer.setAttribute("width", width);
1387
- viewer.setAttribute("height", height);
1388
- viewer.setAttribute("server", server);
1389
- viewer.setAttribute("scene-id", sceneID);
1390
- // optional attributes
1391
- const productID = (this.getAttribute("product-id") || this.getAttribute("scene-product-id"));
1392
- const variationID = this.getAttribute("variation-id");
1393
- const variationSKU = this.getAttribute("variation-sku");
1394
- const showAR = this.getAttribute("show-ar");
1395
- if (productID) {
1396
- viewer.setAttribute("product-id", productID);
1397
- }
1398
- if (variationID) {
1399
- viewer.setAttribute("variation-id", variationID);
1400
- }
1401
- if (variationSKU) {
1402
- viewer.setAttribute("variation-sku", variationSKU);
1403
- }
1404
- if (showAR) {
1405
- viewer.setAttribute("show-ar", showAR);
1406
- }
1407
- viewer.onload = () => {
1408
- return accept(viewer);
1409
- };
1410
- this.append(viewer);
1411
- this._element = viewer;
1412
- this._state = plattar_controller_1.ControllerState.Renderer;
1413
- return;
1414
- }
1415
- return reject(new Error("ViewerController.startRenderer() - minimum required attributes not set, use scene-id as a minimum"));
1416
- });
1417
- }
1418
- initAR() {
1419
- return new Promise((accept, reject) => {
1420
- if (!util_1.Util.canAugment()) {
1421
- return reject(new Error("ViewerController.initAR() - cannot proceed as AR not available in context"));
1422
- }
1423
- const productID = this.getAttribute("product-id");
1424
- // use product-id if available
1425
- if (productID) {
1426
- const variationID = this.getAttribute("variation-id");
1427
- const variationSKU = this.getAttribute("variation-sku");
1428
- const product = new product_ar_1.ProductAR(productID, variationID, variationSKU);
1429
- return product.init().then(accept).catch(reject);
1430
- }
1431
- const sceneProductID = this.getAttribute("scene-product-id");
1432
- // use scene-product-id if available
1433
- if (sceneProductID) {
1434
- const variationID = this.getAttribute("variation-id");
1435
- const variationSKU = this.getAttribute("variation-sku");
1436
- const product = new scene_product_ar_1.SceneProductAR(sceneProductID, variationID, variationSKU);
1437
- return product.init().then(accept).catch(reject);
1438
- }
1439
- const sceneID = this.getAttribute("scene-id");
1440
- // fallback to using default SceneAR implementation
1441
- if (sceneID) {
1442
- // special case - check if scene only has a single product, if so
1443
- // we need to use provided variation-id or variation-sku to override
1444
- const variationID = this.getAttribute("variation-id");
1445
- const variationSKU = this.getAttribute("variation-sku");
1446
- // just do scene-ar if variation ID and variation SKU is not set
1447
- if (!variationID && !variationSKU) {
1448
- const sceneAR = new scene_ar_1.SceneAR(sceneID);
1449
- return sceneAR.init().then(accept).catch(reject);
1549
+ if (attributeName === "variation-id") {
1550
+ const variationIDs = this.getAttribute("variation-id");
1551
+ const variationIDsList = variationIDs ? variationIDs.split(",") : [];
1552
+ if (variationIDsList.length > 0) {
1553
+ await viewer.messenger.selectVariationID(variationIDsList);
1554
+ }
1450
1555
  }
1451
- // otherwise decode scene
1452
- return configurator_state_1.ConfiguratorState.decodeScene(sceneID).then((state) => {
1453
- const firstProduct = state.first();
1454
- if (state.length > 1 || !firstProduct) {
1455
- return reject(new Error("ViewerController.initAR() - single product required to override variation-id or variation-sku"));
1556
+ if (attributeName === "variation-sku") {
1557
+ const variationSKUs = this.getAttribute("variation-sku");
1558
+ const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
1559
+ if (variationSKUList.length > 0) {
1560
+ await viewer.messenger.selectVariationSKU(variationSKUList);
1456
1561
  }
1457
- const product = new scene_product_ar_1.SceneProductAR(firstProduct.scene_product_id, variationID, variationSKU);
1458
- return product.init().then(accept).catch(reject);
1459
- }).catch(reject);
1562
+ }
1460
1563
  }
1461
- return reject(new Error("ViewerController.initAR() - minimum required attributes not set, use scene-id as a minimum"));
1462
- });
1463
- }
1464
- removeRenderer() {
1465
- if (this._element) {
1466
- this._element.remove();
1467
- this._element = null;
1468
- return true;
1564
+ return;
1469
1565
  }
1470
- return false;
1471
- }
1472
- get element() {
1473
- return this._element;
1474
- }
1475
- }
1476
- exports.ViewerController = ViewerController;
1477
-
1478
- },{"../../ar/product-ar":3,"../../ar/scene-ar":5,"../../ar/scene-product-ar":6,"../../util/configurator-state":14,"../../util/util":15,"./plattar-controller":8,"@plattar/plattar-api":44}],11:[function(require,module,exports){
1479
- "use strict";
1480
- Object.defineProperty(exports, "__esModule", { value: true });
1481
- exports.VTOController = void 0;
1482
- const plattar_api_1 = require("@plattar/plattar-api");
1483
- const plattar_services_1 = require("@plattar/plattar-services");
1484
- const __1 = require("../..");
1485
- const raw_ar_1 = require("../../ar/raw-ar");
1486
- const util_1 = require("../../util/util");
1487
- const plattar_controller_1 = require("./plattar-controller");
1488
- /**
1489
- * Manages an instance of the <plattar-configurator> HTML Element
1490
- */
1491
- class VTOController extends plattar_controller_1.PlattarController {
1492
- constructor(parent) {
1493
- super(parent);
1494
- }
1495
- onAttributesUpdated() {
1496
- const state = this._state;
1497
1566
  // re-render the QR Code when attributes have changed
1498
1567
  if (state === plattar_controller_1.ControllerState.QRCode) {
1568
+ if (attributeName === "variation-id") {
1569
+ const configState = await this.getConfiguratorState();
1570
+ const variationIDs = this.getAttribute("variation-id");
1571
+ const variationIDsList = variationIDs ? variationIDs.split(",") : [];
1572
+ variationIDsList.forEach((variationID) => {
1573
+ configState.state.setVariationID(variationID);
1574
+ });
1575
+ }
1576
+ if (attributeName === "variation-sku") {
1577
+ const configState = await this.getConfiguratorState();
1578
+ const variationSKUs = this.getAttribute("variation-sku");
1579
+ const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
1580
+ variationSKUList.forEach((variationSKU) => {
1581
+ configState.state.setVariationSKU(variationSKU);
1582
+ });
1583
+ }
1499
1584
  this.startQRCode(this._prevQROpt);
1500
1585
  return;
1501
1586
  }
1502
1587
  }
1503
- startViewerQRCode(options) {
1588
+ async startViewerQRCode(options) {
1589
+ // remove the old renderer instance if any
1590
+ this.removeRenderer();
1591
+ const sceneID = this.getAttribute("scene-id");
1592
+ if (!sceneID) {
1593
+ throw new Error("VTOController.startQRCode() - minimum required attributes not set, use scene-id as a minimum");
1594
+ }
1595
+ const opt = options || this._GetDefaultQROptions();
1596
+ const viewer = document.createElement("plattar-qrcode");
1597
+ this._element = viewer;
1598
+ // required attributes with defaults for plattar-viewer node
1599
+ const width = this.getAttribute("width") || "500px";
1600
+ const height = this.getAttribute("height") || "500px";
1601
+ viewer.setAttribute("width", width);
1602
+ viewer.setAttribute("height", height);
1603
+ if (opt.color) {
1604
+ viewer.setAttribute("color", opt.color);
1605
+ }
1606
+ if (opt.margin) {
1607
+ viewer.setAttribute("margin", "" + opt.margin);
1608
+ }
1609
+ if (opt.qrType) {
1610
+ viewer.setAttribute("qr-type", opt.qrType);
1611
+ }
1612
+ viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
1613
+ let dst = plattar_api_1.Server.location().base + "renderer/facear.html?scene_id=" + sceneID;
1614
+ // optional attributes
1615
+ let configState = null;
1616
+ try {
1617
+ configState = await this.getConfiguratorState();
1618
+ }
1619
+ catch (_err) {
1620
+ // config state is not available
1621
+ configState = null;
1622
+ }
1623
+ const showAR = this.getAttribute("show-ar");
1624
+ const productID = this.getAttribute("product-id");
1625
+ const sceneProductID = this.getAttribute("scene-product-id");
1626
+ const variationID = this.getAttribute("variation-id");
1627
+ if (configState) {
1628
+ dst += "&config_state=" + configState.state.encode();
1629
+ }
1630
+ if (showAR) {
1631
+ dst += "&show_ar=" + showAR;
1632
+ }
1633
+ if (productID) {
1634
+ dst += "&product_id=" + productID;
1635
+ }
1636
+ if (sceneProductID) {
1637
+ dst += "&scene_product_id=" + sceneProductID;
1638
+ }
1639
+ if (variationID) {
1640
+ dst += "&variation_id=" + variationID;
1641
+ }
1642
+ viewer.setAttribute("url", opt.url || dst);
1643
+ this._state = plattar_controller_1.ControllerState.QRCode;
1644
+ this._prevQROpt = opt;
1504
1645
  return new Promise((accept, reject) => {
1505
- // remove the old renderer instance if any
1506
- this.removeRenderer();
1507
- const sceneID = this.getAttribute("scene-id");
1508
- if (sceneID) {
1509
- const opt = options || this._GetDefaultQROptions();
1510
- const viewer = document.createElement("plattar-qrcode");
1511
- // required attributes with defaults for plattar-viewer node
1512
- const width = this.getAttribute("width") || "500px";
1513
- const height = this.getAttribute("height") || "500px";
1514
- viewer.setAttribute("width", width);
1515
- viewer.setAttribute("height", height);
1516
- if (opt.color) {
1517
- viewer.setAttribute("color", opt.color);
1518
- }
1519
- if (opt.margin) {
1520
- viewer.setAttribute("margin", "" + opt.margin);
1521
- }
1522
- if (opt.qrType) {
1523
- viewer.setAttribute("qr-type", opt.qrType);
1524
- }
1525
- viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
1526
- let dst = plattar_api_1.Server.location().base + "renderer/facear.html?scene_id=" + sceneID;
1527
- // optional attributes
1528
- const configState = this.getAttribute("config-state");
1529
- const showAR = this.getAttribute("show-ar");
1530
- const productID = this.getAttribute("product-id");
1531
- const sceneProductID = this.getAttribute("scene-product-id");
1532
- const variationID = this.getAttribute("variation-id");
1533
- if (configState) {
1534
- dst += "&config_state=" + configState;
1535
- }
1536
- if (showAR) {
1537
- dst += "&show_ar=" + showAR;
1538
- }
1539
- if (productID) {
1540
- dst += "&product_id=" + productID;
1541
- }
1542
- if (sceneProductID) {
1543
- dst += "&scene_product_id=" + sceneProductID;
1544
- }
1545
- if (variationID) {
1546
- dst += "&variation_id=" + variationID;
1547
- }
1548
- viewer.setAttribute("url", opt.url || dst);
1549
- viewer.onload = () => {
1550
- return accept(viewer);
1551
- };
1552
- this.append(viewer);
1553
- this._element = viewer;
1554
- this._state = plattar_controller_1.ControllerState.QRCode;
1555
- this._prevQROpt = opt;
1556
- return;
1557
- }
1558
- return reject(new Error("VTOController.startQRCode() - minimum required attributes not set, use scene-id as a minimum"));
1646
+ viewer.onload = () => {
1647
+ return accept(viewer);
1648
+ };
1649
+ this.append(viewer);
1559
1650
  });
1560
1651
  }
1561
- startRenderer() {
1652
+ async startRenderer() {
1653
+ // remove the old renderer instance if any
1654
+ this.removeRenderer();
1655
+ const sceneID = this.getAttribute("scene-id");
1656
+ if (!sceneID) {
1657
+ throw new Error("VTOController.startRenderer() - minimum required attributes not set, use scene-id as a minimum");
1658
+ }
1659
+ // required attributes with defaults for plattar-facear node
1660
+ const width = this.getAttribute("width") || "500px";
1661
+ const height = this.getAttribute("height") || "500px";
1662
+ const server = this.getAttribute("server") || "production";
1663
+ const viewer = document.createElement("plattar-facear");
1664
+ this._element = viewer;
1665
+ viewer.setAttribute("width", width);
1666
+ viewer.setAttribute("height", height);
1667
+ viewer.setAttribute("server", server);
1668
+ viewer.setAttribute("scene-id", sceneID);
1669
+ // optional attributes
1670
+ let configState = null;
1671
+ try {
1672
+ configState = await this.getConfiguratorState();
1673
+ }
1674
+ catch (_err) {
1675
+ // config state not available
1676
+ configState = null;
1677
+ }
1678
+ const showAR = this.getAttribute("show-ar");
1679
+ const productID = this.getAttribute("product-id");
1680
+ const sceneProductID = this.getAttribute("scene-product-id");
1681
+ const variationID = this.getAttribute("variation-id");
1682
+ if (configState) {
1683
+ viewer.setAttribute("config-state", configState.state.encode());
1684
+ }
1685
+ if (showAR) {
1686
+ viewer.setAttribute("show-ar", showAR);
1687
+ }
1688
+ if (productID) {
1689
+ viewer.setAttribute("product-id", productID);
1690
+ }
1691
+ if (sceneProductID) {
1692
+ viewer.setAttribute("scene-product-id", sceneProductID);
1693
+ }
1694
+ if (variationID) {
1695
+ viewer.setAttribute("variation-id", variationID);
1696
+ }
1697
+ this._state = plattar_controller_1.ControllerState.Renderer;
1562
1698
  return new Promise((accept, reject) => {
1563
- // remove the old renderer instance if any
1564
- this.removeRenderer();
1565
- const sceneID = this.getAttribute("scene-id");
1566
- if (sceneID) {
1567
- // required attributes with defaults for plattar-facear node
1568
- const width = this.getAttribute("width") || "500px";
1569
- const height = this.getAttribute("height") || "500px";
1570
- const server = this.getAttribute("server") || "production";
1571
- const viewer = document.createElement("plattar-facear");
1572
- viewer.setAttribute("width", width);
1573
- viewer.setAttribute("height", height);
1574
- viewer.setAttribute("server", server);
1575
- viewer.setAttribute("scene-id", sceneID);
1576
- // optional attributes
1577
- const configState = this.getAttribute("config-state");
1578
- const showAR = this.getAttribute("show-ar");
1579
- const productID = this.getAttribute("product-id");
1580
- const sceneProductID = this.getAttribute("scene-product-id");
1581
- const variationID = this.getAttribute("variation-id");
1582
- if (configState) {
1583
- viewer.setAttribute("config-state", configState);
1584
- }
1585
- if (showAR) {
1586
- viewer.setAttribute("show-ar", showAR);
1587
- }
1588
- if (productID) {
1589
- viewer.setAttribute("product-id", productID);
1590
- }
1591
- if (sceneProductID) {
1592
- viewer.setAttribute("scene-product-id", sceneProductID);
1593
- }
1594
- if (variationID) {
1595
- viewer.setAttribute("variation-id", variationID);
1596
- }
1597
- viewer.onload = () => {
1598
- return accept(viewer);
1599
- };
1600
- this.append(viewer);
1601
- this._element = viewer;
1602
- this._state = plattar_controller_1.ControllerState.Renderer;
1603
- return;
1699
+ this.append(viewer);
1700
+ if (configState) {
1701
+ this.setupMessengerObservers(viewer, configState);
1604
1702
  }
1605
- return reject(new Error("VTOController.startRenderer() - minimum required attributes not set, use scene-id as a minimum"));
1703
+ return accept(viewer);
1606
1704
  });
1607
1705
  }
1608
- initAR() {
1609
- return new Promise((accept, reject) => {
1610
- if (!util_1.Util.canAugment()) {
1611
- return reject(new Error("VTOController.initAR() - cannot proceed as VTO AR not available in context"));
1612
- }
1613
- if (!(util_1.Util.isSafari() || util_1.Util.isChromeOnIOS())) {
1614
- return reject(new Error("VTOController.initAR() - cannot proceed as VTO AR only available on IOS Mobile devices"));
1615
- }
1616
- const arMode = this.getAttribute("ar-mode") || "generated";
1617
- switch (arMode.toLowerCase()) {
1618
- case "inherited":
1619
- this._InitARInherited(accept, reject);
1620
- return;
1621
- case "generated":
1622
- default:
1623
- this._InitARGenerated(accept, reject);
1624
- }
1625
- });
1706
+ async initAR() {
1707
+ if (!util_1.Util.canAugment()) {
1708
+ throw new Error("VTOController.initAR() - cannot proceed as VTO AR not available in context");
1709
+ }
1710
+ if (!(util_1.Util.isSafari() || util_1.Util.isChromeOnIOS())) {
1711
+ throw new Error("VTOController.initAR() - cannot proceed as VTO AR only available on IOS Mobile devices");
1712
+ }
1713
+ const arMode = this.getAttribute("ar-mode") || "generated";
1714
+ switch (arMode.toLowerCase()) {
1715
+ case "inherited":
1716
+ return this._InitARInherited();
1717
+ case "generated":
1718
+ default:
1719
+ return this._InitARGenerated();
1720
+ }
1626
1721
  }
1627
1722
  /**
1628
1723
  * Private Function - This launches the Static/Inherited AR Mode
1629
1724
  */
1630
- _InitARInherited(accept, reject) {
1725
+ async _InitARInherited() {
1631
1726
  const sceneID = this.getAttribute("scene-id");
1632
- const configState = this.getAttribute("config-state");
1633
- // use config-state if its available
1634
- if (sceneID && configState) {
1635
- const state = __1.ConfiguratorState.decode(configState);
1636
- const first = state.first();
1637
- if (first) {
1638
- const sceneProductAR = new __1.SceneProductAR(first.scene_product_id, first.product_variation_id);
1639
- sceneProductAR.init().then(accept).catch(reject);
1640
- return;
1641
- }
1642
- return reject(new Error("VTOController.initAR() - invalid config-state does not have any product states"));
1727
+ if (!sceneID) {
1728
+ throw new Error("VTOController.initAR() - inherited AR minimum required attributes not set, use scene-id as a minimum");
1643
1729
  }
1644
- // otherwise fallback to using scene
1645
- if (sceneID) {
1646
- __1.ConfiguratorState.decodeScene(sceneID).then((state) => {
1647
- const first = state.first();
1648
- if (first) {
1649
- const sceneProductAR = new __1.SceneProductAR(first.scene_product_id, first.product_variation_id);
1650
- return sceneProductAR.init().then(accept).catch(reject);
1651
- }
1652
- return reject(new Error("VTOController.initAR() - invalid Scene does not have any product states"));
1653
- }).catch(reject);
1654
- return;
1730
+ const state = (await this.getConfiguratorState()).state;
1731
+ const first = state.first();
1732
+ if (first) {
1733
+ const sceneProductAR = new __1.SceneProductAR(first.scene_product_id, first.product_variation_id);
1734
+ return sceneProductAR.init();
1655
1735
  }
1656
- return reject(new Error("VTOController.initAR() - minimum required attributes not set, use scene-id as a minimum"));
1736
+ throw new Error("VTOController.initAR() - invalid decoded config-state does not have any product states");
1657
1737
  }
1658
1738
  /**
1659
1739
  * Private Function - This launches the Dynamic/Generated AR Mode
1660
1740
  */
1661
- _InitARGenerated(accept, reject) {
1662
- // if scene ID is available and the state is a configurator viewer
1663
- // we can use the real-time configurator state to launch the AR view
1664
- const viewer = this.element;
1741
+ async _InitARGenerated() {
1665
1742
  const sceneID = this.getAttribute("scene-id");
1666
- if (viewer && sceneID && viewer.messenger) {
1667
- viewer.messenger.getARFile("vto").then((result) => {
1668
- const rawAR = new raw_ar_1.RawAR(result.filename);
1669
- return rawAR.init().then(accept).catch(reject);
1670
- }).catch(reject);
1671
- return;
1672
- }
1673
- const configState = this.getAttribute("config-state");
1674
- // otherwise scene ID is available to the viewer is not launched
1675
- // we can use the static configuration state to launch the AR view
1676
- if (sceneID && configState) {
1677
- const state = __1.ConfiguratorState.decode(configState);
1678
- if (state.length > 0) {
1679
- const server = this.getAttribute("server") || "production";
1680
- const configurator = new plattar_services_1.Configurator();
1681
- configurator.server = server;
1682
- configurator.output = "vto";
1683
- state.forEach((productState) => {
1684
- if (productState.meta_data.augment === true) {
1685
- configurator.addSceneProduct(productState.scene_product_id, productState.product_variation_id);
1686
- }
1687
- });
1688
- configurator.get().then((result) => {
1689
- const rawAR = new raw_ar_1.RawAR(result.filename);
1690
- rawAR.init().then(accept).catch(reject);
1691
- }).catch(reject);
1692
- return;
1693
- }
1694
- return reject(new Error("VTOController.initAR() - invalid config-state does not have any product states"));
1695
- }
1696
- // otherwise no config-state or viewer is active
1697
- // fallback to using default SceneAR implementation
1698
- if (sceneID) {
1699
- const productID = this.getAttribute("product-id");
1700
- const sceneProductID = this.getAttribute("scene-product-id");
1701
- const variationID = this.getAttribute("variation-id");
1702
- const sceneAR = new __1.SceneAR(sceneID, {
1703
- productID: productID ? productID : undefined,
1704
- sceneProductID: sceneProductID ? sceneProductID : undefined,
1705
- variationID: variationID ? variationID : undefined
1706
- });
1707
- sceneAR.init().then(accept).catch(reject);
1708
- return;
1743
+ if (!sceneID) {
1744
+ throw new Error("VTOController.initAR() - generated AR minimum required attributes not set, use scene-id as a minimum");
1709
1745
  }
1710
- return reject(new Error("VTOController.initAR() - minimum required attributes not set, use scene-id as a minimum"));
1746
+ const configAR = new configurator_ar_1.ConfiguratorAR(await this.getConfiguratorState());
1747
+ return configAR.init();
1711
1748
  }
1712
1749
  removeRenderer() {
1713
1750
  if (this._element) {
@@ -1715,6 +1752,7 @@ class VTOController extends plattar_controller_1.PlattarController {
1715
1752
  this._element = null;
1716
1753
  return true;
1717
1754
  }
1755
+ this.removeMessengerObservers();
1718
1756
  return false;
1719
1757
  }
1720
1758
  get element() {
@@ -1723,22 +1761,22 @@ class VTOController extends plattar_controller_1.PlattarController {
1723
1761
  }
1724
1762
  exports.VTOController = VTOController;
1725
1763
 
1726
- },{"../..":13,"../../ar/raw-ar":4,"../../util/util":15,"./plattar-controller":8,"@plattar/plattar-api":44,"@plattar/plattar-services":115}],12:[function(require,module,exports){
1764
+ },{"../..":13,"../../ar/configurator-ar":1,"../../util/util":15,"./plattar-controller":9,"@plattar/plattar-api":44}],12:[function(require,module,exports){
1727
1765
  "use strict";
1728
1766
  Object.defineProperty(exports, "__esModule", { value: true });
1729
1767
  const plattar_api_1 = require("@plattar/plattar-api");
1730
- const product_controller_1 = require("./controllers/product-controller");
1731
- const viewer_controller_1 = require("./controllers/viewer-controller");
1732
1768
  const configurator_controller_1 = require("./controllers/configurator-controller");
1733
1769
  const vto_controller_1 = require("./controllers/vto-controller");
1770
+ const product_controller_1 = require("./controllers/product-controller");
1734
1771
  /**
1735
1772
  * This tracks the current embed type
1736
1773
  */
1737
1774
  var EmbedType;
1738
1775
  (function (EmbedType) {
1739
- EmbedType[EmbedType["Viewer"] = 0] = "Viewer";
1740
- EmbedType[EmbedType["Configurator"] = 1] = "Configurator";
1776
+ EmbedType[EmbedType["Configurator"] = 0] = "Configurator";
1777
+ EmbedType[EmbedType["Legacy"] = 1] = "Legacy";
1741
1778
  EmbedType[EmbedType["VTO"] = 2] = "VTO";
1779
+ EmbedType[EmbedType["None"] = 3] = "None";
1742
1780
  })(EmbedType || (EmbedType = {}));
1743
1781
  /**
1744
1782
  * This is the primary <plattar-embed /> node that allows easy embedding
@@ -1748,115 +1786,154 @@ class PlattarEmbed extends HTMLElement {
1748
1786
  constructor() {
1749
1787
  super();
1750
1788
  // this is the current embed type, viewer by default
1751
- this._currentType = EmbedType.Viewer;
1789
+ this._currentType = EmbedType.None;
1752
1790
  this._controller = null;
1791
+ this._currentSceneID = null;
1792
+ this._observer = null;
1753
1793
  }
1754
1794
  get viewer() {
1755
1795
  return this._controller ? this._controller.element : null;
1756
1796
  }
1797
+ /**
1798
+ * Begin observing all changes to this DOM element
1799
+ */
1757
1800
  connectedCallback() {
1758
- const embedType = this.hasAttribute("embed-type") ? this.getAttribute("embed-type") : "viewer";
1801
+ this.create();
1802
+ }
1803
+ /**
1804
+ * creates a brand new instance of this embed
1805
+ */
1806
+ create() {
1807
+ // server cannot be changed once its set - defaults to production
1808
+ const server = this.hasAttribute("server") ? this.getAttribute("server") : "production";
1809
+ plattar_api_1.Server.create(plattar_api_1.Server.match(server || "production"));
1810
+ if (!this._observer) {
1811
+ this._observer = new MutationObserver((mutations) => {
1812
+ mutations.forEach((mutation) => {
1813
+ if (mutation.type === "attributes") {
1814
+ const attributeName = mutation.attributeName ? mutation.attributeName : "none";
1815
+ if (this._currentType !== EmbedType.Legacy) {
1816
+ this._CreateEmbed(attributeName);
1817
+ }
1818
+ else {
1819
+ this._OnAttributesUpdated(attributeName);
1820
+ }
1821
+ }
1822
+ });
1823
+ });
1824
+ this._observer.observe(this, {
1825
+ attributes: true
1826
+ });
1827
+ }
1828
+ const sceneID = this.hasAttribute("scene-id") ? this.getAttribute("scene-id") : null;
1829
+ const productID = this.hasAttribute("product-id") ? this.getAttribute("product-id") : null;
1830
+ if (!sceneID && productID) {
1831
+ this._currentType = EmbedType.Legacy;
1832
+ this._CreateLegacyEmbed();
1833
+ return;
1834
+ }
1835
+ this._CreateEmbed("none");
1836
+ }
1837
+ /**
1838
+ * Destroys the active instance of this embed and resets internal state to default
1839
+ */
1840
+ destroy() {
1841
+ if (this._controller) {
1842
+ this._controller.removeRenderer();
1843
+ this._controller = null;
1844
+ }
1845
+ this._currentType = EmbedType.None;
1846
+ }
1847
+ /**
1848
+ * this is only used for backwards-compatible legacy embed types typically
1849
+ * embedding products with variations (without a scene-id)
1850
+ */
1851
+ _CreateLegacyEmbed() {
1852
+ this._controller = new product_controller_1.ProductController(this);
1853
+ }
1854
+ /**
1855
+ * creates the embed
1856
+ * this can also be called when attributes/state changes so embeds can be re-loaded
1857
+ */
1858
+ _CreateEmbed(attributeName) {
1859
+ const embedType = this.hasAttribute("embed-type") ? this.getAttribute("embed-type") : "configurator";
1860
+ const currentEmbed = this._currentType;
1759
1861
  if (embedType) {
1760
1862
  switch (embedType.toLowerCase()) {
1761
- case "viewer":
1762
- this._currentType = EmbedType.Viewer;
1763
- break;
1764
1863
  case "vto":
1765
1864
  this._currentType = EmbedType.VTO;
1766
1865
  break;
1866
+ case "viewer":
1767
1867
  case "configurator":
1768
- this._currentType = EmbedType.Configurator;
1769
- break;
1770
1868
  default:
1771
- this._currentType = EmbedType.Viewer;
1869
+ this._currentType = EmbedType.Configurator;
1772
1870
  }
1773
1871
  }
1774
- const observer = new MutationObserver((mutations) => {
1775
- mutations.forEach((mutation) => {
1776
- if (mutation.type === "attributes") {
1777
- this._OnAttributesUpdated();
1778
- }
1779
- });
1780
- });
1781
- observer.observe(this, {
1782
- attributes: true
1783
- });
1784
- const server = this.hasAttribute("server") ? this.getAttribute("server") : "production";
1785
- plattar_api_1.Server.create(plattar_api_1.Server.match(server || "production"));
1872
+ // check if the controller needs to be re-created
1873
+ if ((currentEmbed !== this._currentType) && this._controller) {
1874
+ this._controller.removeRenderer();
1875
+ this._controller = null;
1876
+ }
1786
1877
  const sceneID = this.hasAttribute("scene-id") ? this.getAttribute("scene-id") : null;
1787
- const productID = this.hasAttribute("product-id") ? this.getAttribute("product-id") : null;
1788
- // decide which controller to initialise
1789
- if (this._currentType === EmbedType.Viewer) {
1790
- // initialise product if scene-id is missing but product-id is defined
1791
- if (!sceneID && productID) {
1792
- this._controller = new product_controller_1.ProductController(this);
1878
+ // if the provided SceneID doesn't match, we need to remove the controller
1879
+ if ((sceneID !== this._currentSceneID) && this._controller) {
1880
+ this._controller.removeRenderer();
1881
+ this._controller = null;
1882
+ }
1883
+ this._currentSceneID = sceneID;
1884
+ // scene-id is the absolute minimum in order to initialise the embeds
1885
+ if (!this._currentSceneID) {
1886
+ return;
1887
+ }
1888
+ // if the controller was removed due to state-change, we need to re-initialise it
1889
+ if (!this._controller) {
1890
+ switch (this._currentType) {
1891
+ case EmbedType.Configurator:
1892
+ this._controller = new configurator_controller_1.ConfiguratorController(this);
1893
+ break;
1894
+ case EmbedType.VTO:
1895
+ this._controller = new vto_controller_1.VTOController(this);
1896
+ break;
1793
1897
  }
1794
- else if (sceneID) {
1795
- this._controller = new viewer_controller_1.ViewerController(this);
1898
+ if (this._controller) {
1899
+ const init = this.hasAttribute("init") ? this.getAttribute("init") : null;
1900
+ switch (init) {
1901
+ case "viewer":
1902
+ this.startViewer();
1903
+ break;
1904
+ case "qrcode":
1905
+ this.startQRCode();
1906
+ break;
1907
+ }
1796
1908
  }
1797
1909
  }
1798
- else if (this._currentType === EmbedType.Configurator) {
1799
- this._controller = new configurator_controller_1.ConfiguratorController(this);
1800
- }
1801
- else if (this._currentType === EmbedType.VTO) {
1802
- this._controller = new vto_controller_1.VTOController(this);
1803
- }
1804
- const init = this.hasAttribute("init") ? this.getAttribute("init") : null;
1805
- if (init === "ar") {
1806
- this.startAR();
1807
- }
1808
- else if (init === "viewer") {
1809
- this.startViewer();
1810
- }
1811
- else if (init === "qrcode") {
1812
- this.startQRCode();
1813
- }
1814
- else if (init === "ar-fallback-qrcode") {
1815
- this.startAR().then(() => {
1816
- // nothing to do, launched successfully
1817
- }).catch((_err) => {
1818
- this.startQRCode();
1819
- });
1820
- }
1821
- else if (init === "ar-fallback-viewer") {
1822
- this.startAR().then(() => {
1823
- // nothing to do, launched successfully
1824
- }).catch((_err) => {
1825
- this.startViewer();
1826
- });
1910
+ else {
1911
+ this._OnAttributesUpdated(attributeName);
1827
1912
  }
1828
1913
  }
1829
- initAR() {
1830
- return new Promise((accept, reject) => {
1831
- if (!this._controller) {
1832
- return reject(new Error("PlattarEmbed.initAR() - cannot execute as controller has not loaded yet"));
1833
- }
1834
- return this._controller.initAR().then(accept).catch(reject);
1835
- });
1914
+ async initAR() {
1915
+ if (!this._controller) {
1916
+ throw new Error("PlattarEmbed.initAR() - cannot execute as controller has not loaded yet");
1917
+ }
1918
+ return this._controller.initAR();
1836
1919
  }
1837
- startAR() {
1838
- return new Promise((accept, reject) => {
1839
- if (!this._controller) {
1840
- return reject(new Error("PlattarEmbed.startAR() - cannot execute as controller has not loaded yet"));
1841
- }
1842
- return this._controller.startAR().then(accept).catch(reject);
1843
- });
1920
+ async startAR() {
1921
+ if (!this._controller) {
1922
+ throw new Error("PlattarEmbed.startAR() - cannot execute as controller has not loaded yet");
1923
+ }
1924
+ return this._controller.startAR();
1844
1925
  }
1845
- startViewer() {
1846
- return new Promise((accept, reject) => {
1847
- if (!this._controller) {
1848
- return reject(new Error("PlattarEmbed.startViewer() - cannot execute as controller has not loaded yet"));
1849
- }
1850
- return this._controller.startRenderer().then(accept).catch(reject);
1851
- });
1926
+ async startViewer() {
1927
+ if (!this._controller) {
1928
+ throw new Error("PlattarEmbed.startViewer() - cannot execute as controller has not loaded yet");
1929
+ }
1930
+ return this._controller.startRenderer();
1852
1931
  }
1853
- startQRCode(options = null) {
1854
- return new Promise((accept, reject) => {
1855
- if (!this._controller) {
1856
- return reject(new Error("PlattarEmbed.startQRCode() - cannot execute as controller has not loaded yet"));
1857
- }
1858
- return this._controller.startQRCode(options).then(accept).catch(reject);
1859
- });
1932
+ async startQRCode(options = null) {
1933
+ if (!this._controller) {
1934
+ throw new Error("PlattarEmbed.startQRCode() - cannot execute as controller has not loaded yet");
1935
+ }
1936
+ return this._controller.startQRCode(options);
1860
1937
  }
1861
1938
  /**
1862
1939
  * This will remove the currently active Renderer
@@ -1873,15 +1950,15 @@ class PlattarEmbed extends HTMLElement {
1873
1950
  * This is called by the observer if any of the embed attributes have changed
1874
1951
  * based on the state of the embed, we update the internal structure accordingly
1875
1952
  */
1876
- _OnAttributesUpdated() {
1953
+ _OnAttributesUpdated(attributeName) {
1877
1954
  if (this._controller) {
1878
- this._controller.onAttributesUpdated();
1955
+ this._controller.onAttributesUpdated(attributeName);
1879
1956
  }
1880
1957
  }
1881
1958
  }
1882
1959
  exports.default = PlattarEmbed;
1883
1960
 
1884
- },{"./controllers/configurator-controller":7,"./controllers/product-controller":9,"./controllers/viewer-controller":10,"./controllers/vto-controller":11,"@plattar/plattar-api":44}],13:[function(require,module,exports){
1961
+ },{"./controllers/configurator-controller":8,"./controllers/product-controller":10,"./controllers/vto-controller":11,"@plattar/plattar-api":44}],13:[function(require,module,exports){
1885
1962
  "use strict";
1886
1963
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1887
1964
  if (k2 === undefined) k2 = k;
@@ -1939,16 +2016,23 @@ if (customElements) {
1939
2016
  }
1940
2017
  console.log("using @plattar/plattar-ar-adapter v" + version_1.default);
1941
2018
 
1942
- },{"./ar/launcher-ar":1,"./ar/model-ar":2,"./ar/product-ar":3,"./ar/raw-ar":4,"./ar/scene-ar":5,"./ar/scene-product-ar":6,"./embed/plattar-embed":12,"./util/configurator-state":14,"./util/util":15,"./version":16,"@plattar/plattar-qrcode":110,"@plattar/plattar-web":130}],14:[function(require,module,exports){
2019
+ },{"./ar/launcher-ar":2,"./ar/model-ar":3,"./ar/product-ar":4,"./ar/raw-ar":5,"./ar/scene-ar":6,"./ar/scene-product-ar":7,"./embed/plattar-embed":12,"./util/configurator-state":14,"./util/util":15,"./version":16,"@plattar/plattar-qrcode":110,"@plattar/plattar-web":130}],14:[function(require,module,exports){
1943
2020
  "use strict";
1944
2021
  Object.defineProperty(exports, "__esModule", { value: true });
1945
2022
  exports.ConfiguratorState = void 0;
1946
2023
  const plattar_api_1 = require("@plattar/plattar-api");
2024
+ /**
2025
+ * Manages a Configuration State of multiple Products with multiple Variations
2026
+ * Allows easily changing
2027
+ */
1947
2028
  class ConfiguratorState {
1948
2029
  constructor(state = null) {
2030
+ this._mappedVariationIDValues = new Map();
2031
+ this._mappedVariationSKUValues = new Map();
1949
2032
  const defaultState = {
1950
2033
  meta: {
1951
2034
  scene_product_index: 0,
2035
+ scene_model_index: 0,
1952
2036
  product_variation_index: 1,
1953
2037
  meta_index: 2,
1954
2038
  },
@@ -1961,6 +2045,7 @@ class ConfiguratorState {
1961
2045
  // set the meta data
1962
2046
  if (parsedState.meta) {
1963
2047
  defaultState.meta.scene_product_index = parsedState.meta.scene_product_index || 0;
2048
+ defaultState.meta.scene_model_index = parsedState.meta.scene_model_index || 0;
1964
2049
  defaultState.meta.product_variation_index = parsedState.meta.product_variation_index || 1;
1965
2050
  defaultState.meta.meta_index = parsedState.meta.meta_index || 2;
1966
2051
  }
@@ -1973,6 +2058,30 @@ class ConfiguratorState {
1973
2058
  }
1974
2059
  this._state = defaultState;
1975
2060
  }
2061
+ /**
2062
+ * Modifyes the SceneProduct that this Variation SKU belongs to and changes for
2063
+ * purposes of Configuration
2064
+ */
2065
+ setVariationSKU(productVariationSKU) {
2066
+ const variationID = this._mappedVariationSKUValues.get(productVariationSKU);
2067
+ if (!variationID) {
2068
+ console.warn("ConfiguratorState.setVariationSKU() - Variation SKU of " + productVariationSKU + " is not defined in any variations");
2069
+ return;
2070
+ }
2071
+ this.setVariationID(variationID);
2072
+ }
2073
+ /**
2074
+ * Modifyes the SceneProduct that this Variation belongs to and changes for
2075
+ * purposes of Configuration
2076
+ */
2077
+ setVariationID(productVariationID) {
2078
+ const sceneProductID = this._mappedVariationIDValues.get(productVariationID);
2079
+ if (!sceneProductID) {
2080
+ console.warn("ConfiguratorState.setVariationID() - Variation ID of " + productVariationID + " is not defined in any products");
2081
+ return;
2082
+ }
2083
+ this.setSceneProduct(sceneProductID, productVariationID);
2084
+ }
1976
2085
  /**
1977
2086
  * Adds a new Scene Product/Variation combo with meta-data into the Configurator State
1978
2087
  *
@@ -1983,6 +2092,34 @@ class ConfiguratorState {
1983
2092
  setSceneProduct(sceneProductID, productVariationID, metaData = null) {
1984
2093
  this.addSceneProduct(sceneProductID, productVariationID, metaData);
1985
2094
  }
2095
+ /**
2096
+ * Adds a new SceneModel with meta-data into the Configurator State. Note that the SceneProductDataMeta will
2097
+ * override the isSceneModel variable and assign to "true" automatically
2098
+ *
2099
+ * @param SceneModelID - The SceneModel ID to add
2100
+ * @param metaData - Arbitrary meta-data that can be used against certain operaions
2101
+ */
2102
+ setSceneModel(SceneModelID, metaData = null) {
2103
+ if (SceneModelID) {
2104
+ metaData = metaData || { augment: true, type: "scenemodel" };
2105
+ metaData.type = "scenemodel";
2106
+ const states = this._state.states;
2107
+ const meta = this._state.meta;
2108
+ let newData = null;
2109
+ const existingData = this.findSceneProductIndex(SceneModelID);
2110
+ if (existingData) {
2111
+ newData = existingData;
2112
+ }
2113
+ else {
2114
+ newData = [];
2115
+ // push the new data into the stack
2116
+ states.push(newData);
2117
+ }
2118
+ newData[meta.scene_product_index] = SceneModelID;
2119
+ newData[meta.product_variation_index] = null;
2120
+ newData[meta.meta_index] = metaData;
2121
+ }
2122
+ }
1986
2123
  /**
1987
2124
  * Adds a new Scene Product/Variation combo with meta-data into the Configurator State
1988
2125
  *
@@ -1992,6 +2129,8 @@ class ConfiguratorState {
1992
2129
  */
1993
2130
  addSceneProduct(sceneProductID, productVariationID, metaData = null) {
1994
2131
  if (sceneProductID && productVariationID) {
2132
+ metaData = metaData || { augment: true, type: "sceneproduct" };
2133
+ metaData.type = "sceneproduct";
1995
2134
  const states = this._state.states;
1996
2135
  const meta = this._state.meta;
1997
2136
  let newData = null;
@@ -2006,9 +2145,7 @@ class ConfiguratorState {
2006
2145
  }
2007
2146
  newData[meta.scene_product_index] = sceneProductID;
2008
2147
  newData[meta.product_variation_index] = productVariationID;
2009
- if (metaData) {
2010
- newData[meta.meta_index] = metaData;
2011
- }
2148
+ newData[meta.meta_index] = metaData;
2012
2149
  }
2013
2150
  }
2014
2151
  /**
@@ -2040,12 +2177,14 @@ class ConfiguratorState {
2040
2177
  scene_product_id: found[meta.scene_product_index],
2041
2178
  product_variation_id: found[meta.product_variation_index],
2042
2179
  meta_data: {
2043
- augment: true
2180
+ augment: true,
2181
+ type: "sceneproduct"
2044
2182
  }
2045
2183
  };
2046
2184
  // include the meta-data
2047
2185
  if (found.length === 3) {
2048
2186
  data.meta_data.augment = found[meta.meta_index].augment || true;
2187
+ data.meta_data.type = found[meta.meta_index].type || "sceneproduct";
2049
2188
  }
2050
2189
  return data;
2051
2190
  }
@@ -2064,7 +2203,8 @@ class ConfiguratorState {
2064
2203
  scene_product_id: productState[meta.scene_product_index],
2065
2204
  product_variation_id: productState[meta.product_variation_index],
2066
2205
  meta_data: {
2067
- augment: true
2206
+ augment: true,
2207
+ type: "sceneproduct"
2068
2208
  }
2069
2209
  });
2070
2210
  }
@@ -2073,13 +2213,24 @@ class ConfiguratorState {
2073
2213
  scene_product_id: productState[meta.scene_product_index],
2074
2214
  product_variation_id: productState[meta.product_variation_index],
2075
2215
  meta_data: {
2076
- augment: productState[meta.meta_index].augment || true
2216
+ augment: productState[meta.meta_index].augment || true,
2217
+ type: productState[meta.meta_index].type || "sceneproduct"
2077
2218
  }
2078
2219
  });
2079
2220
  }
2080
2221
  });
2081
2222
  }
2082
2223
  }
2224
+ /**
2225
+ * Compose and return an array of all internal objects
2226
+ */
2227
+ array() {
2228
+ const array = new Array();
2229
+ this.forEach((object) => {
2230
+ array.push(object);
2231
+ });
2232
+ return array;
2233
+ }
2083
2234
  /**
2084
2235
  * @returns Returns the first reference of data in the stack, otherwise returns null
2085
2236
  */
@@ -2099,12 +2250,14 @@ class ConfiguratorState {
2099
2250
  scene_product_id: found[meta.scene_product_index],
2100
2251
  product_variation_id: found[meta.product_variation_index],
2101
2252
  meta_data: {
2102
- augment: true
2253
+ augment: true,
2254
+ type: "sceneproduct"
2103
2255
  }
2104
2256
  };
2105
2257
  // include the meta-data
2106
2258
  if (found.length === 3) {
2107
2259
  data.meta_data.augment = found[meta.meta_index].augment || true;
2260
+ data.meta_data.type = found[meta.meta_index].type || "sceneproduct";
2108
2261
  }
2109
2262
  return data;
2110
2263
  }
@@ -2122,37 +2275,78 @@ class ConfiguratorState {
2122
2275
  static decode(state) {
2123
2276
  return new ConfiguratorState(state);
2124
2277
  }
2278
+ /**
2279
+ * Decodes a previously generated state
2280
+ * @param sceneID
2281
+ * @param state
2282
+ * @returns
2283
+ */
2284
+ static async decodeState(sceneID = null, state = null) {
2285
+ if (!sceneID || !state) {
2286
+ throw new Error("ConfiguratorState.decodeState(sceneID, state) - sceneID and state must be defined");
2287
+ }
2288
+ const configState = new ConfiguratorState(state);
2289
+ const fscene = new plattar_api_1.Scene(sceneID);
2290
+ fscene.include(plattar_api_1.Project);
2291
+ fscene.include(plattar_api_1.SceneProduct);
2292
+ fscene.include(plattar_api_1.SceneModel);
2293
+ fscene.include(plattar_api_1.SceneProduct.include(plattar_api_1.Product.include(plattar_api_1.ProductVariation)));
2294
+ const scene = await fscene.get();
2295
+ return {
2296
+ scene: scene,
2297
+ state: configState
2298
+ };
2299
+ }
2125
2300
  /**
2126
2301
  * Generates a new ConfiguratorState instance from all SceneProducts and default
2127
2302
  * variations from the provided Scene ID
2128
2303
  * @param sceneID - the Scene ID to generate
2129
2304
  * @returns - Promise that resolves into a ConfiguratorState instance
2130
2305
  */
2131
- static decodeScene(sceneID = null) {
2132
- return new Promise((accept, reject) => {
2133
- const configState = new ConfiguratorState();
2134
- if (!sceneID) {
2135
- return reject(new Error("ConfiguratorState.decodeScene(sceneID) - sceneID must be defined"));
2136
- }
2137
- const scene = new plattar_api_1.Scene(sceneID);
2138
- scene.include(plattar_api_1.SceneProduct);
2139
- scene.include(plattar_api_1.SceneProduct.include(plattar_api_1.Product));
2140
- scene.get().then((scene) => {
2141
- const sceneProducts = scene.relationships.filter(plattar_api_1.SceneProduct);
2142
- // nothing to do if no AR components can be found
2143
- if (sceneProducts.length <= 0) {
2144
- return accept(configState);
2306
+ static async decodeScene(sceneID = null) {
2307
+ if (!sceneID) {
2308
+ throw new Error("ConfiguratorState.decodeScene(sceneID) - sceneID must be defined");
2309
+ }
2310
+ const configState = new ConfiguratorState();
2311
+ const fscene = new plattar_api_1.Scene(sceneID);
2312
+ fscene.include(plattar_api_1.Project);
2313
+ fscene.include(plattar_api_1.SceneProduct);
2314
+ fscene.include(plattar_api_1.SceneModel);
2315
+ fscene.include(plattar_api_1.SceneProduct.include(plattar_api_1.Product.include(plattar_api_1.ProductVariation)));
2316
+ const scene = await fscene.get();
2317
+ const sceneProducts = scene.relationships.filter(plattar_api_1.SceneProduct);
2318
+ const sceneModels = scene.relationships.filter(plattar_api_1.SceneModel);
2319
+ // add out scene models
2320
+ sceneModels.forEach((sceneModel) => {
2321
+ configState.setSceneModel(sceneModel.id, {
2322
+ augment: sceneModel.attributes.include_in_augment,
2323
+ type: "scenemodel"
2324
+ });
2325
+ });
2326
+ // add out scene products
2327
+ sceneProducts.forEach((sceneProduct) => {
2328
+ const product = sceneProduct.relationships.find(plattar_api_1.Product);
2329
+ if (product) {
2330
+ if (product.attributes.product_variation_id) {
2331
+ configState.setSceneProduct(sceneProduct.id, product.attributes.product_variation_id, {
2332
+ augment: sceneProduct.attributes.include_in_augment,
2333
+ type: "sceneproduct"
2334
+ });
2145
2335
  }
2146
- // add out scene models
2147
- sceneProducts.forEach((sceneProduct) => {
2148
- const product = sceneProduct.relationships.find(plattar_api_1.Product);
2149
- if (product && product.attributes.product_variation_id) {
2150
- configState.setSceneProduct(sceneProduct.id, product.attributes.product_variation_id);
2336
+ // add the variation to an acceptible range of values
2337
+ const variations = product.relationships.filter(plattar_api_1.ProductVariation);
2338
+ variations.forEach((variation) => {
2339
+ configState._mappedVariationIDValues.set(variation.id, sceneProduct.id);
2340
+ if (variation.attributes.sku) {
2341
+ configState._mappedVariationSKUValues.set(variation.attributes.sku, variation.id);
2151
2342
  }
2152
2343
  });
2153
- accept(configState);
2154
- }).catch(reject);
2344
+ }
2155
2345
  });
2346
+ return {
2347
+ scene: scene,
2348
+ state: configState
2349
+ };
2156
2350
  }
2157
2351
  /**
2158
2352
  * Encode and return the internal ConfiguratorState as a Base64 String
@@ -2241,7 +2435,7 @@ exports.Util = Util;
2241
2435
  },{}],16:[function(require,module,exports){
2242
2436
  "use strict";
2243
2437
  Object.defineProperty(exports, "__esModule", { value: true });
2244
- exports.default = "1.154.2";
2438
+ exports.default = "1.155.1";
2245
2439
 
2246
2440
  },{}],17:[function(require,module,exports){
2247
2441
  "use strict";