@thefittingroom/shop-ui 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,75 +1,50 @@
1
- # The Fitting Room - Shop SDK
1
+ # The Fitting Room - Shop UI
2
+
3
+ Modal UI for The Fitting Room. Provides UI hooks to integrate into the parent UI.
2
4
 
3
5
  ## Installation
4
6
 
5
7
  ```bash
6
- LANGUAGE_URL=https://assets.dev.thefittingroom.xyz/shop-sdk/4200127/languages
7
- ASSETS_URL=https://assets.dev.thefittingroom.xyz/shop-sdk/assets
8
-
9
- # build everytime changes are detected
10
- npm run dev:rollup
11
- # run a live server on localhost:3030 and disable cors
12
- npx live-server --host=localhost --port=3030 --cors
8
+ npm i @thefittingroom/shop-ui
13
9
  ```
14
10
 
15
- The sdk gets transpiled from typescript a javascript ESM module located at `dist/esm/main(.min).js`
11
+ or
16
12
 
17
- You can develop locally and reference it in your html like this:
18
- `import {InitFittingRoom, comps, InitLocale} from "http://localhost:3030/dist/cjs/main.js"`
19
-
20
- ## Merges on main branch
13
+ ```bash
14
+ yarn @thefittingroom/shop-ui
15
+ ```
21
16
 
22
- When a pull request gets merged into main, a development build gets published to S3.
23
- You can access the development builds by using a commit sha on main like this:
17
+ ## Usage
24
18
 
25
- `import {InitFittingRoom, comps, InitLocale} from "https://assets.dev.thefittingroom.xyz/shop-sdk/<COMMIT_SHA>/main.js"`
19
+ ```typescript
20
+ import { initFittingRoom } from '@thefittingroom/shop-ui'
26
21
 
27
- ## Overriding library functions
22
+ // Your brandId: Number
23
+ const shopId: number = 9001
28
24
 
29
- The sdk works out of the box with modals and does not require any overriding.
30
- All methods on the `tfr` object are overridable.
31
- View the [FittingRoom](https://github.com/TheFittingRoom/shop-sdk/blob/96d59558bdbec6cc1e899cac297838a4810de5d4/src/types/index.ts#L63) interface to see all of the overridable function signatures.
32
- The main implementation can be found in `init.ts`
25
+ // UI Hooks
26
+ const hooks: TfrHooks = {
27
+ onLoading: () => {},
28
+ onLoadingComplete: () => {},
29
+ onAvatarReady: (frames: string[]) => {},
30
+ onError: () => {},
31
+ onLogin: () => {},
32
+ onLogout: () => {},
33
+ }
33
34
 
34
- ```javascript
35
- // use the language code in the get url (ex. ?lang=en)
36
- InitLocale()
35
+ // the div id to contain the modal elements
36
+ const modalDivId: string = 'tfr-modal'
37
37
 
38
- // define a modal div in the html to attach the fitting room to
39
- let tfr = InitFittingRoom(1, 'tfr-tryon-modal')
38
+ // initFittingRoom is an async function and must be awaited
39
+ const tfr = await initFittingRoom(shopId, modalDivId, hooks)
40
40
 
41
- // add an optional sign out button
42
- let signout = document.getElementById('signout')
43
- signout.addEventListener('click', () => {
44
- // pass an empty sku to the onSignout since its not being used in a modal
45
- // call the onSignout function wrapper to return a promise
46
- // wait for the promise
47
- // shows signed out modal by default
48
- tfr
49
- .onSignout('')()
50
- .then(() => {
51
- // do something after signing out of the fitting room
52
- })
53
- })
41
+ // on page nav to new product
42
+ tfr.setSku(sku)
54
43
 
