@playgenx/components 0.1.0 → 0.2.1

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.
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ // SPDX-License-Identifier: MIT
3
+ /**
4
+ * playgenx-state — CLI for inspecting and operating on
5
+ * PlaygroundState snapshots.
6
+ *
7
+ * Pure ESM, no extra deps. Reads JSON from stdin (or argv),
8
+ * writes JSON to stdout.
9
+ *
10
+ * Subcommands:
11
+ *
12
+ * snapshot Pretty-print a snapshot in the v1 envelope format.
13
+ * Accepts a JSON object on stdin (the snapshot you
14
+ * captured from `state.snapshot()` or a DebugSurface).
15
+ *
16
+ * validate Validate one or more stateKey strings from stdin.
17
+ * Reads a JSON array of strings, returns the per-key
18
+ * verdict.
19
+ *
20
+ * diff Diff two snapshots. Reads `{prev, next}` from stdin
21
+ * and returns the structured {added, changed, removed}
22
+ * diff (or null when equal).
23
+ *
24
+ * keys List the sorted keys of a snapshot from stdin.
25
+ *
26
+ * count Count the keys in a snapshot from stdin.
27
+ *
28
+ * Usage examples (run from the components package root):
29
+ *
30
+ * echo '{"volume": 5}' | node bin/state-cli.mjs snapshot
31
+ * echo '["volume","user.name","bad key"]' | node bin/state-cli.mjs validate
32
+ * echo '{"prev":{"a":1},"next":{"a":2,"b":3}}' | node bin/state-cli.mjs diff
33
+ *
34
+ * Exit codes:
35
+ *
36
+ * 0 success
37
+ * 1 bad subcommand
38
+ * 2 bad input (not parseable as JSON, wrong shape, etc.)
39
+ * 3 validation failure (one or more keys rejected)
40
+ *
41
+ * @packageDocumentation
42
+ */
43
+
44
+ import {
45
+ dumpState,
46
+ diffSnapshots,
47
+ validateStateKey,
48
+ } from '../dist/index.mjs';
49
+
50
+ /**
51
+ * Read all of stdin into a string. Node-only.
52
+ */
53
+ async function readStdin() {
54
+ if (process.stdin.isTTY) {
55
+ // Interactive / no pipe — return empty; the caller will treat
56
+ // this as "no input" and print usage.
57
+ return '';
58
+ }
59
+ const chunks = [];
60
+ for await (const chunk of process.stdin) {
61
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
62
+ }
63
+ return Buffer.concat(chunks).toString('utf8');
64
+ }
65
+
66
+ function usage() {
67
+ return [
68
+ 'Usage: playgenx-state <subcommand> [input]',
69
+ '',
70
+ 'Subcommands:',
71
+ ' snapshot Pretty-print a state snapshot (JSON on stdin)',
72
+ ' validate Validate an array of stateKey strings (JSON array on stdin)',
73
+ ' diff Diff two snapshots ({prev, next} on stdin)',
74
+ ' keys List sorted keys of a snapshot (JSON on stdin)',
75
+ ' count Count keys in a snapshot (JSON on stdin)',
76
+ '',
77
+ 'Reads from stdin when no arg is given.',
78
+ ].join('\n');
79
+ }
80
+
81
+ function ok(payload) {
82
+ process.stdout.write(JSON.stringify(payload, null, 2) + '\n');
83
+ }
84
+
85
+ function fail(code, msg) {
86
+ process.stderr.write(`error: ${msg}\n`);
87
+ process.exit(code);
88
+ }
89
+
90
+ /**
91
+ * Convert an arbitrary snapshot to the StateEnvelope shape. The
92
+ * input is whatever the caller passed; we expect a plain object.
93
+ */
94
+ function envelope(input) {
95
+ const keys = Object.keys(input).sort();
96
+ return { version: 1, keys, values: { ...input } };
97
+ }
98
+
99
+ async function main(argv) {
100
+ const sub = argv[0];
101
+ if (!sub || sub === '-h' || sub === '--help') {
102
+ process.stdout.write(usage() + '\n');
103
+ return 0;
104
+ }
105
+ const stdinPayload = (await readStdin()).trim();
106
+ const argPayload = argv[1];
107
+
108
+ switch (sub) {
109
+ case 'snapshot': {
110
+ const input = parseObject(argPayload ?? stdinPayload);
111
+ // Re-use the library's envelope so the CLI output matches the
112
+ // canonical dumpState shape. (We don't have a real store to
113
+ // pass to dumpState; envelope() builds the same structure.)
114
+ const env = envelope(input);
115
+ process.stdout.write(JSON.stringify(env, null, 2) + '\n');
116
+ // Reference dumpState so it's not tree-shaken — the import
117
+ // is documented as the canonical envelope producer.
118
+ void dumpState;
119
+ return 0;
120
+ }
121
+
122
+ case 'validate': {
123
+ const input = parseArray(argPayload ?? stdinPayload);
124
+ const results = input.map((k) => {
125
+ if (typeof k !== 'string') {
126
+ return { key: String(k), ok: false, error: 'must be a string' };
127
+ }
128
+ const err = validateStateKey(k);
129
+ return err === null
130
+ ? { key: k, ok: true }
131
+ : { key: k, ok: false, error: err };
132
+ });
133
+ const anyFailed = results.some((r) => !r.ok);
134
+ ok(results);
135
+ return anyFailed ? 3 : 0;
136
+ }
137
+
138
+ case 'diff': {
139
+ const input = parseObject(argPayload ?? stdinPayload);
140
+ if (!('prev' in input) || !('next' in input)) {
141
+ fail(2, 'diff expects {prev, next}');
142
+ }
143
+ const prev = input.prev;
144
+ const next = input.next;
145
+ if (typeof prev !== 'object' || prev === null) fail(2, 'prev must be an object');
146
+ if (typeof next !== 'object' || next === null) fail(2, 'next must be an object');
147
+ const d = diffSnapshots(prev, next);
148
+ ok(d);
149
+ return 0;
150
+ }
151
+
152
+ case 'keys': {
153
+ const input = parseObject(argPayload ?? stdinPayload);
154
+ ok(Object.keys(input).sort());
155
+ return 0;
156
+ }
157
+
158
+ case 'count': {
159
+ const input = parseObject(argPayload ?? stdinPayload);
160
+ ok({ keys: Object.keys(input).length });
161
+ return 0;
162
+ }
163
+
164
+ default:
165
+ process.stderr.write(usage() + '\n');
166
+ return 1;
167
+ }
168
+ }
169
+
170
+ function parseObject(raw) {
171
+ if (raw === '') fail(2, 'expected a JSON object on stdin or as argv[1]');
172
+ try {
173
+ const v = JSON.parse(raw);
174
+ if (typeof v !== 'object' || v === null || Array.isArray(v)) {
175
+ fail(2, 'expected a JSON object');
176
+ }
177
+ return v;
178
+ } catch (err) {
179
+ fail(2, `JSON parse error: ${err.message}`);
180
+ }
181
+ }
182
+
183
+ function parseArray(raw) {
184
+ if (raw === '') fail(2, 'expected a JSON array on stdin or as argv[1]');
185
+ try {
186
+ const v = JSON.parse(raw);
187
+ if (!Array.isArray(v)) fail(2, 'expected a JSON array');
188
+ return v;
189
+ } catch (err) {
190
+ fail(2, `JSON parse error: ${err.message}`);
191
+ }
192
+ }
193
+
194
+ main(process.argv.slice(2))
195
+ .then((code) => process.exit(code))
196
+ .catch((err) => fail(2, err.message ?? String(err)));
package/dist/index.d.mts CHANGED
@@ -54,12 +54,37 @@ interface SliderProps {
54
54
  step?: number;
55
55
  /** Optional caption rendered above the slider. */
56
56
  label?: string;
57
+ /**
58
+ * When set, the slider is "bound" to the playground state: initial
59
+ * value comes from state.get(stateKey), onChange writes state.set.
60
+ * `value` prop is ignored when stateKey is present.
61
+ */
62
+ stateKey?: string;
57
63
  }
