@memori.ai/memori-react 8.41.0 → 8.41.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/Avatar/Avatar.js +5 -10
  3. package/dist/components/Avatar/Avatar.js.map +1 -1
  4. package/dist/components/MemoriWidget/MemoriWidget.js +123 -26
  5. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  6. package/dist/components/layouts/website-assistant.css +2 -1
  7. package/dist/helpers/nats/isSessionExpiredError.d.ts +3 -0
  8. package/dist/helpers/nats/isSessionExpiredError.js +37 -0
  9. package/dist/helpers/nats/isSessionExpiredError.js.map +1 -0
  10. package/dist/locales/de.json +1 -0
  11. package/dist/locales/en.json +1 -0
  12. package/dist/locales/es.json +1 -0
  13. package/dist/locales/fr.json +1 -0
  14. package/dist/locales/it.json +1 -0
  15. package/dist/types/integration.d.ts +3 -0
  16. package/dist/types/integration.js +16 -0
  17. package/dist/types/integration.js.map +1 -0
  18. package/dist/version.d.ts +1 -1
  19. package/dist/version.js +1 -1
  20. package/esm/components/Avatar/Avatar.js +5 -10
  21. package/esm/components/Avatar/Avatar.js.map +1 -1
  22. package/esm/components/MemoriWidget/MemoriWidget.js +123 -26
  23. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  24. package/esm/components/layouts/website-assistant.css +2 -1
  25. package/esm/helpers/nats/isSessionExpiredError.d.ts +3 -0
  26. package/esm/helpers/nats/isSessionExpiredError.js +32 -0
  27. package/esm/helpers/nats/isSessionExpiredError.js.map +1 -0
  28. package/esm/locales/de.json +1 -0
  29. package/esm/locales/en.json +1 -0
  30. package/esm/locales/es.json +1 -0
  31. package/esm/locales/fr.json +1 -0
  32. package/esm/locales/it.json +1 -0
  33. package/esm/types/integration.d.ts +3 -0
  34. package/esm/types/integration.js +11 -0
  35. package/esm/types/integration.js.map +1 -0
  36. package/esm/version.d.ts +1 -1
  37. package/esm/version.js +1 -1
  38. package/package.json +1 -1
  39. package/src/components/Avatar/Avatar.stories.tsx +45 -28
  40. package/src/components/Avatar/Avatar.test.tsx +27 -0
  41. package/src/components/Avatar/Avatar.tsx +8 -12
  42. package/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap +63 -0
  43. package/src/components/MemoriWidget/MemoriWidget.tsx +195 -46
  44. package/src/components/layouts/website-assistant.css +2 -1
  45. package/src/helpers/nats/isSessionExpiredError.test.ts +38 -0
  46. package/src/helpers/nats/isSessionExpiredError.ts +51 -0
  47. package/src/index.stories.tsx +16 -0
  48. package/src/locales/de.json +1 -0
  49. package/src/locales/en.json +1 -0
  50. package/src/locales/es.json +1 -0
  51. package/src/locales/fr.json +1 -0
  52. package/src/locales/it.json +1 -0
  53. package/src/types/integration.test.ts +32 -0
  54. package/src/types/integration.ts +31 -0
  55. package/src/version.ts +1 -1