55
- // call TryOn with a colorway_size_asset sku
56
- document.getElementById('tryon').addEventListener('click', (e) => {
57
- tfr.TryOn('5003-007-08')
58
- })
44
+ // close the modal
45
+ tfr.close()
59
46
  ```
60
47
 
61
- ## Localization
62
-
63
- You can call `SetLocale` to change the language of the sdk without using url searchParams.
64
-
65
- ```javascript
66
- SetLocale('en')
67
- .then(() => {
68
- // do something after setting the locale
69
- })
70
- .catch((err) => {
71
- // handle error
72
- })
73
- ```
48
+ Several low level methods are exposed via `tfr.shop`
74
49
 
75
- Warnings will be generated in the console for any missing locale definitions.
50
+ See [@thefittingroom/sdk](https://github.com/TheFittingRoom/shop-sdk/tree/main)
package/dist/esm/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * thefittingroom v0.0.1 (2023-07-18T18:27:14.496Z)
2
+ * thefittingroom v0.0.4 (2023-07-19T15:30:35.007Z)
3
3
  * Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
4
4
  */
5
5
  /*!
6
- * thefittingroom v0.0.3 (2023-07-18T18:14:19.719Z)
6
+ * thefittingroom v0.0.7 (2023-07-19T15:29:31.094Z)
7
7
  * Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
8
8
  */
9
9
  /**
@@ -16354,8 +16354,8 @@ const devKeys = {
16354
16354
  url: "https://tfr.dev.thefittingroom.xyz",
16355
16355
  },
16356
16356
  config: {
16357
- avatarTimeout: "120000",
16358
- vtoTimeout: "120000",
16357
+ avatarTimeout: Number("120000"),
16358
+ vtoTimeout: Number("120000"),
16359
16359
  },
16360
16360
  };
16361
16361
  const prodKeys = {
@@ -16371,8 +16371,8 @@ const prodKeys = {
16371
16371
  url: "https://tfr.p.thefittingroom.xyz",
16372
16372
  },
16373
16373
  config: {
16374
- avatarTimeout: "120000",
16375
- vtoTimeout: "120000",
16374
+ avatarTimeout: Number("120000"),
16375
+ vtoTimeout: Number("120000"),
16376
16376
  },
16377
16377
  };
16378
16378
 
@@ -22813,6 +22813,20 @@ class FirebaseUser {
22813
22813
  const userProfile = await Ol(Aa(this.firestore, 'users', this.id));
22814
22814
  return userProfile.data();
22815
22815
  }
22816
+ watchUserProfileForChanges(predicate, timeout) {
22817
+ let unsub;
22818
+ const q = sl(Ta(this.firestore, 'users'), rl(Eh(), '==', this.id));
22819
+ const cancel = setTimeout(() => unsub(), timeout);
22820
+ return new Promise((resolve) => {
22821
+ unsub = jl(q, (snapshot) => {
22822
+ if (!predicate(snapshot))
22823
+ return;
22824
+ clearTimeout(cancel);
22825
+ unsub();
22826
+ resolve(snapshot.docs[0].data());
22827
+ });
22828
+ });
22829
+ }
22816
22830
  async login(username, password) {
22817
22831
  if (this.auth.currentUser)
22818
22832
  await this.auth.signOut();
@@ -22833,9 +22847,15 @@ class FirebaseUser {
22833
22847
 
22834
22848
  class Firebase {
22835
22849
  constructor() {
22836
- this.promisefyOnSnapshot = (q) => {
22850
+ this.promisefyOnSnapshot = (q, unsubscribeWhenData) => {
22837
22851
  let unsub;
22838
- const promise = new Promise((resolve) => (unsub = jl(q, (snapshot) => resolve(snapshot))));
22852
+ const promise = new Promise((resolve) => {
22853
+ unsub = jl(q, (snapshot) => {
22854
+ resolve(snapshot);
22855
+ if (unsubscribeWhenData)
22856
+ unsub();
22857
+ });
22858
+ });
22839
22859
  return { promise, unsubscribe: () => unsub() };
22840
22860
  };
22841
22861
  const firebaseKeys = Config.getInstance().firebase;
@@ -22846,9 +22866,9 @@ class Firebase {
22846
22866
  onInit() {
22847
22867
  return this.user.onInit();
22848
22868
  }
22849
- query(collectionName, constraint) {
22869
+ query(collectionName, constraint, unsubscribeWhenData = true) {
22850
22870
  const q = sl(Ta(this.firestore, collectionName), constraint);
22851
- return this.promisefyOnSnapshot(q);
22871
+ return this.promisefyOnSnapshot(q, unsubscribeWhenData);
22852
22872
  }
22853
22873
  getDocs(collectionName, constraints) {
22854
22874
  const q = sl(Ta(this.firestore, collectionName), ...constraints);
@@ -22868,7 +22888,7 @@ const getFirebaseError = (e) => {
22868
22888
  const asyncTry = (promise) => promise.then((data) => [null, data]).catch((error) => [error]);
22869
22889
 
22870
22890
  class Fetcher {
22871
- static endpoint() {
22891
+ static get endpoint() {
22872
22892
  const api = Config.getInstance().api;
22873
22893
  return api.url;
22874
22894
  }
@@ -22998,10 +23018,15 @@ class TfrShop {
22998
23018
  const res = await Fetcher.Post(this.user, '/ios-app-link', { phone_number: sanitizedTel }, false);
22999
23019
  console.log(res);
23000
23020
  }
23001
- awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
23021
+ async awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
23022
+ var _a, _b, _c, _d;
23002
23023
  if (!this.isLoggedIn)
23003
23024
  throw new UserNotLoggedInError();
23004
- return this.getColorwaySizeAssetFrames(colorwaySizeAssetSKU);
23025
+ const predicate = (data) => { var _a, _b, _c; return Boolean((_c = (_b = (_a = data.docs[0].data()) === null || _a === void 0 ? void 0 : _a.vto) === null || _b === void 0 ? void 0 : _b[this.brandId]) === null || _c === void 0 ? void 0 : _c[colorwaySizeAssetSKU]); };
23026
+ const userProfile = (await this.user.watchUserProfileForChanges(predicate, TfrShop.vtoTimeout));
23027
+ if (!((_d = (_c = (_b = (_a = userProfile === null || userProfile === void 0 ? void 0 : userProfile.vto) === null || _a === void 0 ? void 0 : _a[this.brandId]) === null || _b === void 0 ? void 0 : _b[colorwaySizeAssetSKU]) === null || _c === void 0 ? void 0 : _c.frames) === null || _d === void 0 ? void 0 : _d.length))
23028
+ throw new NoFramesFoundError();
23029
+ return userProfile.vto[this.brandId][colorwaySizeAssetSKU].frames;
23005
23030
  }
23006
23031
  async requestThenGetColorwaySizeAssetFrames(colorwaySizeAssetSku) {
23007
23032
  var _a, _b;
@@ -23070,6 +23095,8 @@ class TfrShop {
23070
23095
  return frames;
23071
23096
  }
23072
23097
  }
23098
+ TfrShop.avatarTimeout = 120000;
23099
+ TfrShop.vtoTimeout = 120000;
23073
23100
  const initShop = (brandId, env = 'dev') => {
23074
23101
  if (env === 'dev' || env === 'development')
23075
23102
  console.warn('TfrShop is in development mode');
@@ -36151,7 +36178,7 @@ class FittingRoom {
36151
36178
  this.shopId = shopId;
36152
36179
  this.hooks = hooks;
36153
36180
  this.nav = new FittingRoomNav(modalDivId, this.signIn.bind(this), this.forgotPassword.bind(this), this.submitTel.bind(this));
36154
- this.tfrShop = initShop(Number(this.shopId), "dev");
36181
+ this.tfrShop = initShop(Number(this.shopId), "prod");
36155
36182
  }
36156
36183
  get sku() {
36157
36184
  return this.nav.sku;
@@ -36195,7 +36222,8 @@ class FittingRoom {
36195
36222
  this.nav.onNotCreated();
36196
36223
  break;
36197
36224
  case AvatarState.PENDING:
36198
- this.nav.onLoading();
36225
+ if (this.hooks.onLoading)
36226
+ this.hooks.onLoading();
36199
36227
  break;
36200
36228
  case AvatarState.CREATED:
36201
36229
  console.debug('avatar_state: created');
@@ -36231,7 +36259,6 @@ class FittingRoom {
36231
36259
  try {
36232
36260
  if (this.hooks.onLoading)
36233
36261
  this.hooks.onLoading();
36234
- this.nav.onLoading();
36235
36262
  const frames = await this.tfrShop.tryOn(this.sku);
36236
36263
  this.nav.close();
36237
36264
  if (this.hooks.onAvatarReady)
@@ -36252,7 +36279,11 @@ class FittingRoom {
36252
36279
  }
36253
36280
  }
36254
36281
 
36255
- const initFittingRoom = (shopId, modalDivId, hooks) => new FittingRoom(shopId, modalDivId, hooks);
36282
+ const initFittingRoom = async (shopId, modalDivId, hooks) => {
36283
+ const tfr = new FittingRoom(shopId, modalDivId, hooks);
36284
+ await tfr.onInit();
36285
+ return tfr;
36286
+ };
36256
36287
 
36257
36288
  export { VTO_TIMEOUT_MS, initFittingRoom };
36258
36289
  //# sourceMappingURL=index.js.map