@liforma/client 0.4.8 → 0.4.10

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 (101) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/next/index.js +516 -185
  3. package/dist/next/index.js.map +1 -1
  4. package/dist/next/next/createLiformaSessionRouteHandler.d.ts +4 -0
  5. package/dist/next/next/createLiformaSessionRouteHandler.d.ts.map +1 -1
  6. package/dist/next/v2/api/mintPublicSession.d.ts +1 -0
  7. package/dist/next/v2/api/mintPublicSession.d.ts.map +1 -1
  8. package/dist/next/v2/api/sessionEndpointRequest.d.ts +4 -0
  9. package/dist/next/v2/api/sessionEndpointRequest.d.ts.map +1 -1
  10. package/dist/next/v2/embed/iframeHost.d.ts +13 -1
  11. package/dist/next/v2/embed/iframeHost.d.ts.map +1 -1
  12. package/dist/next/v2/embed/protocol.d.ts +35 -1
  13. package/dist/next/v2/embed/protocol.d.ts.map +1 -1
  14. package/dist/next/v2/experience.d.ts +17 -2
  15. package/dist/next/v2/experience.d.ts.map +1 -1
  16. package/dist/next/v2/experienceEvents.d.ts +3 -1
  17. package/dist/next/v2/experienceEvents.d.ts.map +1 -1
  18. package/dist/next/v2/sdkRelease.d.ts +3 -0
  19. package/dist/next/v2/sdkRelease.d.ts.map +1 -0
  20. package/dist/next/v2/types/sessionInteraction.d.ts +29 -0
  21. package/dist/next/v2/types/sessionInteraction.d.ts.map +1 -1
  22. package/dist/next/v2/types/sessionManifest.d.ts +1 -0
  23. package/dist/next/v2/types/sessionManifest.d.ts.map +1 -1
  24. package/dist/next/widget/mountExperienceWidget.d.ts.map +1 -1
  25. package/dist/next/widget/types.d.ts +5 -0
  26. package/dist/next/widget/types.d.ts.map +1 -1
  27. package/dist/npm/index.js +542 -225
  28. package/dist/npm/index.js.map +1 -1
  29. package/dist/npm/svelte/experienceLoadError.d.ts.map +1 -1
  30. package/dist/npm/svelte/experienceLoadErrorStyles.d.ts +1 -1
  31. package/dist/npm/svelte/experienceLoadErrorStyles.d.ts.map +1 -1
  32. package/dist/npm/v2/api/mintPublicSession.d.ts +1 -0
  33. package/dist/npm/v2/api/mintPublicSession.d.ts.map +1 -1
  34. package/dist/npm/v2/api/sessionEndpointRequest.d.ts +4 -0
  35. package/dist/npm/v2/api/sessionEndpointRequest.d.ts.map +1 -1
  36. package/dist/npm/v2/embed/iframeHost.d.ts +13 -1
  37. package/dist/npm/v2/embed/iframeHost.d.ts.map +1 -1
  38. package/dist/npm/v2/embed/protocol.d.ts +35 -1
  39. package/dist/npm/v2/embed/protocol.d.ts.map +1 -1
  40. package/dist/npm/v2/experience.d.ts +17 -2
  41. package/dist/npm/v2/experience.d.ts.map +1 -1
  42. package/dist/npm/v2/experienceEvents.d.ts +3 -1
  43. package/dist/npm/v2/experienceEvents.d.ts.map +1 -1
  44. package/dist/npm/v2/index.d.ts +1 -1
  45. package/dist/npm/v2/index.d.ts.map +1 -1
  46. package/dist/npm/v2/liforma-experience.d.ts +2 -0
  47. package/dist/npm/v2/liforma-experience.d.ts.map +1 -1
  48. package/dist/npm/v2/npm.d.ts +1 -1
  49. package/dist/npm/v2/npm.d.ts.map +1 -1
  50. package/dist/npm/v2/sdkRelease.d.ts +3 -0
  51. package/dist/npm/v2/sdkRelease.d.ts.map +1 -0
  52. package/dist/npm/v2/types/sessionInteraction.d.ts +29 -0
  53. package/dist/npm/v2/types/sessionInteraction.d.ts.map +1 -1
  54. package/dist/npm/v2/types/sessionManifest.d.ts +1 -0
  55. package/dist/npm/v2/types/sessionManifest.d.ts.map +1 -1
  56. package/dist/npm/v2/types/sessionManifestSchema.d.ts +17 -0
  57. package/dist/npm/v2/types/sessionManifestSchema.d.ts.map +1 -1
  58. package/dist/npm/widget/mountExperienceWidget.d.ts.map +1 -1
  59. package/dist/npm/widget/types.d.ts +5 -0
  60. package/dist/npm/widget/types.d.ts.map +1 -1
  61. package/dist/react/component/experienceComponentLaunch.d.ts.map +1 -1
  62. package/dist/react/component/experienceComponentRuntime.d.ts +1 -0
  63. package/dist/react/component/experienceComponentRuntime.d.ts.map +1 -1
  64. package/dist/react/component/experienceComponentTypes.d.ts +7 -0
  65. package/dist/react/component/experienceComponentTypes.d.ts.map +1 -1
  66. package/dist/react/index.js +977 -642
  67. package/dist/react/index.js.map +1 -1
  68. package/dist/react/react/Experience.d.ts.map +1 -1
  69. package/dist/react/svelte/experienceLoadError.d.ts.map +1 -1
  70. package/dist/react/svelte/experienceLoadErrorStyles.d.ts +1 -1
  71. package/dist/react/svelte/experienceLoadErrorStyles.d.ts.map +1 -1
  72. package/dist/react/v2/api/mintPublicSession.d.ts +1 -0
  73. package/dist/react/v2/api/mintPublicSession.d.ts.map +1 -1
  74. package/dist/react/v2/api/sessionEndpointRequest.d.ts +4 -0
  75. package/dist/react/v2/api/sessionEndpointRequest.d.ts.map +1 -1
  76. package/dist/react/v2/embed/iframeHost.d.ts +13 -1
  77. package/dist/react/v2/embed/iframeHost.d.ts.map +1 -1
  78. package/dist/react/v2/embed/protocol.d.ts +35 -1
  79. package/dist/react/v2/embed/protocol.d.ts.map +1 -1
  80. package/dist/react/v2/experience.d.ts +17 -2
  81. package/dist/react/v2/experience.d.ts.map +1 -1
  82. package/dist/react/v2/experienceEvents.d.ts +3 -1
  83. package/dist/react/v2/experienceEvents.d.ts.map +1 -1
  84. package/dist/react/v2/sdkRelease.d.ts +3 -0
  85. package/dist/react/v2/sdkRelease.d.ts.map +1 -0
  86. package/dist/react/v2/types/sessionInteraction.d.ts +29 -0
  87. package/dist/react/v2/types/sessionInteraction.d.ts.map +1 -1
  88. package/dist/react/v2/types/sessionManifest.d.ts +1 -0
  89. package/dist/react/v2/types/sessionManifest.d.ts.map +1 -1
  90. package/dist/react/widget/mountExperienceWidget.d.ts.map +1 -1
  91. package/dist/react/widget/types.d.ts +5 -0
  92. package/dist/react/widget/types.d.ts.map +1 -1
  93. package/dist/sdk/v2/client.js +2 -2
  94. package/dist/sdk/v2/client.js.map +1 -1
  95. package/dist/svelte/Experience.svelte +6 -0
  96. package/dist/svelte/experienceLoadError.js +37 -15
  97. package/dist/svelte/experienceLoadError.test.js +8 -0
  98. package/dist/svelte/experienceLoadErrorOverlay.js +1 -1
  99. package/dist/svelte/experienceLoadErrorStyles.d.ts +1 -1
  100. package/dist/svelte/experienceLoadErrorStyles.js +1 -0
  101. package/package.json +1 -1
