@seed-ship/mcp-ui-solid 5.3.1 → 5.5.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/CHANGELOG.md +104 -0
- package/dist/components/StreamingUIRenderer.cjs +106 -90
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts +7 -0
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +107 -91
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +101 -82
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts +23 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +102 -83
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-ui-spec/dist/schemas.cjs +493 -0
- package/dist/mcp-ui-spec/dist/schemas.cjs.map +1 -0
- package/dist/mcp-ui-spec/dist/schemas.js +493 -0
- package/dist/mcp-ui-spec/dist/schemas.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.cjs +118 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js +118 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.cjs +10 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js +10 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs +8 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js +9 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs +122 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js +122 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs +137 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js +139 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.cjs +105 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js +106 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs +3229 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs.map +1 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js +3230 -0
- package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js.map +1 -0
- package/dist/services/validation.cjs +70 -152
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +70 -152
- package/dist/services/validation.js.map +1 -1
- package/dist/utils/logger.cjs +26 -4
- package/dist/utils/logger.cjs.map +1 -1
- package/dist/utils/logger.d.ts +30 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +27 -5
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/perf.cjs +34 -0
- package/dist/utils/perf.cjs.map +1 -0
- package/dist/utils/perf.d.ts +19 -0
- package/dist/utils/perf.d.ts.map +1 -0
- package/dist/utils/perf.js +34 -0
- package/dist/utils/perf.js.map +1 -0
- package/package.json +3 -2
- package/src/components/StreamingUIRenderer.tsx +54 -2
- package/src/components/UIResourceRenderer.errorMode.test.tsx +95 -0
- package/src/components/UIResourceRenderer.tsx +72 -4
- package/src/index.ts +7 -0
- package/src/services/validation.spec-migration.test.ts +207 -0
- package/src/services/validation.ts +132 -178
- package/src/utils/logger.test.ts +130 -0
- package/src/utils/logger.ts +60 -7
- package/src/utils/perf.test.ts +59 -0
- package/src/utils/perf.ts +50 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/utils/logger.ts
CHANGED
|
@@ -1,12 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Simple internal logger utility
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Logging is enabled when EITHER:
|
|
5
|
+
* 1. `process.env.NODE_ENV !== 'production'` (dev build), OR
|
|
6
|
+
* 2. `process.env.MCP_UI_DEBUG === 'true'` (server-side opt-in for prod), OR
|
|
7
|
+
* 3. `globalThis.__MCP_UI_DEBUG__ === true` (browser-side runtime toggle), OR
|
|
8
|
+
* 4. `setDebugMode(true)` has been called from app code.
|
|
9
|
+
*
|
|
10
|
+
* `error` always logs regardless of mode.
|
|
11
|
+
*
|
|
12
|
+
* @see setDebugMode, isDebugEnabled — runtime controls (v5.4.0)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
// Browser-side runtime flag — settable from devtools console:
|
|
17
|
+
// `globalThis.__MCP_UI_DEBUG__ = true`
|
|
18
|
+
// eslint-disable-next-line no-var
|
|
19
|
+
var __MCP_UI_DEBUG__: boolean | undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let debugOverride: boolean | null = null
|
|
23
|
+
|
|
24
|
+
function readEnvFlag(): boolean {
|
|
25
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
26
|
+
if (process.env.MCP_UI_DEBUG === 'true') return true
|
|
27
|
+
if (process.env.NODE_ENV !== 'production') return true
|
|
28
|
+
}
|
|
29
|
+
if (typeof globalThis !== 'undefined' && globalThis.__MCP_UI_DEBUG__ === true) {
|
|
30
|
+
return true
|
|
31
|
+
}
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isDebugActive(): boolean {
|
|
36
|
+
if (debugOverride !== null) return debugOverride
|
|
37
|
+
return readEnvFlag()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Programmatically enable/disable verbose logging at runtime.
|
|
42
|
+
*
|
|
43
|
+
* Pass `null` to clear the override and fall back to env-based detection.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { setDebugMode } from '@seed-ship/mcp-ui-solid'
|
|
48
|
+
* setDebugMode(true) // turn on verbose logs
|
|
49
|
+
* setDebugMode(false) // turn off (overrides NODE_ENV=development)
|
|
50
|
+
* setDebugMode(null) // restore env-based behavior
|
|
51
|
+
* ```
|
|
7
52
|
*/
|
|
53
|
+
export function setDebugMode(enabled: boolean | null): void {
|
|
54
|
+
debugOverride = enabled
|
|
55
|
+
}
|
|
8
56
|
|
|
9
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Whether verbose logging is currently active (env + override combined).
|
|
59
|
+
*/
|
|
60
|
+
export function isDebugEnabled(): boolean {
|
|
61
|
+
return isDebugActive()
|
|
62
|
+
}
|
|
10
63
|
|
|
11
64
|
export interface Logger {
|
|
12
65
|
info(message: string, context?: Record<string, unknown>): void
|
|
@@ -39,13 +92,13 @@ function formatLogMessage(
|
|
|
39
92
|
export function createLogger(feature: string): Logger {
|
|
40
93
|
return {
|
|
41
94
|
info(message: string, context?: Record<string, unknown>) {
|
|
42
|
-
if (
|
|
95
|
+
if (isDebugActive()) {
|
|
43
96
|
console.info(formatLogMessage(feature, message, context))
|
|
44
97
|
}
|
|
45
98
|
},
|
|
46
99
|
|
|
47
100
|
warn(message: string, context?: Record<string, unknown>) {
|
|
48
|
-
if (
|
|
101
|
+
if (isDebugActive()) {
|
|
49
102
|
console.warn(formatLogMessage(feature, message, context))
|
|
50
103
|
}
|
|
51
104
|
},
|
|
@@ -56,7 +109,7 @@ export function createLogger(feature: string): Logger {
|
|
|
56
109
|
},
|
|
57
110
|
|
|
58
111
|
debug(message: string, context?: Record<string, unknown>) {
|
|
59
|
-
if (
|
|
112
|
+
if (isDebugActive()) {
|
|
60
113
|
console.debug(formatLogMessage(feature, message, context))
|
|
61
114
|
}
|
|
62
115
|
},
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for performance markers — v5.4.0 (B.4)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
6
|
+
import { markRenderStart, markRenderEnd, PERF_PREFIX } from './perf'
|
|
7
|
+
|
|
8
|
+
describe('performance marks (v5.4.0 — B.4)', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
if (typeof performance !== 'undefined' && typeof performance.clearMarks === 'function') {
|
|
11
|
+
performance.clearMarks()
|
|
12
|
+
}
|
|
13
|
+
if (typeof performance !== 'undefined' && typeof performance.clearMeasures === 'function') {
|
|
14
|
+
performance.clearMeasures()
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('PERF_PREFIX is the documented namespace', () => {
|
|
19
|
+
expect(PERF_PREFIX).toBe('mcp-ui:component:')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('markRenderStart writes a `:render-start` mark with the component id', () => {
|
|
23
|
+
markRenderStart('cmp-A')
|
|
24
|
+
const entries = performance.getEntriesByName('mcp-ui:component:cmp-A:render-start')
|
|
25
|
+
expect(entries.length).toBe(1)
|
|
26
|
+
expect(entries[0].entryType).toBe('mark')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('markRenderEnd writes both `:render-end` mark and a `:render` measure', () => {
|
|
30
|
+
markRenderStart('cmp-B')
|
|
31
|
+
markRenderEnd('cmp-B')
|
|
32
|
+
|
|
33
|
+
const endEntries = performance.getEntriesByName('mcp-ui:component:cmp-B:render-end')
|
|
34
|
+
expect(endEntries.length).toBe(1)
|
|
35
|
+
|
|
36
|
+
const measureEntries = performance.getEntriesByName('mcp-ui:component:cmp-B:render')
|
|
37
|
+
expect(measureEntries.length).toBe(1)
|
|
38
|
+
expect(measureEntries[0].entryType).toBe('measure')
|
|
39
|
+
expect(measureEntries[0].duration).toBeGreaterThanOrEqual(0)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('markRenderEnd without a preceding markRenderStart still writes the end mark (no throw)', () => {
|
|
43
|
+
expect(() => markRenderEnd('cmp-orphan')).not.toThrow()
|
|
44
|
+
const endEntries = performance.getEntriesByName('mcp-ui:component:cmp-orphan:render-end')
|
|
45
|
+
expect(endEntries.length).toBe(1)
|
|
46
|
+
// measure may or may not be created, but it must NOT crash the render path
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('mark functions are no-ops when performance is undefined (SSR-safe)', () => {
|
|
50
|
+
const originalPerf = (globalThis as any).performance
|
|
51
|
+
;(globalThis as any).performance = undefined
|
|
52
|
+
try {
|
|
53
|
+
expect(() => markRenderStart('ssr')).not.toThrow()
|
|
54
|
+
expect(() => markRenderEnd('ssr')).not.toThrow()
|
|
55
|
+
} finally {
|
|
56
|
+
;(globalThis as any).performance = originalPerf
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance markers for component renders (v5.4.0)
|
|
3
|
+
*
|
|
4
|
+
* Emits `performance.mark()` entries that show up automatically in Chrome
|
|
5
|
+
* DevTools "Performance" panel under user timings. Consumers can also
|
|
6
|
+
* query them via `performance.getEntriesByName(...)` for custom tracing.
|
|
7
|
+
*
|
|
8
|
+
* Naming convention :
|
|
9
|
+
* `mcp-ui:component:<id>:render-start`
|
|
10
|
+
* `mcp-ui:component:<id>:render-end`
|
|
11
|
+
* `mcp-ui:component:<id>:render` (a `measure` between the two)
|
|
12
|
+
*
|
|
13
|
+
* Always-on: marks are cheap (sub-microsecond) and only matter when a
|
|
14
|
+
* profiler is recording. SSR-safe (`performance` is guarded).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const PERF_PREFIX = 'mcp-ui:component:'
|
|
18
|
+
|
|
19
|
+
function hasPerf(): boolean {
|
|
20
|
+
return typeof performance !== 'undefined' && typeof performance.mark === 'function'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function markRenderStart(componentId: string): void {
|
|
24
|
+
if (!hasPerf()) return
|
|
25
|
+
try {
|
|
26
|
+
performance.mark(`${PERF_PREFIX}${componentId}:render-start`)
|
|
27
|
+
} catch {
|
|
28
|
+
// Ignore — performance.mark can throw on malformed names; not worth crashing the render.
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function markRenderEnd(componentId: string): void {
|
|
33
|
+
if (!hasPerf()) return
|
|
34
|
+
try {
|
|
35
|
+
performance.mark(`${PERF_PREFIX}${componentId}:render-end`)
|
|
36
|
+
if (typeof performance.measure === 'function') {
|
|
37
|
+
try {
|
|
38
|
+
performance.measure(
|
|
39
|
+
`${PERF_PREFIX}${componentId}:render`,
|
|
40
|
+
`${PERF_PREFIX}${componentId}:render-start`,
|
|
41
|
+
`${PERF_PREFIX}${componentId}:render-end`
|
|
42
|
+
)
|
|
43
|
+
} catch {
|
|
44
|
+
// Start mark may be missing if the render path was short-circuited — ignore.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
// Ignore.
|
|
49
|
+
}
|
|
50
|
+
}
|