@@ -0,0 +1,3 @@
1
+ import type { NatsDialogResponseEvent, NatsErrorEvent } from './useNatsSession';
2
+ export declare function isSessionExpiredNatsError(event: NatsErrorEvent): boolean;
3
+ export declare function isSessionExpiredNatsResponse(event: NatsDialogResponseEvent): boolean;
@@ -0,0 +1,32 @@
1
+ const SESSION_NOT_FOUND = -101;
2
+ const SESSION_EXPIRED = -103;
3
+ const SESSION_NOT_FOUND_MESSAGE = /session\s+with\s+id\s+["']?[^"']+["']?\s+not\s+found/i;
4
+ function isExpiredResultCode(resultCode) {
5
+ return (resultCode === 404 ||
6
+ resultCode === SESSION_EXPIRED ||
7
+ resultCode === SESSION_NOT_FOUND);
8
+ }
9
+ function isExpiredErrorMessage(message) {
10
+ if (!message)
11
+ return false;
12
+ return SESSION_NOT_FOUND_MESSAGE.test(message);
13
+ }
14
+ export function isSessionExpiredNatsError(event) {
15
+ if (isExpiredResultCode(event.errorCode)) {
16
+ return true;
17
+ }
18
+ if (typeof event.errorCode === 'string') {
19
+ const code = event.errorCode.toUpperCase();
20
+ if (code.includes('SESSION_EXPIRED') || code.includes('SESSION_NOT_FOUND')) {
21
+ return true;
22
+ }
23
+ }
24
+ return isExpiredErrorMessage(event.errorMessage);
25
+ }
26
+ export function isSessionExpiredNatsResponse(event) {
27
+ if (isExpiredResultCode(event.resultCode)) {
28
+ return true;
29
+ }
30
+ return isExpiredErrorMessage(event.resultMessage);
31
+ }
32
+ //# sourceMappingURL=isSessionExpiredError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isSessionExpiredError.js","sourceRoot":"","sources":["../../../src/helpers/nats/isSessionExpiredError.ts"],"names":[],"mappings":"AAMA,MAAM,iBAAiB,GAAG,CAAC,GAAG,CAAC;AAC/B,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC;AAE7B,MAAM,yBAAyB,GAC7B,uDAAuD,CAAC;AAE1D,SAAS,mBAAmB,CAAC,UAAmB;IAC9C,OAAO,CACL,UAAU,KAAK,GAAG;QAClB,UAAU,KAAK,eAAe;QAC9B,UAAU,KAAK,iBAAiB,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgB;IAC7C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAGD,MAAM,UAAU,yBAAyB,CAAC,KAAqB;IAC7D,IAAI,mBAAmB,CAAC,KAAK,CAAC,SAA+B,CAAC,EAAE;QAC9D,OAAO,IAAI,CAAC;KACb;IAED,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE;QACvC,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YAC1E,OAAO,IAAI,CAAC;SACb;KACF;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAGD,MAAM,UAAU,4BAA4B,CAC1C,KAA8B;IAE9B,IAAI,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;QACzC,OAAO,IAAI,CAAC;KACb;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;AACpD,CAAC"}
@@ -75,6 +75,7 @@
75
75
  "errorFetchingSession": "Fehler beim Laden der Sitzung",
76
76
  "errorGettingReferralURL": "Fehler beim Laden des Referrals",
77
77
  "errorReopeningSession": "Fehler beim erneuten Öffnen der Sitzung",
78
+ "sessionExpiredReopening": "Sitzung abgelaufen, Sitzung wird neu geöffnet",
78
79
  "ageVerification": "Altersüberprüfung",
79
80
  "ageVerificationText": "Um mit diesem Zwilling interagieren zu können, müssen Sie mindestens sein {{minAge}} Jahre alt.",
80
81
  "nsfw": "NSFW: Dieser Agent enthält Inhalte für Erwachsene",
@@ -77,6 +77,7 @@
77
77
  "errorFetchingSession": "Error during session loading",
78
78
  "errorGettingReferralURL": "Error during referral loading",
79
79
  "errorReopeningSession": "Error during session reopening",
80
+ "sessionExpiredReopening": "Session expired, reopening session",
80
81
  "ageVerification": "Age verification",
81
82
  "ageVerificationText": "To interact with this agent, you must be at least {{minAge}} years old.",
82
83
  "nsfw": "NSFW: This agent contains adult contents",
@@ -75,6 +75,7 @@
75
75
  "errorFetchingSession": "Error durante el cargamento de la sesión",
76
76
  "errorGettingReferralURL": "Error durante el cargamento del référent",
77
77
  "errorReopeningSession": "Error durante el re-abrir la sesión",
78
+ "sessionExpiredReopening": "Sesión expirada, reabriendo sesión",
78
79
  "ageVerification": "Verificación de edad",
79
80
  "ageVerificationText": "Para interactuar con este Gemelo, debes tener al menos {{minAge}} años.",