@@ -59,11 +59,13 @@
59
59
  startButton,
60
60
  theme,
61
61
  showFeedback,
62
+ interaction,
62
63
  closeButton,
63
64
  conversationProcessor,
64
65
  speechOnly = false,
65
66
  fit,
66
67
  attribution,
68
+ alreadyConverted,
67
69
  avatarId,
68
70
  backdropId,
69
71
  locationId,
@@ -114,6 +116,7 @@
114
116
  conversationProcessor ? identityKey(conversationProcessor) : 0,
115
117
  speechOnly,
116
118
  attribution,
119
+ alreadyConverted,
117
120
  avatarId,
118
121
  backdropId,
119
122
  locationId,
@@ -336,6 +339,7 @@
336
339
  speechInputMode,
337
340
  speechOnly,
338
341
  attribution,
342
+ alreadyConverted,
339
343
  conversationProcessor
340
344
  };
341
345
  }
@@ -356,6 +360,7 @@
356
360
  speechInputMode,
357
361
  speechOnly,
358
362
  attribution,
363
+ alreadyConverted,
359
364
  conversationProcessor
360
365
  };
361
366
  }
@@ -390,6 +395,7 @@
390
395
  startButton: untrack(() => startButton),
391
396
  theme: untrack(() => theme),
392
397
  showFeedback: untrack(() => showFeedback),
