@poveste/shared 0.7.0 → 0.8.0

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/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './codegen/index.js';
2
2
  export * from './setup.js';
3
3
  export * from './state.js';
4
+ export * from './story-error.js';
4
5
  export * from './story.js';
5
6
  export * from './type-utils.js';
6
7
  export * from './types/index.js';
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './codegen/index.js';
2
2
  export * from './setup.js';
3
3
  export * from './state.js';
4
+ export * from './story-error.js';
4
5
  export * from './story.js';
5
6
  export * from './type-utils.js';
6
7
  export * from './types/index.js';
@@ -0,0 +1,13 @@
1
+ export declare const SANDBOX_ERROR = "__poveste:sandbox-error";
2
+ export interface StoryError {
3
+ message: string;
4
+ stack?: string;
5
+ /**
6
+ * Which occupant threw. A warm realm is retargeted rather than reloaded
7
+ * (#240), so the host has to reject a report from the previous one.
8
+ */
9
+ storyId?: string;
10
+ variantId?: string;
11
+ }
12
+ export declare function toStoryError(error: unknown): Pick<StoryError, 'message' | 'stack'>;
13
+ export declare function reportStoryError(error: unknown, occupant?: Pick<StoryError, 'storyId' | 'variantId'>): void;
@@ -0,0 +1,30 @@
1
+ // A story whose component throws still renders — Vue routes the error to
2
+ // `console.error` and leaves the template on screen, so the book shows a broken
3
+ // component as if it worked (#323). Nothing in the app can observe that on its
4
+ // own: the throw never reaches `window.onerror`, so it has to be reported from
5
+ // inside the framework that swallowed it.
6
+ //
7
+ // This lives in `shared` because both the app and every plugin can import it,
8
+ // which keeps the sandbox-to-host contract in one place.
9
+ export const SANDBOX_ERROR = '__poveste:sandbox-error';
10
+ export function toStoryError(error) {
11
+ if (error instanceof Error) {
12
+ return { message: error.message || String(error), stack: error.stack };
13
+ }
14
+ return { message: typeof error === 'string' ? error : String(error) };
15
+ }
16
+ // Reports from inside the sandbox to the host. A no-op outside one, so a plugin
17
+ // can call it unconditionally — stories also render in the host document
18
+ // itself, where there is no parent to tell.
19
+ export function reportStoryError(error, occupant = {}) {
20
+ if (typeof window === 'undefined' || !window.parent || window.parent === window) {
21
+ return;
22
+ }
23
+ const payload = { ...toStoryError(error), ...occupant };
24
+ try {
25
+ window.parent.postMessage({ type: SANDBOX_ERROR, ...payload }, window.location.origin);
26
+ }
27
+ catch {
28
+ // Reporting a failure must not become one.
29
+ }
30
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@poveste/shared",
3
3
  "type": "module",
4
- "version": "0.7.0",
4
+ "version": "0.8.0",
5
5
  "description": "Shared utilities for Poveste",
6
6
  "author": {
7
7
  "name": "Sorin Gitlan"
@@ -44,7 +44,7 @@
44
44
  "pathe": "^1.1.2",
45
45
  "picocolors": "^1.1.1",
46
46
  "unhead": "^3.1.0",
47
- "@poveste/vendors": "^0.7.0"
47
+ "@poveste/vendors": "^0.8.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "typescript": "5.6.3",