80
81
  "nsfw": "NSFW: Este gemelo contiene contenido para adultos",
@@ -74,6 +74,7 @@
74
74
  "errorFetchingSession": "Erreur lors du chargement de la session",
75
75
  "errorGettingReferralURL": "Erreur lors du chargement du référent",
76
76
  "errorReopeningSession": "Erreur lors de la re-ouverture de la session",
77
+ "sessionExpiredReopening": "Session expirée, réouverture en cours",
77
78
  "ageVerification": "Vérification de l'âge",
78
79
  "ageVerificationText": "Pour interagir avec ce Agent, vous devez être au minimum {{minAge}} ans.",
79
80
  "nsfw": "NSFW : Ce jumeau contient du contenu pour adultes",
@@ -78,6 +78,7 @@
78
78
  "errorFetchingSession": "Errore durante il caricamento della sessione",
79
79
  "errorGettingReferralURL": "Errore durante il caricamento del riferimento",
80
80
  "errorReopeningSession": "Errore durante il riapertura della sessione",
81
+ "sessionExpiredReopening": "Sessione scaduta, riapertura in corso",
81
82
  "ageVerification": "Verifica dell'età",
82
83
  "ageVerificationText": "Per interagire con questo agente, devi aver almeno {{minAge}} anni.",
83
84
  "nsfw": "NSFW: Questo agente contiene contenuti per adulti",
@@ -0,0 +1,3 @@
1
+ export type AvatarMode = 'readyplayerme' | 'readyplayerme-full' | 'customglb' | 'customrpm' | 'userAvatar' | 'avatar-configurator';
2
+ export declare const is3dAvatarWithUrl: (avatar: AvatarMode | string | undefined, avatarURL: string | undefined) => boolean;
3
+ export declare const usesRpmAvatarView: (avatar: AvatarMode | string | undefined) => boolean;
@@ -0,0 +1,11 @@
1
+ export const is3dAvatarWithUrl = (avatar, avatarURL) => !!avatarURL &&
2
+ (avatar === 'readyplayerme' ||
3
+ avatar === 'readyplayerme-full' ||
4
+ avatar === 'customglb' ||
5
+ avatar === 'customrpm' ||
6
+ avatar === 'avatar-configurator');
7
+ export const usesRpmAvatarView = (avatar) => avatar === 'readyplayerme' ||
8
+ avatar === 'readyplayerme-full' ||
9
+ avatar === 'customrpm' ||
10
+ avatar === 'avatar-configurator';
11
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../../src/types/integration.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAAuC,EACvC,SAA6B,EACpB,EAAE,CACX,CAAC,CAAC,SAAS;IACX,CAAC,MAAM,KAAK,eAAe;QACzB,MAAM,KAAK,oBAAoB;QAC/B,MAAM,KAAK,WAAW;QACtB,MAAM,KAAK,WAAW;QACtB,MAAM,KAAK,qBAAqB,CAAC,CAAC;AAGtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAAuC,EAC9B,EAAE,CACX,MAAM,KAAK,eAAe;IAC1B,MAAM,KAAK,oBAAoB;IAC/B,MAAM,KAAK,WAAW;IACtB,MAAM,KAAK,qBAAqB,CAAC"}
package/esm/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "8.41.0";
1
+ export declare const version = "8.41.2";
package/esm/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '8.41.0';
1
+ export const version = '8.41.2';
2
2
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "8.41.0",
2
+ "version": "8.41.2",
3
3
  "name": "@memori.ai/memori-react",
4
4
  "author": "Memori Srl",
5
5
  "main": "dist/index.js",
@@ -6,6 +6,7 @@ import Avatar, { Props } from './Avatar';
6
6
 
7
7
  import './Avatar.css';
8
8
  import { ArtifactProvider } from '../MemoriArtifactSystem/context/ArtifactContext';
9
+ import { VisemeProvider } from '../../context/visemeContext';
9
10
 