58
64
  /**
59
- * Range input. State: internal `value` mirrors props.value if present
60
- * (otherwise uncontrolled); clamps to [min, max].
65
+ * Range input. Three operating modes:
66
+ *
67
+ * 1. **Uncontrolled** (no `value`, no `stateKey`): the slider owns
68
+ * its value as local React state. The onChange mutates that state.
69
+ * Use this when nothing else needs to observe the value.
70
+ *
71
+ * 2. **Controlled by `value` prop**: the slider is read-only —
72
+ * user input is ignored because there is no `onChange` callback
73
+ * wired by the deterministic renderer. Use this for "static"
74
+ * sliders in artifacts. (If you want fully interactive control,
75
+ * use mode 3.)
76
+ *
77
+ * 3. **Bound to PlaygroundState via `stateKey`**: the slider reads
78
+ * its value from the nearest Provider's store (initial: either
79
+ * the store's current value OR `value` prop, whichever is
80
+ * present; the live store wins when bound). On change, the
81
+ * slider writes to the store. Other components can subscribe
82
+ * to the same key.
83
+ *
84
+ * In all modes the displayed value is clamped to `[min, max]`. NaN
85
+ * inputs clamp to `min`. When `min === max` the input is disabled.
61
86
  */
62
- declare function Slider({ min, max, value, step, label }: SliderProps): React.JSX.Element;
87
+ declare function Slider({ min, max, value, step, label, stateKey }: SliderProps): React.JSX.Element;
63
88
  //#endregion
