@searchspring/snap-store-mobx 0.52.1 → 0.52.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,11 +14,16 @@ export declare class Banner {
14
14
  value: string;
15
15
  constructor(services: StoreServices, banner: SearchResponseModelMerchandisingContentInline);
16
16
  }
17
- type VariantData = {
17
+ export type VariantData = {
18
18
  mappings: SearchResponseModelResultMappings;
19
19
  attributes: Record<string, unknown>;
20
20
  options: Record<string, string>;
21
21
  };
22
+ type ProductMinimal = {
23
+ id: string;
24
+ attributes: Record<string, unknown>;
25
+ mappings: SearchResponseModelResultMappings;
26
+ };
22
27
  export declare class Product {
23
28
  type: string;
24
29
  id: string;
@@ -27,23 +32,24 @@ export declare class Product {
27
32
  custom: {};
28
33
  children?: Array<Child>;
29
34
  quantity: number;
30
- display: VariantData;
35
+ mask: ProductMask;
31
36
  variants?: Variants;
32
37
  constructor(services: StoreServices, result: SearchResponseModelResult, config?: StoreConfigs);
33
- updateDisplay: (display?: {
34
- mappings: SearchResponseModelResultMappings;
35
- attributes: Record<string, unknown>;
36
- options: Record<string, string>;
37
- }) => void;
38
+ get display(): ProductMinimal;
39
+ }
40
+ export declare class ProductMask {
41
+ data: Partial<Product>;
42
+ constructor();
43
+ merge(mask: Partial<Product>): void;
44
+ set(mask: Partial<Product>): void;
45
+ reset(): void;
38
46
  }
39
- declare class Variants {
47
+ export declare class Variants {
40
48
  active?: Variant;
41
49
  data: Variant[];
42
50
  selections: VariantSelection[];
43
- config: StoreConfigs;
44
- updateDisplay: (variant: VariantData) => void;
45
- constructor(config: StoreConfigs, services: StoreServices, variantData: VariantData[], updateDisplay: (variant: VariantData) => void);
46
- setActive(variant: Variant): void;
51
+ setActive: (variant: Variant) => void;
52
+ constructor(variantData: VariantData[], mask: ProductMask);
47
53
  makeSelections(options?: Record<string, string>): void;
48
54
  update(fromSelection: VariantSelection): void;
49
55
  }
@@ -60,20 +66,20 @@ export declare class VariantSelection {
60
66
  selected?: string;
61
67
  previouslySelected?: string;
62
68
  values: SelectionValue[];
63
- private variants;
64
- constructor(config: StoreConfigs, services: StoreServices, variants: Variants, selectorConfig: VariantSelectionOptions, data: Variant[]);
65
- refineSelections(allVariants: Variant[]): void;
69
+ private variantsUpdate;
70
+ constructor(variants: Variants, selectorConfig: VariantSelectionOptions);
71
+ refineSelections(variants: Variants): void;
66
72
  reset(): void;
67
73
  select(value: string, internalSelection?: boolean): void;
68
74
  }
69
- declare class Variant {
75
+ export declare class Variant {
70
76
  type: string;
71
77
  available: boolean;
72
78
  attributes: Record<string, unknown>;
73
79
  options: Record<string, string>;
74
80
  mappings: SearchResponseModelResultMappings;
75
81
  custom: {};
76
- constructor(services: StoreServices, variantData: VariantData);
82
+ constructor(variantData: VariantData);
77
83
  }
78
84
  declare class Child {
79
85
  type: string;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchResultStore.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/SearchResultStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SearchResultStore.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/SearchResultStore.ts"],"names":[],"mappings":"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"}
@@ -38,7 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  return (mod && mod.__esModule) ? mod : { "default": mod };
39
39
  };
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.VariantSelection = exports.Product = exports.Banner = exports.SearchResultStore = void 0;
41
+ exports.Variant = exports.VariantSelection = exports.Variants = exports.ProductMask = exports.Product = exports.Banner = exports.SearchResultStore = void 0;
42
42
  var mobx_1 = require("mobx");
43
43
  var deepmerge_1 = __importDefault(require("deepmerge"));
44
44
  var is_plain_object_1 = require("is-plain-object");
@@ -95,7 +95,6 @@ var Banner = /** @class */ (function () {
95
95
  exports.Banner = Banner;
96
96
  var Product = /** @class */ (function () {
97
97
  function Product(services, result, config) {
98
- var _this = this;
99
98
  var _a, _b, _c;
100
99
  this.type = 'product';
101
100
  this.attributes = {};
@@ -105,35 +104,16 @@ var Product = /** @class */ (function () {
105
104
  this.custom = {};
106
105
  this.children = [];
107
106
  this.quantity = 1;
108
- this.display = {
109
- mappings: {
110
- core: {},
111
- },
112
- attributes: {},
113
- options: {},
114
- };
115
- this.updateDisplay = function (display) {
116
- var defaultDisplay = {
117
- mappings: _this.mappings,
118
- attributes: _this.attributes,
119
- options: {},
120
- };
121
- var newDisplay = (0, deepmerge_1.default)(defaultDisplay, display || defaultDisplay, { isMergeableObject: is_plain_object_1.isPlainObject });
122
- if (JSON.stringify(_this.display) !== JSON.stringify(newDisplay)) {
123
- _this.display = newDisplay;
124
- }
125
- };
107
+ this.mask = new ProductMask();
126
108
  this.id = result.id;
127
109
  this.attributes = result.attributes;
128
110
  this.mappings = result.mappings;
129
- //initialize the display
130
- this.updateDisplay();
131
111
  var variantsField = (_b = (_a = config === null || config === void 0 ? void 0 : config.settings) === null || _a === void 0 ? void 0 : _a.variants) === null || _b === void 0 ? void 0 : _b.field;
132
112
  if (config && variantsField && this.attributes && this.attributes[variantsField]) {
133
113
  try {
134
114
  // parse the field (JSON)
135
115
  var parsedVariants = JSON.parse(this.attributes[variantsField]);
136
- this.variants = new Variants(config, services, parsedVariants, this.updateDisplay);
116
+ this.variants = new Variants(parsedVariants, this.mask);
137
117
  }
138
118
  catch (err) {
139
119
  // failed to parse the variant JSON
@@ -147,7 +127,7 @@ var Product = /** @class */ (function () {
147
127
  }
148
128
  (0, mobx_1.makeObservable)(this, {
149
129
  id: mobx_1.observable,
150
- display: mobx_1.observable,
130
+ display: mobx_1.computed,
151
131
  attributes: mobx_1.observable,
152
132
  custom: mobx_1.observable,
153
133
  quantity: mobx_1.observable,
@@ -159,11 +139,46 @@ var Product = /** @class */ (function () {
159
139
  }, {});
160
140
  (0, mobx_1.makeObservable)(this.mappings.core, coreObservables);
161
141
  }
142
+ Object.defineProperty(Product.prototype, "display", {
143
+ get: function () {
144
+ return (0, deepmerge_1.default)({ id: this.id, mappings: this.mappings, attributes: this.attributes }, this.mask.data, { isMergeableObject: is_plain_object_1.isPlainObject });
145
+ },
146
+ enumerable: false,
147
+ configurable: true
148
+ });
162
149
  return Product;
163
150
  }());
164
151
  exports.Product = Product;
152
+ // Mask is used to power the product display for quick attribute swapping
153
+ var ProductMask = /** @class */ (function () {
154
+ function ProductMask() {
155
+ this.data = {};
156
+ (0, mobx_1.makeObservable)(this, {
157
+ data: mobx_1.observable,
158
+ });
159
+ }
160
+ ProductMask.prototype.merge = function (mask) {
161
+ // TODO: look into making more performant
162
+ // needed to prevent infinite re-render on merge with same data
163
+ if (JSON.stringify((0, deepmerge_1.default)(this.data, mask)) != JSON.stringify(this.data)) {
164
+ this.data = (0, deepmerge_1.default)(this.data, mask);
165
+ }
166
+ };
167
+ ProductMask.prototype.set = function (mask) {
168
+ // TODO: look into making more performant
169
+ // needed to prevent infinite re-render on set with same data
170
+ if (JSON.stringify(mask) != JSON.stringify(this.data)) {
171
+ this.data = mask;
172
+ }
173
+ };
174
+ ProductMask.prototype.reset = function () {
175
+ this.data = {};
176
+ };
177
+ return ProductMask;
178
+ }());
179
+ exports.ProductMask = ProductMask;
165
180
  var Variants = /** @class */ (function () {
166
- function Variants(config, services, variantData, updateDisplay) {
181
+ function Variants(variantData, mask) {
167
182
  var _this = this;
168
183
  this.data = [];
169
184
  this.selections = [];
@@ -175,25 +190,24 @@ var Variants = /** @class */ (function () {
175
190
  options.push(variantOption);
176
191
  }
177
192
  });
178
- return new Variant(services, variant);
193
+ return new Variant(variant);
179
194
  });
180
- this.config = config;
181
- this.updateDisplay = updateDisplay;
182
195
  options.map(function (option) {
183
196
  // TODO - merge with variant config before constructing selection (for label overrides and swatch mappings)
184
197
  var optionConfig = {
185
198
  field: option,
186
199
  label: option,
187
200
  };
188
- _this.selections.push(new VariantSelection(config, services, _this, optionConfig, _this.data));
201
+ _this.selections.push(new VariantSelection(_this, optionConfig));
189
202
  });
203
+ // setting function in constructor to prevent exposing mask as class property
204
+ this.setActive = function (variant) {
205
+ _this.active = variant;
206
+ mask.set({ mappings: _this.active.mappings, attributes: _this.active.attributes });
207
+ };
190
208
  // select first available
191
209
  this.makeSelections();
192
210
  }
193
- Variants.prototype.setActive = function (variant) {
194
- this.active = variant;
195
- this.updateDisplay(this.active);
196
- };
197
211
  Variants.prototype.makeSelections = function (options) {
198
212
  // TODO - support for affinity to attempt to pre-selected options
199
213
  // options = {color: 'Blue', size: 'L'};
@@ -202,7 +216,7 @@ var Variants = /** @class */ (function () {
202
216
  this.selections.forEach(function (selection) {
203
217
  var firstAvailableOption = selection.values.find(function (value) { return value.available; });
204
218
  if (firstAvailableOption) {
205
- selection.select(firstAvailableOption.value);
219
+ selection.select(firstAvailableOption.value, true);
206
220
  }
207
221
  });
208
222
  }
@@ -218,7 +232,7 @@ var Variants = /** @class */ (function () {
218
232
  return -1;
219
233
  });
220
234
  // refine selections ensuring that the selection that triggered the update refines LAST
221
- orderedSelections.forEach(function (selection) { return selection.refineSelections(_this.data); });
235
+ orderedSelections.forEach(function (selection) { return selection.refineSelections(_this); });
222
236
  // check to see if we have enough selections made to update the display
223
237
  var selectedSelections = this.selections.filter(function (selection) { var _a; return (_a = selection.selected) === null || _a === void 0 ? void 0 : _a.length; });
224
238
  if (selectedSelections.length) {
@@ -239,27 +253,29 @@ var Variants = /** @class */ (function () {
239
253
  };
240
254
  return Variants;
241
255
  }());
256
+ exports.Variants = Variants;
242
257
  var VariantSelection = /** @class */ (function () {
243
- function VariantSelection(config, services, variants, selectorConfig, data) {
258
+ function VariantSelection(variants, selectorConfig) {
259
+ var _this = this;
244
260
  this.selected = ''; //ex: blue
245
261
  this.previouslySelected = '';
246
262
  this.values = [];
247
263
  this.field = selectorConfig.field;
248
264
  this.label = selectorConfig.label;
249
- // reference to parent variants
250
- this.variants = variants;
265
+ // needed to prevent attaching variants as class property
266
+ this.variantsUpdate = function () { return variants.update(_this); };
251
267
  // create possible values from the data and refine them
252
- this.refineSelections(data);
268
+ this.refineSelections(variants);
253
269
  (0, mobx_1.makeObservable)(this, {
254
270
  selected: mobx_1.observable,
255
271
  values: mobx_1.observable,
256
272
  });
257
273
  }
258
- VariantSelection.prototype.refineSelections = function (allVariants) {
274
+ VariantSelection.prototype.refineSelections = function (variants) {
259
275
  var _this = this;
260
276
  // current selection should only consider OTHER selections for availability
261
- var selectedSelections = this.variants.selections.filter(function (selection) { return selection.field != _this.field && selection.selected; });
262
- var availableVariants = allVariants;
277
+ var selectedSelections = variants.selections.filter(function (selection) { return selection.field != _this.field && selection.selected; });
278
+ var availableVariants = variants.data;
263
279
  var _loop_2 = function (selectedSelection) {
264
280
  availableVariants = availableVariants.filter(function (variant) { return selectedSelection.selected == variant.options[selectedSelection.field] && variant.available; });
265
281
  };
@@ -268,33 +284,35 @@ var VariantSelection = /** @class */ (function () {
268
284
  var selectedSelection = selectedSelections_2[_i];
269
285
  _loop_2(selectedSelection);
270
286
  }
271
- var newValues = allVariants
287
+ var newValues = variants.data
272
288
  .filter(function (variant) { return variant.options[_this.field]; })
273
289
  .reduce(function (values, variant) {
274
290
  var _a;
275
291
  if (!values.some(function (val) { return variant.options[_this.field] == val.value; })) {
276
292
  values.push({
277
293
  value: variant.options[_this.field],
278
- label: variant.options[_this.field], // TODO - use configurable mappings
279
- // TODO set background for swatches (via configurable mappings)
294
+ label: variant.options[_this.field],
295
+ // TODO: use configurable mappings from config
296
+ // TODO: set background for swatches (via configurable mappings) from config
280
297
  thumbnailImageUrl: (_a = variant.mappings.core) === null || _a === void 0 ? void 0 : _a.thumbnailImageUrl,
281
298
  available: Boolean(availableVariants.some(function (availableVariant) { return availableVariant.options[_this.field] == variant.options[_this.field]; })),
282
299
  });
283
300
  }
301
+ // TODO: use sorting function from config
284
302
  return values;
285
303
  }, []);
286
304
  // if selection has been made
287
305
  if (this.selected) {
288
- //is that selection still available?
306
+ // check if the selection is stil available
289
307
  if (!newValues.some(function (val) { return val.value == _this.selected && val.available; })) {
290
- // the previous selection is no longer available
291
- if (this.previouslySelected && newValues.some(function (val) { return val.value == _this.previouslySelected && val.available; })) {
292
- if (this.selected !== this.previouslySelected) {
293
- this.select(this.previouslySelected, true);
294
- }
308
+ // the selection is no longer available, attempt to select previous selection
309
+ if (this.selected !== this.previouslySelected &&
310
+ this.previouslySelected &&
311
+ newValues.some(function (val) { return val.value == _this.previouslySelected && val.available; })) {
312
+ this.select(this.previouslySelected, true);
295
313
  }
296
314
  else {
297
- //otherwise just choose the first available option
315
+ // choose the first available option if previous seletions are unavailable
298
316
  var availableValues = newValues.filter(function (val) { return val.available; });
299
317
  if (newValues.length && availableValues.length) {
300
318
  var nextAvailableValue = availableValues[0].value;
@@ -315,18 +333,18 @@ var VariantSelection = /** @class */ (function () {
315
333
  if (internalSelection === void 0) { internalSelection = false; }
316
334
  var valueExist = this.values.find(function (val) { return val.value == value; });
317
335
  if (valueExist) {
318
- this.selected = value;
319
336
  if (!internalSelection) {
320
- this.previouslySelected = value;
337
+ this.previouslySelected = this.selected;
321
338
  }
322
- this.variants.update(this);
339
+ this.selected = value;
340
+ this.variantsUpdate();
323
341
  }
324
342
  };
325
343
  return VariantSelection;
326
344
  }());
327
345
  exports.VariantSelection = VariantSelection;
328
346
  var Variant = /** @class */ (function () {
329
- function Variant(services, variantData) {
347
+ function Variant(variantData) {
330
348
  this.type = 'variant';
331
349
  this.attributes = {};
332
350
  this.options = {};
@@ -347,6 +365,7 @@ var Variant = /** @class */ (function () {
347
365
  }
348
366
  return Variant;
349
367
  }());
368
+ exports.Variant = Variant;
350
369
  var Child = /** @class */ (function () {
351
370
  function Child(services, result) {
352
371
  this.type = 'child';
@@ -2,7 +2,7 @@ export { SearchMerchandisingStore, BannerContent, ContentType } from './SearchMe
2
2
  export { SearchFacetStore, ValueFacet, RangeFacet, FacetValue, FacetHierarchyValue, FacetRangeValue } from './SearchFacetStore';
3
3
  export { SearchFilterStore, Filter } from './SearchFilterStore';
4
4
  export { SearchPaginationStore } from './SearchPaginationStore';
5
- export { SearchResultStore, Product, Banner, VariantSelection } from './SearchResultStore';
5
+ export { SearchResultStore, Product, Banner } from './SearchResultStore';
6
6
  export { SearchSortingStore } from './SearchSortingStore';
7
7
  export { SearchQueryStore } from './SearchQueryStore';
8
8
  export { SearchHistoryStore } from './SearchHistoryStore';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChI,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChI,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SearchHistoryStore = exports.SearchQueryStore = exports.SearchSortingStore = exports.VariantSelection = exports.Banner = exports.Product = exports.SearchResultStore = exports.SearchPaginationStore = exports.Filter = exports.SearchFilterStore = exports.FacetRangeValue = exports.FacetHierarchyValue = exports.FacetValue = exports.RangeFacet = exports.ValueFacet = exports.SearchFacetStore = exports.ContentType = exports.SearchMerchandisingStore = void 0;
3
+ exports.SearchHistoryStore = exports.SearchQueryStore = exports.SearchSortingStore = exports.Banner = exports.Product = exports.SearchResultStore = exports.SearchPaginationStore = exports.Filter = exports.SearchFilterStore = exports.FacetRangeValue = exports.FacetHierarchyValue = exports.FacetValue = exports.RangeFacet = exports.ValueFacet = exports.SearchFacetStore = exports.ContentType = exports.SearchMerchandisingStore = void 0;
4
4
  var SearchMerchandisingStore_1 = require("./SearchMerchandisingStore");
5
5
  Object.defineProperty(exports, "SearchMerchandisingStore", { enumerable: true, get: function () { return SearchMerchandisingStore_1.SearchMerchandisingStore; } });
6
6
  Object.defineProperty(exports, "ContentType", { enumerable: true, get: function () { return SearchMerchandisingStore_1.ContentType; } });
@@ -20,7 +20,6 @@ var SearchResultStore_1 = require("./SearchResultStore");
20
20
  Object.defineProperty(exports, "SearchResultStore", { enumerable: true, get: function () { return SearchResultStore_1.SearchResultStore; } });
21
21
  Object.defineProperty(exports, "Product", { enumerable: true, get: function () { return SearchResultStore_1.Product; } });
22
22
  Object.defineProperty(exports, "Banner", { enumerable: true, get: function () { return SearchResultStore_1.Banner; } });
23
- Object.defineProperty(exports, "VariantSelection", { enumerable: true, get: function () { return SearchResultStore_1.VariantSelection; } });
24
23
  var SearchSortingStore_1 = require("./SearchSortingStore");
25
24
  Object.defineProperty(exports, "SearchSortingStore", { enumerable: true, get: function () { return SearchSortingStore_1.SearchSortingStore; } });
26
25
  var SearchQueryStore_1 = require("./SearchQueryStore");
@@ -14,11 +14,16 @@ export declare class Banner {
14
14
  value: string;
15
15
  constructor(services: StoreServices, banner: SearchResponseModelMerchandisingContentInline);
16
16
  }
17
- type VariantData = {
17
+ export type VariantData = {
18
18
  mappings: SearchResponseModelResultMappings;
19
19
  attributes: Record<string, unknown>;
20
20
  options: Record<string, string>;
21
21
  };
22
+ type ProductMinimal = {
23
+ id: string;
24
+ attributes: Record<string, unknown>;
25
+ mappings: SearchResponseModelResultMappings;
26
+ };
22
27
  export declare class Product {
23
28
  type: string;
24
29
  id: string;
@@ -27,23 +32,24 @@ export declare class Product {
27
32
  custom: {};
28
33
  children?: Array<Child>;
29
34
  quantity: number;
30
- display: VariantData;
35
+ mask: ProductMask;
31
36
  variants?: Variants;
32
37
  constructor(services: StoreServices, result: SearchResponseModelResult, config?: StoreConfigs);
33
- updateDisplay: (display?: {
34
- mappings: SearchResponseModelResultMappings;
35
- attributes: Record<string, unknown>;
36
- options: Record<string, string>;
37
- }) => void;
38
+ get display(): ProductMinimal;
39
+ }
40
+ export declare class ProductMask {
41
+ data: Partial<Product>;
42
+ constructor();
43
+ merge(mask: Partial<Product>): void;
44
+ set(mask: Partial<Product>): void;
45
+ reset(): void;
38
46
  }
39
- declare class Variants {
47
+ export declare class Variants {
40
48
  active?: Variant;
41
49
  data: Variant[];
42
50
  selections: VariantSelection[];
43
- config: StoreConfigs;
44
- updateDisplay: (variant: VariantData) => void;
45
- constructor(config: StoreConfigs, services: StoreServices, variantData: VariantData[], updateDisplay: (variant: VariantData) => void);
46
- setActive(variant: Variant): void;
51
+ setActive: (variant: Variant) => void;
52
+ constructor(variantData: VariantData[], mask: ProductMask);
47
53
  makeSelections(options?: Record<string, string>): void;
48
54
  update(fromSelection: VariantSelection): void;
49
55
  }
@@ -60,20 +66,20 @@ export declare class VariantSelection {
60
66
  selected?: string;
61
67
  previouslySelected?: string;
62
68
  values: SelectionValue[];
63
- private variants;
64
- constructor(config: StoreConfigs, services: StoreServices, variants: Variants, selectorConfig: VariantSelectionOptions, data: Variant[]);
65
- refineSelections(allVariants: Variant[]): void;
69
+ private variantsUpdate;
70
+ constructor(variants: Variants, selectorConfig: VariantSelectionOptions);
71
+ refineSelections(variants: Variants): void;
66
72
  reset(): void;
67
73
  select(value: string, internalSelection?: boolean): void;
68
74
  }
69
- declare class Variant {
75
+ export declare class Variant {
70
76
  type: string;
71
77
  available: boolean;
72
78
  attributes: Record<string, unknown>;
73
79
  options: Record<string, string>;
74
80
  mappings: SearchResponseModelResultMappings;
75
81
  custom: {};
76
- constructor(services: StoreServices, variantData: VariantData);
82
+ constructor(variantData: VariantData);
77
83
  }
78
84
  declare class Child {
79
85
  type: string;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchResultStore.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/SearchResultStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SearchResultStore.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/SearchResultStore.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { makeObservable, observable } from 'mobx';
1
+ import { computed, makeObservable, observable } from 'mobx';
2
2
  import deepmerge from 'deepmerge';
3
3
  import { isPlainObject } from 'is-plain-object';
4
4
  export class SearchResultStore extends Array {
@@ -52,35 +52,16 @@ export class Product {
52
52
  this.custom = {};
53
53
  this.children = [];
54
54
  this.quantity = 1;
55
- this.display = {
56
- mappings: {
57
- core: {},
58
- },
59
- attributes: {},
60
- options: {},
61
- };
62
- this.updateDisplay = (display) => {
63
- const defaultDisplay = {
64
- mappings: this.mappings,
65
- attributes: this.attributes,
66
- options: {},
67
- };
68
- const newDisplay = deepmerge(defaultDisplay, display || defaultDisplay, { isMergeableObject: isPlainObject });
69
- if (JSON.stringify(this.display) !== JSON.stringify(newDisplay)) {
70
- this.display = newDisplay;
71
- }
72
- };
55
+ this.mask = new ProductMask();
73
56
  this.id = result.id;
74
57
  this.attributes = result.attributes;
75
58
  this.mappings = result.mappings;
76
- //initialize the display
77
- this.updateDisplay();
78
59
  const variantsField = config?.settings?.variants?.field;
79
60
  if (config && variantsField && this.attributes && this.attributes[variantsField]) {
80
61
  try {
81
62
  // parse the field (JSON)
82
63
  const parsedVariants = JSON.parse(this.attributes[variantsField]);
83
- this.variants = new Variants(config, services, parsedVariants, this.updateDisplay);
64
+ this.variants = new Variants(parsedVariants, this.mask);
84
65
  }
85
66
  catch (err) {
86
67
  // failed to parse the variant JSON
@@ -97,7 +78,7 @@ export class Product {
97
78
  }
98
79
  makeObservable(this, {
99
80
  id: observable,
100
- display: observable,
81
+ display: computed,
101
82
  attributes: observable,
102
83
  custom: observable,
103
84
  quantity: observable,
@@ -111,9 +92,38 @@ export class Product {
111
92
  }, {});
112
93
  makeObservable(this.mappings.core, coreObservables);
113
94
  }
95
+ get display() {
96
+ return deepmerge({ id: this.id, mappings: this.mappings, attributes: this.attributes }, this.mask.data, { isMergeableObject: isPlainObject });
97
+ }
98
+ }
99
+ // Mask is used to power the product display for quick attribute swapping
100
+ export class ProductMask {
101
+ constructor() {
102
+ this.data = {};
103
+ makeObservable(this, {
104
+ data: observable,
105
+ });
106
+ }
107
+ merge(mask) {
108
+ // TODO: look into making more performant
109
+ // needed to prevent infinite re-render on merge with same data
110
+ if (JSON.stringify(deepmerge(this.data, mask)) != JSON.stringify(this.data)) {
111
+ this.data = deepmerge(this.data, mask);
112
+ }
113
+ }
114
+ set(mask) {
115
+ // TODO: look into making more performant
116
+ // needed to prevent infinite re-render on set with same data
117
+ if (JSON.stringify(mask) != JSON.stringify(this.data)) {
118
+ this.data = mask;
119
+ }
120
+ }
121
+ reset() {
122
+ this.data = {};
123
+ }
114
124
  }
115
- class Variants {
116
- constructor(config, services, variantData, updateDisplay) {
125
+ export class Variants {
126
+ constructor(variantData, mask) {
117
127
  this.data = [];
118
128
  this.selections = [];
119
129
  const options = [];
@@ -124,25 +134,24 @@ class Variants {
124
134
  options.push(variantOption);
125
135
  }
126
136
  });
127
- return new Variant(services, variant);
137
+ return new Variant(variant);
128
138
  });
129
- this.config = config;
130
- this.updateDisplay = updateDisplay;
131
139
  options.map((option) => {
132
140
  // TODO - merge with variant config before constructing selection (for label overrides and swatch mappings)
133
141
  const optionConfig = {
134
142
  field: option,
135
143
  label: option,
136
144
  };
137
- this.selections.push(new VariantSelection(config, services, this, optionConfig, this.data));
145
+ this.selections.push(new VariantSelection(this, optionConfig));
138
146
  });
147
+ // setting function in constructor to prevent exposing mask as class property
148
+ this.setActive = (variant) => {
149
+ this.active = variant;
150
+ mask.set({ mappings: this.active.mappings, attributes: this.active.attributes });
151
+ };
139
152
  // select first available
140
153
  this.makeSelections();
141
154
  }
142
- setActive(variant) {
143
- this.active = variant;
144
- this.updateDisplay(this.active);
145
- }
146
155
  makeSelections(options) {
147
156
  // TODO - support for affinity to attempt to pre-selected options
148
157
  // options = {color: 'Blue', size: 'L'};
@@ -151,7 +160,7 @@ class Variants {
151
160
  this.selections.forEach((selection) => {
152
161
  const firstAvailableOption = selection.values.find((value) => value.available);
153
162
  if (firstAvailableOption) {
154
- selection.select(firstAvailableOption.value);
163
+ selection.select(firstAvailableOption.value, true);
155
164
  }
156
165
  });
157
166
  }
@@ -166,7 +175,7 @@ class Variants {
166
175
  return -1;
167
176
  });
168
177
  // refine selections ensuring that the selection that triggered the update refines LAST
169
- orderedSelections.forEach((selection) => selection.refineSelections(this.data));
178
+ orderedSelections.forEach((selection) => selection.refineSelections(this));
170
179
  // check to see if we have enough selections made to update the display
171
180
  const selectedSelections = this.selections.filter((selection) => selection.selected?.length);
172
181
  if (selectedSelections.length) {
@@ -183,55 +192,57 @@ class Variants {
183
192
  }
184
193
  }
185
194
  export class VariantSelection {
186
- constructor(config, services, variants, selectorConfig, data) {
195
+ constructor(variants, selectorConfig) {
187
196
  this.selected = ''; //ex: blue
188
197
  this.previouslySelected = '';
189
198
  this.values = [];
190
199
  this.field = selectorConfig.field;
191
200
  this.label = selectorConfig.label;
192
- // reference to parent variants
193
- this.variants = variants;
201
+ // needed to prevent attaching variants as class property
202
+ this.variantsUpdate = () => variants.update(this);
194
203
  // create possible values from the data and refine them
195
- this.refineSelections(data);
204
+ this.refineSelections(variants);
196
205
  makeObservable(this, {
197
206
  selected: observable,
198
207
  values: observable,
199
208
  });
200
209
  }
201
- refineSelections(allVariants) {
210
+ refineSelections(variants) {
202
211
  // current selection should only consider OTHER selections for availability
203
- const selectedSelections = this.variants.selections.filter((selection) => selection.field != this.field && selection.selected);
204
- let availableVariants = allVariants;
212
+ const selectedSelections = variants.selections.filter((selection) => selection.field != this.field && selection.selected);
213
+ let availableVariants = variants.data;
205
214
  // loop through selectedSelections and remove products that do not match
206
215
  for (const selectedSelection of selectedSelections) {
207
216
  availableVariants = availableVariants.filter((variant) => selectedSelection.selected == variant.options[selectedSelection.field] && variant.available);
208
217
  }
209
- const newValues = allVariants
218
+ const newValues = variants.data
210
219
  .filter((variant) => variant.options[this.field])
211
220
  .reduce((values, variant) => {
212
221
  if (!values.some((val) => variant.options[this.field] == val.value)) {
213
222
  values.push({
214
223
  value: variant.options[this.field],
215
- label: variant.options[this.field], // TODO - use configurable mappings
216
- // TODO set background for swatches (via configurable mappings)
224
+ label: variant.options[this.field],
225
+ // TODO: use configurable mappings from config
226
+ // TODO: set background for swatches (via configurable mappings) from config
217
227
  thumbnailImageUrl: variant.mappings.core?.thumbnailImageUrl,
218
228
  available: Boolean(availableVariants.some((availableVariant) => availableVariant.options[this.field] == variant.options[this.field])),
219
229
  });
220
230
  }
231
+ // TODO: use sorting function from config
221
232
  return values;
222
233
  }, []);
223
234
  // if selection has been made
224
235
  if (this.selected) {
225
- //is that selection still available?
236
+ // check if the selection is stil available
226
237
  if (!newValues.some((val) => val.value == this.selected && val.available)) {
227
- // the previous selection is no longer available
228
- if (this.previouslySelected && newValues.some((val) => val.value == this.previouslySelected && val.available)) {
229
- if (this.selected !== this.previouslySelected) {
230
- this.select(this.previouslySelected, true);
231
- }
238
+ // the selection is no longer available, attempt to select previous selection
239
+ if (this.selected !== this.previouslySelected &&
240
+ this.previouslySelected &&
241
+ newValues.some((val) => val.value == this.previouslySelected && val.available)) {
242
+ this.select(this.previouslySelected, true);
232
243
  }
233
244
  else {
234
- //otherwise just choose the first available option
245
+ // choose the first available option if previous seletions are unavailable
235
246
  const availableValues = newValues.filter((val) => val.available);
236
247
  if (newValues.length && availableValues.length) {
237
248
  const nextAvailableValue = availableValues[0].value;
@@ -251,16 +262,16 @@ export class VariantSelection {
251
262
  select(value, internalSelection = false) {
252
263
  const valueExist = this.values.find((val) => val.value == value);
253
264
  if (valueExist) {
254
- this.selected = value;
255
265
  if (!internalSelection) {
256
- this.previouslySelected = value;
266
+ this.previouslySelected = this.selected;
257
267
  }
258
- this.variants.update(this);
268
+ this.selected = value;
269
+ this.variantsUpdate();
259
270
  }
260
271
  }
261
272
  }
262
- class Variant {
263
- constructor(services, variantData) {
273
+ export class Variant {
274
+ constructor(variantData) {
264
275
  this.type = 'variant';
265
276
  this.attributes = {};
266
277
  this.options = {};
@@ -2,7 +2,7 @@ export { SearchMerchandisingStore, BannerContent, ContentType } from './SearchMe
2
2
  export { SearchFacetStore, ValueFacet, RangeFacet, FacetValue, FacetHierarchyValue, FacetRangeValue } from './SearchFacetStore';
3
3
  export { SearchFilterStore, Filter } from './SearchFilterStore';
4
4
  export { SearchPaginationStore } from './SearchPaginationStore';
5
- export { SearchResultStore, Product, Banner, VariantSelection } from './SearchResultStore';
5
+ export { SearchResultStore, Product, Banner } from './SearchResultStore';
6
6
  export { SearchSortingStore } from './SearchSortingStore';
7
7
  export { SearchQueryStore } from './SearchQueryStore';
8
8
  export { SearchHistoryStore } from './SearchHistoryStore';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChI,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChI,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -2,7 +2,7 @@ export { SearchMerchandisingStore, ContentType } from './SearchMerchandisingStor
2
2
  export { SearchFacetStore, ValueFacet, RangeFacet, FacetValue, FacetHierarchyValue, FacetRangeValue } from './SearchFacetStore';
3
3
  export { SearchFilterStore, Filter } from './SearchFilterStore';
4
4
  export { SearchPaginationStore } from './SearchPaginationStore';
5
- export { SearchResultStore, Product, Banner, VariantSelection } from './SearchResultStore';
5
+ export { SearchResultStore, Product, Banner } from './SearchResultStore';
6
6
  export { SearchSortingStore } from './SearchSortingStore';
7
7
  export { SearchQueryStore } from './SearchQueryStore';
8
8
  export { SearchHistoryStore } from './SearchHistoryStore';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searchspring/snap-store-mobx",
3
- "version": "0.52.1",
3
+ "version": "0.52.2",
4
4
  "description": "Snap MobX Store",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -20,16 +20,16 @@
20
20
  "test:watch": "jest --watch"
21
21
  },
22
22
  "dependencies": {
23
- "@searchspring/snap-toolbox": "^0.52.1",
23
+ "@searchspring/snap-toolbox": "^0.52.2",
24
24
  "mobx": "6.9.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@searchspring/snap-client": "^0.52.1",
28
- "@searchspring/snap-url-manager": "^0.52.1"
27
+ "@searchspring/snap-client": "^0.52.2",
28
+ "@searchspring/snap-url-manager": "^0.52.2"
29
29
  },
30
30
  "sideEffects": false,
31
31
  "files": [
32
32
  "dist/**/*"
33
33
  ],
34
- "gitHead": "c9651b79b78d8105b0f17234528ab6ba8eaa3cab"
34
+ "gitHead": "eb44b26b54bc6c3d1fdebb9ee4b26d526bc40329"
35
35
  }