10
11
  const meta: Meta = {
11
12
  title: 'Widget/Avatar',
@@ -33,34 +34,38 @@ const Template: Story<Props> = args => {
33
34
 
34
35
  return (
35
36
  <I18nWrapper>
36
- <ArtifactProvider>
37
- <div
38
- style={
39
- args.integrationConfig?.avatar === 'customglb' ||
40
- args.integrationConfig?.avatar === 'readyplayerme' ||
41
- args.integrationConfig?.avatar === 'readyplayerme-full'
42
- ? {}
43
- : { marginTop: '20vw' }
44
- }
45
- >
46
- <Avatar
47
- {...args}
48
- integrationConfig={
49
- args.integrationConfig
50
- ? {
51
- ...args.integrationConfig,
52
- avatarURL:
53
- args.integrationConfig.avatarURL?.split('#')?.[0] +
54
- `#${new Date(Date.now()).toISOString()}`,
55
- }
56
- : undefined
57
- }
58
- avatar3dVisible={avatar3dVisible}
59
- setAvatar3dVisible={setAvatar3dVisible}
60
- key={Date.now()}
61
- />
62
- </div>
63
- </ArtifactProvider>
37
+ <VisemeProvider>
38
+ {' '}
39
+ <ArtifactProvider>
40
+ <div
41
+ style={
42
+ args.integrationConfig?.avatar === 'customglb' ||
43
+ args.integrationConfig?.avatar === 'readyplayerme' ||
44
+ args.integrationConfig?.avatar === 'readyplayerme-full' ||
45
+ args.integrationConfig?.avatar === 'avatar-configurator'
46
+ ? {}
47
+ : { marginTop: '20vw' }
48
+ }
49
+ >
50
+ <Avatar
51
+ {...args}
52
+ integrationConfig={
53
+ args.integrationConfig
54
+ ? {
55
+ ...args.integrationConfig,
56
+ avatarURL:
57
+ args.integrationConfig.avatarURL?.split('#')?.[0] +
58
+ `#${new Date(Date.now()).toISOString()}`,
59
+ }
60
+ : undefined
61
+ }
62
+ avatar3dVisible={avatar3dVisible}
63
+ setAvatar3dVisible={setAvatar3dVisible}
64
+ key={Date.now()}
65
+ />
66
+ </div>
67
+ </ArtifactProvider>
68
+ </VisemeProvider>
64
69
  </I18nWrapper>
65
70
  );
66
71
  };
@@ -141,3 +146,15 @@ FullbodyReadyPlayerMeAvatar.args = {
141
146
  'https://models.readyplayer.me/63b55751f17e295642bf07a2.glb#1669136149862',
142
147
  },
143
148
  };
149
+
150
+ export const AvatarConfigurator = Template.bind({});
151
+ AvatarConfigurator.args = {
152
+ ...FullbodyReadyPlayerMeAvatar.args,
153
+ integrationConfig: {
154
+ ...integrationConfig,
155
+ avatar: 'avatar-configurator',
156
+ avatarURL:
157
+ 'https://models.readyplayer.me/63b55751f17e295642bf07a2.glb#1669136149862',
158
+ },
159
+ avatarType: 'avatar3d',
160
+ };
@@ -102,3 +102,30 @@ it('renders Avatar with rpm 3d avatar unchanged', () => {
102
102
  );
103
103
  expect(container).toMatchSnapshot();
104
104
  });
105
+
106
+ it('renders Avatar with avatar-configurator like readyplayerme-full', () => {
107
+ const { container } = render(
108
+ <VisemeProvider>
109
+ <Avatar
110
+ memori={memori}
111
+ integration={integration}
112
+ isTotem={false}
113
+ setEnablePositionControls={() => {}}
114
+ integrationConfig={{
115
+ ...integrationConfig,
116
+ avatar: 'avatar-configurator',
117
+ avatarURL:
118
+ 'https://assets.memori.ai/api/v2/asset/b791f77c-1a94-4272-829e-eca82fcc62b7.glb',
119
+ }}
120
+ tenant={tenant}
121
+ instruct={false}
122
+ avatar3dVisible={true}
123
+ setAvatar3dVisible={() => {}}
124
+ hasUserActivatedSpeak={false}
125
+ isPlayingAudio={false}
126
+ avatarType="avatar3d"
127
+ />
128
+ </VisemeProvider>
129
+ );
130
+ expect(container).toMatchSnapshot();
131
+ });
@@ -17,6 +17,7 @@ import Edit from '../icons/Edit';
17
17
  import cx from 'classnames';