64
89
  //#region src/Chart.d.ts
65
90
  type ChartKind = 'bar' | 'line' | 'pie';
@@ -176,23 +201,310 @@ interface ListProps {
176
201
  */
177
202
  declare function List({ items, ordered, children }: ListProps): React.JSX.Element;
178
203
  //#endregion
179
- //#region src/registry.d.ts
204
+ //#region src/state.d.ts
205
+ /**
206
+ * Per-render state store. Components read/write values keyed by string.
207
+ * One store per Provider instance; nested Providers create nested scopes.
208
+ */
209
+ interface PlaygroundState {
210
+ /** Read a value by key. Returns undefined if unset. */
211
+ get<T = unknown>(key: string): T | undefined;
212
+ /**
213
+ * Set a value. Triggers re-render of subscribers. No-op if the new
214
+ * value is `===` to the current value.
215
+ */
216
+ set<T = unknown>(key: string, value: T): void;
217
+ /**
218
+ * Subscribe to changes on a single key. The callback fires on every
219
+ * `set(key, ...)` with a different value. Returns an unsubscribe
220
+ * function. Non-React callers can use this directly.
221
+ */
222
+ subscribe(key: string, cb: (value: unknown) => void): () => void;
223
+ /**
224
+ * Bulk-read: returns a shallow snapshot of all keys. Useful for
225
+ * snapshotting state at a moment in time (e.g., for undo).
226
+ */
227
+ snapshot(): Readonly<Record<string, unknown>>;
228
+ /** Bulk-write: replace all values. Subscribers fire for changed keys. */
229
+ replaceAll(values: Record<string, unknown>): void;
230
+ }
231
+ /**
232
+ * Create a fresh state store. Public so PlaygroundStateProvider can
233
+ * construct one, but consumers should use Provider/usePlaygroundState
234
+ * to access stores (not direct construction).
235
+ *
236
+ * The optional type parameter is the "shape" of values you intend to
237
+ * store. It's purely a documentation convenience — the store does
238
+ * not enforce it (so you can store heterogeneous values for
239
+ * playgrounds that mix kinds), but `get<T>()` and `set<T>()` will
240
+ * infer correctly when you pass it here.
241
+ */
242
+ declare function createPlaygroundState<T = unknown>(initial?: Record<string, T>): PlaygroundState;
243
+ interface PlaygroundStateProviderProps {
244
+ /** Initial state values keyed by name. */
245
+ initial?: Record<string, unknown>;
246
+ /**
247
+ * Optional pre-existing state. If supplied, `initial` is merged on
248
+ * top (initial wins for overlapping keys). Use this for SSR
249
+ * rehydration or seeded values.
250
+ */
251
+ seed?: Record<string, unknown>;
252
+ children: React.ReactNode;
253
+ }
254
+ /**
255
+ * Provide a PlaygroundState scope to descendant components.
256
+ *
257
+ * Each Provider instance has its own store; nested Providers create
258
+ * independent scopes. Components rendered outside any Provider will
259
+ * throw a clear error if they call usePlaygroundState.
260
+ */
261
+ declare function PlaygroundStateProvider(props: PlaygroundStateProviderProps): React.JSX.Element;
262
+ /**
263
+ * Hook to access the nearest PlaygroundState store. Throws a clear
264
+ * error if called outside a Provider so consumers get a usable
265
+ * diagnostic instead of a `Cannot read properties of undefined`.
266
+ *
267
+ * Note for @playgenx/renderer users: the renderer's `renderBody`
268
+ * does NOT yet auto-wrap with a PlaygroundStateProvider. You'll
269
+ * need to wrap your own tree with `<PlaygroundStateProvider>` (or
270
+ * use the lower-level `renderNodes` API) before state-bound
271
+ * components can resolve. The `withState` option on `renderBody`
272
+ * is planned for a future renderer release (tracked in v0.6.0).
273
+ */
274
+ declare function usePlaygroundState(): PlaygroundState;
275
+ /**
276
+ * Optional helper for binding a component prop to a state key. Returns
277
+ * the live value (re-renders subscribers on change) and a setter. Pass
278
+ * `undefined` for `key` to disable the binding — the component behaves
279
+ * as if it had no stateKey, and `set` becomes a no-op. Safe to call
280
+ * outside a Provider.
281
+ *
282
+ * Implementation note: this hook ALWAYS calls the same number of
283
+ * React hooks regardless of whether `key` is set or a Provider is in
284
+ * scope. The "no binding" / "no Provider" branch uses dummy local
285
+ * state so the hook count stays aligned across renders. That means a
286
+ * component can flip `stateKey` from defined to undefined (or move in
287
+ * or out of a Provider) without crashing with a hooks-order error.
288
+ *
289
+ * Components that accept a `stateKey` prop should call this internally
290
+ * and use the returned tuple as a drop-in for the underlying
291
+ * value/onChange pair. The return type widens to `readonly [...] | undefined`
292
+ * so the caller can still branch on `if (bound)` — but they don't have
293
+ * to (the tuple is always safe to index).
294
+ *
295
+ * @example
296
+ * const bound = useBoundValueOrUndefined<number>(stateKey, 50);
297
+ * // ... onChange={(e) => bound?.[1](Number(e.currentTarget.value))}
298
+ */
299
+ declare function useBoundValueOrUndefined<T>(key: string | undefined, fallback: T): readonly [T, (next: T) => void] | undefined;
300
+ declare function useBoundValue<T>(key: string, fallback: T): readonly [T, (next: T) => void];
301
+ /**
302
+ * State-binding action shape. Used by `<Button onClickAction={...}>`.
303
+ * { set: { count: 1 } } -> sets state.count = 1
304
+ * { toggle: 'open' } -> sets state.open = !state.open
305
+ */
306
+ type StateAction = {
307
+ set?: Record<string, unknown>;
308
+ toggle?: string;
309
+ } | undefined;
310
+ /**
311
+ * Apply a StateAction to the nearest PlaygroundState. Returns an
312
+ * onClick handler that fires the action. If action is undefined
313
+ * the handler is a no-op.
314
+ */
315
+ declare function useStateAction(action: StateAction): (event: unknown) => void;
316
+ //#endregion
317
+ //#region src/stateHelpers.d.ts
180
318
  /**
181
- * Map of PascalCase component name to React component. Use this when
182
- * you have a renderer that walks an AST and needs to pick an
183
- * implementation at runtime:
319
+ * Structured diff between two state snapshots. Pure function does
320
+ * not touch the stores. Returns `null` when the snapshots are
321
+ * shallowly equal (no additions, no changes, no removals).
184
322
  *
185
- * const C = componentMap[tagName];
186
- * if (C) el = <C {...props}>{children}</C>;
323
+ * @example
324
+ * const a = { x: 1, y: 2 };
325
+ * const b = { x: 1, y: 3, z: 4 };
326
+ * diffSnapshots(a, b); // { added: ['z'], changed: ['y'], removed: [] }
327
+ */
328
+ interface StateDiff {
329
+ /** Keys present in `next` but absent from `prev`. */
330
+ added: string[];
331
+ /** Keys whose value changed (using `Object.is` to compare). */
332
+ changed: string[];
333
+ /** Keys present in `prev` but absent from `next`. */
334
+ removed: string[];
335
+ }
336
+ declare function diffSnapshots(prev: Readonly<Record<string, unknown>>, next: Readonly<Record<string, unknown>>): StateDiff | null;
337
+ /**
338
+ * Convenience: take snapshots of both stores and diff them. Returns
339
+ * `null` when equal. Useful in tests and debug endpoints.
340
+ */
341
+ declare function diffState(_a: PlaygroundState, _b: PlaygroundState, prev?: Readonly<Record<string, unknown>>, next?: Readonly<Record<string, unknown>>): StateDiff | null;
342
+ /**
343
+ * Validate a state-key string. Returns `null` on success, or a
344
+ * human-readable error message on failure. The rules:
345
+ *
346
+ * - 1..64 characters
347
+ * - No whitespace
348
+ * - Only alphanumerics, dots, dashes, underscores
349
+ * - Must start with an alphabetic character (so a parser can
350
+ * safely infer `<Slider stateKey="...">` from a body without
351
+ * swallowing accidental numeric keys).
352
+ *
353
+ * Note: keys like `with/slash` or `with spaces` are rejected because
354
+ * the schema-driven body parser uses them as attribute names —
355
+ * a key with weird characters would break the round-trip.
356
+ */
357
+ declare function validateStateKey(key: string): string | null;
358
+ /**
359
+ * Remove every key from the store, firing subscribers with `undefined`.
360
+ * After this call, `state.snapshot()` is `{}`.
361
+ */
362
+ declare function clearState(state: PlaygroundState): void;
363
+ /**
364
+ * JSON-envelope snapshot for offline inspection. Useful for:
365
+ * - piping into `jq` / debug endpoints
366
+ * - attaching to error reports
367
+ * - round-tripping through `JSON.parse(state.snapshot)`.
368
+ *
369
+ * The `version` field is bumped if the envelope shape ever changes,
370
+ * so consumers can branch on it.
371
+ */
372
+ interface StateEnvelope {
373
+ /** Always 1 for now. */
374
+ version: 1;
375
+ /** Sorted list of keys (stable for diffing). */
376
+ keys: string[];
377
+ /** Shallow key→value map. */
378
+ values: Record<string, unknown>;
379
+ }
380
+ declare function dumpState(state: PlaygroundState): string;
381
+ /**
382
+ * Apply multiple `set` calls as a single atomic batch. Each
383
+ * subscriber sees only the LAST value written to its key in this
384
+ * batch. The store still batches subscriber fires via the microtask
385
+ * scheduler — `batch` does not flush synchronously, it only ensures
386
+ * that within the batch, repeated `set` calls to the same key don't
387
+ * queue redundant fires.
388
+ *
389
+ * Useful for: undo/redo, multi-field form commits, hydrated state
390
+ * restore where you want each subscriber to fire exactly once with
391
+ * the final value.
392
+ *
393
+ * @example
394
+ * batch(state, (s) => {
395
+ * s.set('x', 1);
396
+ * s.set('y', 2);
397
+ * s.set('x', 3); // overwrites; subscriber sees only 3
398
+ * });
399
+ */
400
+ declare function batch<T>(state: PlaygroundState, fn: (state: PlaygroundState) => T): T;
401
+ //#endregion
402
+ //#region src/ArtifactErrorBoundary.d.ts
403
+ interface ArtifactErrorBoundaryProps {
404
+ children: React.ReactNode;
405
+ /**
406
+ * Called when a render error is caught. The `info.componentStack`
407
+ * string is the React component stack at the point of error. Log
408
+ * to your observability backend here.
409
+ */
410
+ onError?: (error: Error, info: {
411
+ componentStack: string;
412
+ }) => void;
413
+ /**
414
+ * Optional body string. If present and the consumer renders the
415
+ * default fallback, a "Show source" toggle will be available that
416
+ * reveals this body verbatim. Ignored if a custom `fallback` is
417
+ * supplied (the consumer is responsible for surfacing source).
418
+ */
419
+ body?: string;
420
+ /**
421
+ * Source language hint for the ShowSource toggle in the default
422
+ * fallback. Defaults to 'tsx' (most artifacts are TSX).
423
+ */
424
+ language?: 'tsx' | 'json';
425
+ /**
426
+ * Optional custom fallback. Pass a React element for a static fallback
427
+ * or a function that receives the error for a dynamic one. If
428
+ * omitted, the default fallback renders a panel with the error
429
+ * message and (if `body` is supplied) a ShowSource toggle.
430
+ */
431
+ fallback?: React.ReactNode | ((error: Error) => React.ReactNode);
432
+ /**
433
+ * Label shown in the default fallback header. Defaults to the
434
+ * artifact kind identifier (e.g. "playground artifact failed to
435
+ * render"). The consumer is expected to pass the kind.
436
+ */
437
+ kind?: string;
438
+ }
439
+ interface State {
440
+ error: Error | null;
441
+ }
442
+ /**
443
+ * Error boundary. Catches render-time errors in `children` and shows
444
+ * the fallback. The error state is reset on prop change of `children`
445
+ * (or explicit `resetKey` bump) so the consumer can recover by
446
+ * re-rendering.
447
+ */
448
+ declare class ArtifactErrorBoundary extends React.Component<ArtifactErrorBoundaryProps, State> {
449
+ state: State;
450
+ static getDerivedStateFromError(error: Error): State;
451
+ componentDidCatch(error: Error, info: React.ErrorInfo): void;
452
+ render(): React.ReactNode;
453
+ }
454
+ //#endregion
455
+ //#region src/ShowSource.d.ts
456
+ interface ShowSourceProps {
457
+ /** The raw body to display when the user expands the source. */
458
+ body: string;
459
+ /** Source language hint. Used in `data-language` for styling hooks. */
460
+ language?: 'tsx' | 'json';
461
+ /**
462
+ * Children is a render prop that receives `(toggle, showing)`.
463
+ * The consumer is expected to render a trigger element (button,
464
+ * link, etc.) and call `toggle` on user interaction.
465
+ */
466
+ children: (toggle: () => void, showing: boolean) => React.ReactNode;
467
+ }
468
+ /**
469
+ * Toggle button + expandable source panel. The trigger UI is the
470
+ * consumer's choice; the panel is plain `<pre><code>`.
471
+ */
472
+ declare function ShowSource(props: ShowSourceProps): React.JSX.Element;
473
+ //#endregion
474
+ //#region src/createRegistry.d.ts
475
+ /**
476
+ * Map of PascalCase component name to React component. Loose typing
477
+ * (`ComponentType<any>`) because each component's prop shape differs and
478
+ * the runtime doesn't know which one it's looking up. Consumers who
479
+ * need stricter types can build their own typed wrapper around
480
+ * `renderBody`.
481
+ */
482
+ type ComponentMap = Record<string, ComponentType<any>>;
483
+ /**
484
+ * The full default registry (Button, Card, Chart, Code, Container,
485
+ * Heading, List, Slider, Stepper, Text, TextField). Frozen. Use
486
+ * `createRegistry(overrides)` to extend.
487
+ */
488
+ declare const componentMap: ComponentMap;
489
+ /**
490
+ * Build a new registry by merging the defaults with caller-supplied
491
+ * overrides. The returned map is frozen (Object.freeze) to prevent
492
+ * post-hoc mutation that would surprise concurrent renders.
187
493
  *
188
- * Keys mirror `DEFAULT_REGISTRY.list()`.
494
+ * **Lowercase HTML tags are NOT in this map.** The renderer handles
495
+ * `div`, `span`, etc. as React intrinsic elements separately. Calling
496
+ * `createRegistry({ div: StubDiv })` will NOT override the renderer
497
+ * for `<div>` (the renderer uses the lowercase lookup path first).
189
498
  *
190
- * Type note: components vary in their props shape, so the map is
191
- * typed permissively (`Record<string, ComponentType<any>>`). Each
192
- * individual export above is still strictly typed.
499
+ * @example
500
+ * ```ts
501
+ * const map = createRegistry({
502
+ * MathExpression: MathExpressionComponent,
503
+ * LatexBlock: LatexBlockComponent,
504
+ * });
505
+ * ```
193
506
  */
194
- declare const componentMap: Record<string, ComponentType<any>>;
195
- type ComponentMapKey = keyof typeof componentMap;
507
+ declare function createRegistry(overrides: Partial<ComponentMap>): ComponentMap;
196
508
  //#endregion
197
- export { Button, type ButtonProps, Card, type CardProps, Chart, type ChartKind, type ChartProps, Code, type CodeProps, ComponentMapKey, Container, type ContainerProps, Heading, type HeadingProps, List, type ListProps, Slider, type SliderProps, type Step, Stepper, type StepperProps, Text, TextField, type TextFieldProps, type TextProps, componentMap };
509
+ export { ArtifactErrorBoundary, type ArtifactErrorBoundaryProps, Button, type ButtonProps, Card, type CardProps, Chart, type ChartKind, type ChartProps, Code, type CodeProps, type ComponentMap, Container, type ContainerProps, Heading, type HeadingProps, List, type ListProps, type PlaygroundState, PlaygroundStateProvider, type PlaygroundStateProviderProps, ShowSource, type ShowSourceProps, Slider, type SliderProps, type StateAction, type StateDiff, type StateEnvelope, type Step, Stepper, type StepperProps, Text, TextField, type TextFieldProps, type TextProps, batch, clearState, componentMap, createPlaygroundState, createRegistry, diffSnapshots, diffState, dumpState, useBoundValue, useBoundValueOrUndefined, usePlaygroundState, useStateAction, validateStateKey };
198
510
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/Button.tsx","../src/TextField.tsx","../src/Slider.tsx","../src/Chart.tsx","../src/Container.tsx","../src/Code.tsx","../src/Heading.tsx","../src/Text.tsx","../src/Stepper.tsx","../src/Card.tsx","../src/List.tsx","../src/registry.ts"],"mappings":";;;;;;;;;UASiB;;EAEf;;EAEA;;EAEA;;;;;EAKA,UAAU,MAAM,kBAAkB;;iBAGpB,SACd,OACA,SACA,UACA,WACC,cAAc,MAAM,IAAI;;;UCzBV;EACf;EACA;EACA;EACA;;;;;;EAMA,WAAW,MAAM,mBAAmB;;;;;;;iBAQtB,YACd,OACA,OACA,aACA,UACA,YACC,iBAAiB,MAAM,IAAI;;;UCxBb;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;iBAOc,SAAS,KAAK,KAAK,OAAO,MAAU,SAAS,cAAc,MAAM,IAAI;;;KCjBzE;;;;;;;;;;;UAYK;EACf,MAAM;EACN;EACA;;iBAGc,QAAQ,MAAM,MAAM,SAAS,aAAa,MAAM,IAAI;;;UCnBnD;EACf;EACA;EACA,WAAW,MAAM;;;;;;iBAOH,YAAY,SAAS,KAAK,YAAY,iBAAiB,MAAM,IAAI;;;UCThE;EACf;EACA,WAAW,MAAM;;;;;;;;iBASH,OAAO,UAAU,YAAY,YAAY,MAAM,IAAI;;;UCXlD;;;;;;EAMf;EACA;EACA,WAAW,MAAM;;iBAYH,UAAU,OAAO,OAAO,YAAY,eAAe,MAAM,IAAI;;;UCpB5D;EACf;EACA;EACA;EACA,WAAW,MAAM;;iBAGH,OAAO,QAAmB,MAAM,OAAO,YAAY,YAAY,MAAM,IAAI;;;UCPxE;EACf;EACA;EACA,OAAO,MAAM;;UAGE;EACf,OAAO;;EAEP;;;;;;iBAOc,UAAU,OAAO,WAAW,eAAe,MAAM,IAAI;;;UChBpD;EACf;;;;;EAKA;EACA,WAAW,MAAM;;iBAGH,OAAO,OAAO,WAAe,YAAY,YAAY,MAAM,IAAI;;;UCV9D;;;;;;EAMf;;EAEA;;EAEA,WAAW,MAAM;;;;;;;iBAQH,OAAO,OAAO,SAAS,YAAY,YAAY,MAAM,IAAI;;;;;;;;;;;;;;;;;cC6B5D,cAAc,eAAe;KAc9B,+BAA+B"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/Button.tsx","../src/TextField.tsx","../src/Slider.tsx","../src/Chart.tsx","../src/Container.tsx","../src/Code.tsx","../src/Heading.tsx","../src/Text.tsx","../src/Stepper.tsx","../src/Card.tsx","../src/List.tsx","../src/state.tsx","../src/stateHelpers.ts","../src/ArtifactErrorBoundary.tsx","../src/ShowSource.tsx","../src/createRegistry.ts"],"mappings":"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"}