398
+ interaction: untrack(() => interaction),
393
399
  closeButton: untrack(() => closeButton),
394
400
  returnUrl: untrack(() => returnUrl),
395
401
  showClose: Boolean(onClose || returnUrl?.trim() || closeButton),
@@ -5,6 +5,26 @@ function toErrorMessage(error) {
5
5
  return error.message;
6
6
  return String(error);
7
7
  }
8
+ function readErrorMeta(error) {
9
+ if (!error || typeof error !== 'object')
10
+ return {};
11
+ const record = error;
12
+ const code = typeof record.code === 'string' && record.code.trim() && record.code.trim() !== 'UNKNOWN'
13
+ ? record.code.trim()
14
+ : undefined;
15
+ const requestId = typeof record.requestId === 'string' && record.requestId.trim()
16
+ ? record.requestId.trim()
17
+ : undefined;
18
+ return { code, requestId };
19
+ }
20
+ function formatTechnicalDetail(message, meta) {
21
+ const parts = [message];
22
+ if (meta.code)
23
+ parts.push(`Code: ${meta.code}`);
24
+ if (meta.requestId)
25
+ parts.push(`Request id: ${meta.requestId}`);
26
+ return parts.join('\n');
27
+ }
8
28
  function currentPageOrigin() {
9
29
  try {
10
30
  if (typeof globalThis.location?.origin === 'string' && globalThis.location.origin) {
@@ -23,49 +43,51 @@ export function extractOriginFromMessage(message) {
23
43
  return ORIGIN_IN_MESSAGE.exec(message)?.[1];
24
44
  }
25
45
  export function presentExperienceLoadError(error, options) {
26
- const technicalMessage = toErrorMessage(error).trim() || 'Unknown error';
46
+ const rawMessage = toErrorMessage(error).trim() || 'Unknown error';
47
+ const meta = readErrorMeta(error);
48
+ const technicalMessage = formatTechnicalDetail(rawMessage, meta);
27
49
  const experienceId = options?.experienceId?.trim() ||
28
- extractExperienceIdFromMessage(technicalMessage) ||
50
+ extractExperienceIdFromMessage(rawMessage) ||
29
51
  undefined;
30
52
  const origin = options?.origin?.trim() ||
31
- extractOriginFromMessage(technicalMessage) ||
53
+ extractOriginFromMessage(rawMessage) ||
32
54
  currentPageOrigin() ||
33
55
  undefined;
34
- if (/No playable experience found/i.test(technicalMessage) ||
35
- /^Experience is not available\.?$/i.test(technicalMessage) ||
36
- /^Unknown experience\.?$/i.test(technicalMessage) ||
37
- /experience_unavailable/i.test(technicalMessage)) {
56
+ if (/No playable experience found/i.test(rawMessage) ||
57
+ /^Experience is not available\.?$/i.test(rawMessage) ||
58
+ /^Unknown experience\.?$/i.test(rawMessage) ||
59
+ /experience_unavailable/i.test(rawMessage)) {
38
60
  const idLabel = experienceId ?? 'the requested experience';
39
61
  return {
40
62
  kind: 'not_found',
41
63
  title: 'The application tried to load an avatar experience that doesn’t exist.',
42
- detail: `Experience with id ${idLabel} does not exist`,
64
+ detail: formatTechnicalDetail(`Experience with id ${idLabel} does not exist`, meta),
43
65
  technicalMessage,
44
66
  experienceId,
45
67
  origin
46
68
  };
47
69
  }
48
- if (/origin_not_allowed/i.test(technicalMessage) ||
49
- /is not an allowed origin/i.test(technicalMessage) ||
50
- /^Origin not allowed/i.test(technicalMessage)) {
70
+ if (/origin_not_allowed/i.test(rawMessage) ||
71
+ /is not an allowed origin/i.test(rawMessage) ||
72
+ /^Origin not allowed/i.test(rawMessage)) {
51
73
  const originLabel = origin ?? 'this page';
52
74
  const idLabel = experienceId ?? 'the requested experience';
53
75
  return {
54
76
  kind: 'origin_not_allowed',
55
77
  title: 'The application tried to load an avatar experience from a website that isn’t allowed.',
56
- detail: `Origin ${originLabel} is not allowed for experience ${idLabel}`,
78
+ detail: formatTechnicalDetail(`Origin ${originLabel} is not allowed for experience ${idLabel}`, meta),
57
79
  technicalMessage,
58
80
  experienceId,
59
81
  origin
60
82
  };
61
83
  }
62
- if (/browser_embeds_disabled/i.test(technicalMessage) ||
63
- /^Browser embeds are not enabled/i.test(technicalMessage)) {
84
+ if (/browser_embeds_disabled/i.test(rawMessage) ||
85
+ /^Browser embeds are not enabled/i.test(rawMessage)) {
64
86
  const idLabel = experienceId ?? 'the requested experience';
65
87
  return {
66
88
  kind: 'browser_embeds_disabled',
67
89
  title: 'The application tried to load an avatar experience that isn’t enabled for browser embeds.',
68
- detail: `Browser embeds are not enabled for experience ${idLabel}`,
90
+ detail: formatTechnicalDetail(`Browser embeds are not enabled for experience ${idLabel}`, meta),
69
91
  technicalMessage,
70
92
  experienceId,
71
93
  origin
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { presentExperienceLoadError } from './experienceLoadError';
3
+ import { LiformaError } from '../v2/errors/LiformaError';
3
4
  describe('presentExperienceLoadError', () => {
4
5
  it('maps unavailable experiences to a friendly not-found presentation', () => {
5
6
  const presentation = presentExperienceLoadError(new Error('No playable experience found for “exp_01MISSING”. Check that the experience id is correct.'), { experienceId: 'exp_01MISSING' });
@@ -15,4 +16,11 @@ describe('presentExperienceLoadError', () => {
15
16
  expect(presentation.experienceId).toBe('exp_01DEMO');
16
17
  expect(presentation.origin).toBe('http://localhost:5173');
17
18
  });
19
+ it('includes code and request id in generic mint failure details', () => {
20
+ const presentation = presentExperienceLoadError(new LiformaError('API database schema is out of date (missing column actorLiformaUserId). Apply pending Prisma migrations on api.liforma.ai.', { code: 'SCHEMA_OUT_OF_DATE', requestId: 'req_abc', status: 502 }));
21
+ expect(presentation.kind).toBe('generic');
22
+ expect(presentation.detail).toContain('API database schema is out of date');
23
+ expect(presentation.detail).toContain('Code: SCHEMA_OUT_OF_DATE');
24
+ expect(presentation.detail).toContain('Request id: req_abc');
25
+ });
18
26
  });
@@ -30,7 +30,7 @@ export function createExperienceLoadErrorOverlay(container, initial) {
30
30
  title.textContent = presentation.title;
31
31
  detail.textContent = presentation.detail;
32
32
  detail.hidden = !advancedOpen;
33
- advancedBtn.textContent = advancedOpen ? 'Hide details' : 'Advanced';
33
+ advancedBtn.textContent = advancedOpen ? 'Hide details' : 'Show details';
34
34
  advancedBtn.setAttribute('aria-expanded', advancedOpen ? 'true' : 'false');
35
35
  }
36
36
  render();
@@ -1,4 +1,4 @@
1
1
  /** Subset of session loading overlay styles for pre-attach Experience load errors. */
2
2
  export declare const EXPERIENCE_LOAD_ERROR_STYLE_ID = "liforma-experience-load-error-styles";
3
3
  export declare function injectExperienceLoadErrorStyles(): void;
4
- export declare const EXPERIENCE_LOAD_ERROR_CSS = "\n\t.liforma-loading-screen {\n\t\tinset: 0;\n\t\tz-index: 20;\n\t\tbox-sizing: border-box;\n\t\toverflow-x: clip;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tmax-width: 100vw;\n\t\tbackground:\n\t\t\tradial-gradient(circle at 50% 60%, rgba(79, 126, 196, 0.18), transparent 38%),\n\t\t\t#030508;\n\t\tfont-family: system-ui, -apple-system, sans-serif;\n\t\tcolor: #e8f0ff;\n\t\ttext-align: center;\n\t}\n\t.liforma-loading-screen-absolute {\n\t\tposition: absolute;\n\t}\n\t.liforma-loading-card {\n\t\tposition: absolute;\n\t\tleft: 50%;\n\t\ttop: 60%;\n\t\ttransform: translate(-50%, -50%);\n\t\twidth: min(22rem, calc(100% - 2.5rem));\n\t\tmax-width: calc(100% - max(1.25rem, env(safe-area-inset-left, 0px)) - max(1.25rem, env(safe-area-inset-right, 0px)));\n\t\tbox-sizing: border-box;\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tborder: 0;\n\t\tbackground: transparent;\n\t\tbox-shadow: none;\n\t}\n\t.liforma-loading-card-error {\n\t\tdisplay: block;\n\t\ttext-align: center;\n\t\tpadding: 1rem 1.05rem;\n\t\tborder-radius: 14px;\n\t\tborder: 1px solid rgba(255, 154, 154, 0.28);\n\t\tbackground:\n\t\t\tlinear-gradient(180deg, rgba(21, 29, 42, 0.92), rgba(9, 13, 20, 0.92));\n\t}\n\t.liforma-loading-kicker {\n\t\tmargin: 0 0 0.18rem;\n\t\tcolor: #8ba4c5;\n\t\tfont-size: 0.68rem;\n\t\tfont-weight: 700;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.08em;\n\t}\n\t.liforma-loading-error {\n\t\tmargin: 0;\n\t\tmax-width: 28rem;\n\t\tcolor: #ffb4b4;\n\t\tfont-size: 0.92rem;\n\t\tline-height: 1.4;\n\t}\n\t.liforma-loading-error-title {\n\t\tmargin: 0;\n\t\tcolor: #f6ebe8;\n\t\tfont-size: 0.98rem;\n\t\tfont-weight: 650;\n\t\tline-height: 1.35;\n\t}\n\t.liforma-loading-error-advanced {\n\t\tmargin: 0.85rem 0 0;\n\t\tpadding: 0;\n\t\tborder: 0;\n\t\tbackground: transparent;\n\t\tcolor: #9eb7d8;\n\t\tfont: inherit;\n\t\tfont-size: 0.78rem;\n\t\tfont-weight: 650;\n\t\tletter-spacing: 0.02em;\n\t\ttext-decoration: underline;\n\t\ttext-underline-offset: 0.18em;\n\t\tcursor: pointer;\n\t}\n\t.liforma-loading-error-advanced:hover,\n\t.liforma-loading-error-advanced:focus-visible {\n\t\tcolor: #d7e6ff;\n\t\toutline: none;\n\t}\n\t.liforma-loading-error-detail {\n\t\tmargin: 0.7rem 0 0;\n\t\tpadding: 0.65rem 0.7rem;\n\t\tborder-radius: 10px;\n\t\tborder: 1px solid rgba(158, 191, 255, 0.16);\n\t\tbackground: rgba(3, 5, 8, 0.45);\n\t\tcolor: #c6d4e8;\n\t\tfont-size: 0.78rem;\n\t\tfont-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n\t\tline-height: 1.4;\n\t\ttext-align: left;\n\t\tword-break: break-word;\n\t}\n\t.liforma-loading-error-detail[hidden] {\n\t\tdisplay: none;\n\t}\n";
4
+ export declare const EXPERIENCE_LOAD_ERROR_CSS = "\n\t.liforma-loading-screen {\n\t\tinset: 0;\n\t\tz-index: 20;\n\t\tbox-sizing: border-box;\n\t\toverflow-x: clip;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tmax-width: 100vw;\n\t\tbackground:\n\t\t\tradial-gradient(circle at 50% 60%, rgba(79, 126, 196, 0.18), transparent 38%),\n\t\t\t#030508;\n\t\tfont-family: system-ui, -apple-system, sans-serif;\n\t\tcolor: #e8f0ff;\n\t\ttext-align: center;\n\t}\n\t.liforma-loading-screen-absolute {\n\t\tposition: absolute;\n\t}\n\t.liforma-loading-card {\n\t\tposition: absolute;\n\t\tleft: 50%;\n\t\ttop: 60%;\n\t\ttransform: translate(-50%, -50%);\n\t\twidth: min(22rem, calc(100% - 2.5rem));\n\t\tmax-width: calc(100% - max(1.25rem, env(safe-area-inset-left, 0px)) - max(1.25rem, env(safe-area-inset-right, 0px)));\n\t\tbox-sizing: border-box;\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tborder: 0;\n\t\tbackground: transparent;\n\t\tbox-shadow: none;\n\t}\n\t.liforma-loading-card-error {\n\t\tdisplay: block;\n\t\ttext-align: center;\n\t\tpadding: 1rem 1.05rem;\n\t\tborder-radius: 14px;\n\t\tborder: 1px solid rgba(255, 154, 154, 0.28);\n\t\tbackground:\n\t\t\tlinear-gradient(180deg, rgba(21, 29, 42, 0.92), rgba(9, 13, 20, 0.92));\n\t}\n\t.liforma-loading-kicker {\n\t\tmargin: 0 0 0.18rem;\n\t\tcolor: #8ba4c5;\n\t\tfont-size: 0.68rem;\n\t\tfont-weight: 700;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.08em;\n\t}\n\t.liforma-loading-error {\n\t\tmargin: 0;\n\t\tmax-width: 28rem;\n\t\tcolor: #ffb4b4;\n\t\tfont-size: 0.92rem;\n\t\tline-height: 1.4;\n\t}\n\t.liforma-loading-error-title {\n\t\tmargin: 0;\n\t\tcolor: #f6ebe8;\n\t\tfont-size: 0.98rem;\n\t\tfont-weight: 650;\n\t\tline-height: 1.35;\n\t}\n\t.liforma-loading-error-advanced {\n\t\tmargin: 0.85rem 0 0;\n\t\tpadding: 0;\n\t\tborder: 0;\n\t\tbackground: transparent;\n\t\tcolor: #9eb7d8;\n\t\tfont: inherit;\n\t\tfont-size: 0.78rem;\n\t\tfont-weight: 650;\n\t\tletter-spacing: 0.02em;\n\t\ttext-decoration: underline;\n\t\ttext-underline-offset: 0.18em;\n\t\tcursor: pointer;\n\t}\n\t.liforma-loading-error-advanced:hover,\n\t.liforma-loading-error-advanced:focus-visible {\n\t\tcolor: #d7e6ff;\n\t\toutline: none;\n\t}\n\t.liforma-loading-error-detail {\n\t\tmargin: 0.7rem 0 0;\n\t\tpadding: 0.65rem 0.7rem;\n\t\tborder-radius: 10px;\n\t\tborder: 1px solid rgba(158, 191, 255, 0.16);\n\t\tbackground: rgba(3, 5, 8, 0.45);\n\t\tcolor: #c6d4e8;\n\t\tfont-size: 0.78rem;\n\t\tfont-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n\t\tline-height: 1.4;\n\t\ttext-align: left;\n\t\twhite-space: pre-wrap;\n\t\tword-break: break-word;\n\t}\n\t.liforma-loading-error-detail[hidden] {\n\t\tdisplay: none;\n\t}\n";
@@ -104,6 +104,7 @@ export const EXPERIENCE_LOAD_ERROR_CSS = `
104
104
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
105
105
  line-height: 1.4;
106
106
  text-align: left;
107
+ white-space: pre-wrap;
107
108
  word-break: break-word;
108
109
  }
109
110
  .liforma-loading-error-detail[hidden] {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liforma/client",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "description": "Liforma browser SDK — Experience sessions, speech API, and Svelte embed component.",
6
6
  "license": "MIT",