diff --git a/craft/src/utils/tiny-invariant-shim.ts b/craft/src/utils/tiny-invariant-shim.ts new file mode 100644 index 0000000..e9ec33b --- /dev/null +++ b/craft/src/utils/tiny-invariant-shim.ts @@ -0,0 +1,17 @@ +/** + * Diagnostic shim for tiny-invariant. The prod tiny-invariant strips + * the failure message, so we lose the actual reason for any Craft.js + * Invariant. Aliasing tiny-invariant -> this shim restores it. + */ +export default function invariant(condition: unknown, message?: string | (() => string)): asserts condition { + if (condition) return; + const provided = typeof message === 'function' ? message() : message; + const value = provided ? `Invariant failed: ${provided}` : 'Invariant failed'; + // Surface the message + stack to the console BEFORE throwing so even + // an uncaught throw leaves a trace we can read. + // eslint-disable-next-line no-console + console.error('[CRAFT INVARIANT]', value); + // eslint-disable-next-line no-console + console.error(new Error('stack-only').stack); + throw new Error(value); +} diff --git a/craft/vite.config.ts b/craft/vite.config.ts index d35d5e4..d77c538 100644 --- a/craft/vite.config.ts +++ b/craft/vite.config.ts @@ -8,6 +8,9 @@ export default defineConfig({ resolve: { alias: { '@': path.resolve(__dirname, './src'), + // Diagnostic: replace tiny-invariant with a shim that always logs the + // failure message (the upstream prod build strips it). + 'tiny-invariant': path.resolve(__dirname, './src/utils/tiny-invariant-shim.ts'), }, }, build: {