18
18
  import ContainerAvatarView from './AvatarView';
19
19
  import { useViseme } from '../../context/visemeContext';
20
+ import { is3dAvatarWithUrl, usesRpmAvatarView } from '../../types/integration';
20
21
 
21
22
  export interface Props {
22
23
  memori: Memori;
@@ -90,11 +91,10 @@ const Avatar: React.FC<Props> = ({
90
91
 
91
92
  const renderAvatar = () => {
92
93
  if (
93
- (integrationConfig?.avatar === 'readyplayerme' ||
94
- integrationConfig?.avatar === 'readyplayerme-full' ||
95
- integrationConfig?.avatar === 'customglb' ||
96
- integrationConfig?.avatar === 'customrpm') &&
97
- integrationConfig?.avatarURL &&
94
+ is3dAvatarWithUrl(
95
+ integrationConfig?.avatar,
96
+ integrationConfig?.avatarURL
97
+ ) &&
98
98
  avatarType &&
99
99
  avatarType !== 'blob'
100
100
  ) {
@@ -123,12 +123,8 @@ const Avatar: React.FC<Props> = ({
123
123
  };
124
124
 
125
125
  const renderAvatarContent = () => {
126
- if (!isClient) return null;
127
- if (
128
- integrationConfig?.avatar === 'readyplayerme' ||
129
- integrationConfig?.avatar === 'readyplayerme-full' ||
130
- integrationConfig?.avatar === 'customrpm'
131
- ) {
126
+ if (!isClient || !integrationConfig) return null;
127
+ if (usesRpmAvatarView(integrationConfig.avatar)) {
132
128
  return (
133
129
  <ErrorBoundary
134
130
  fallback={
@@ -163,7 +159,7 @@ const Avatar: React.FC<Props> = ({
163
159
  );
164
160
  }
165
161
 
166
- if (integrationConfig?.avatar === 'customglb') {
162
+ if (integrationConfig.avatar === 'customglb') {
167
163
  return (
168
164
  <ModelViewer
169
165
  poster={getAvatarUrl() || ''}
@@ -1,5 +1,68 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`renders Avatar with avatar-configurator like readyplayerme-full 1`] = `
4
+ <div>
5
+ <div
6
+ class="memori--avatar-wrapper memori--avatar-avatar-configurator"
7
+ >
8
+ <div
9
+ class="memori--blob-container"
10
+ >
11
+ <div
12
+ class="memori-blob"
13
+ >
14
+ <div
15
+ class="mainDiv"
16
+ />
17
+ <div
18
+ class="mainDiv"
19
+ />
20
+ <div
21
+ class="mainDiv"
22
+ />
23
+ <div
24
+ class="mainDiv"
25
+ />
26
+ <div
27
+ class="mainDiv"
28
+ />
29
+ </div>
30
+ </div>
31
+ </div>
32
+ <div
33
+ class="memori--avatar-toggle"
34
+ >
35
+ <button
36
+ class="memori-button memori-button--ghost memori-button--rounded memori-button--padded memori-button--with-icon"
37
+ >
38
+ <span
39
+ class="memori-button--icon"
40
+ >
41
+ <svg
42
+ aria-hidden="true"
43
+ focusable="false"
44
+ role="img"
45
+ viewBox="0 0 1024 1024"
46
+ xmlns="http://www.w3.org/2000/svg"
47
+ >
48
+ <path
49
+ d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"
50
+ />
51
+ <path
52
+ d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"
53
+ />
54
+ </svg>
55
+ </span>
56
+ <span
57
+ class="memori--avatar-toggle-text"
58
+ >
59
+ hide
60
+ </span>
61
+ </button>
62
+ </div>
63
+ </div>
64
+ `;
65
+
3
66
  exports[`renders Avatar with blob and avatar in blob unchanged 1`] = `
4
67
  <div>
5
68
  <div