@ikonai/sdk-react-ui 0.0.28 → 0.0.31

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/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@ikonai/sdk-react-ui",
3
- "version": "0.0.28",
3
+ "version": "0.0.31",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
7
+ "sideEffects": false,
7
8
  "exports": {
8
9
  ".": {
9
10
  "import": "./index.js",
@@ -1,4 +1,6 @@
1
- export { UiRenderer, type UiRendererProps } from './ui-renderer';
1
+ export { UiRenderer, type UiRendererProps, renderChildren } from './ui-renderer';
2
2
  export { UiComponentRegistry, createComponentLibrary, } from './component-library';
3
3
  export { useUiStore } from './use-ui-store';
4
+ export { useUiNode } from './use-ui-node';
5
+ export { useRootView } from './use-root-view';
4
6
  export type { UiComponentRenderer, UiComponentLibrary, UiNode, UiRenderContext, UiComponentRendererProps, ParsedUiUpdate, UiSnapshot, UiFullSnapshot, UiDiffSnapshot, UiNodeDiff, TextDelta, UiNodeProps, UiUpdateType, UiStoreSnapshot, UiOptimisticPatchState, } from './types';
@@ -1,22 +1,43 @@
1
- import { UIPayload } from '../../../../shared/generated/src/index.ts';
2
- import { UiNode } from '../../../sdk-ui/src/index.ts';
1
+ import { UIPayload } from '../../../../shared/protocol/src/index.ts';
2
+ import { HandlerCache, UiNode, UiStreamStore } from '../../../sdk-ui/src/index.ts';
3
3
  import { IkonClient, IkonVideoPlayback } from '../../../sdk/src/index.ts';
4
4
  import { ComponentType, ReactNode } from 'react';
5
5
  export { type UiUpdateType, type UiNodeProps, type UiNode, type UiNodeDiff, type UiSnapshot, type UiFullSnapshot, type UiDiffSnapshot, type UiSnapshotMetadata, type UiOptimisticPatchMetadata, type UiOptimisticReconcileMetadata, type TextDelta, type ParsedUiUpdate, type UiStoreSnapshot, type UiOptimisticPatchState, } from '../../../sdk-ui/src/index.ts';
6
+ /**
7
+ * Context for rendering UI nodes.
8
+ * Provides access to payloads, action dispatch, and rendering utilities.
9
+ */
6
10
  export interface UiRenderContext {
11
+ /** Get a payload by key */
7
12
  getPayload(key: string): UIPayload | undefined;
13
+ /** Render child nodes (for backward compatibility) */
8
14
  renderChildren(nodes: readonly UiNode[]): ReactNode;
15
+ /** Render a view by ID */
9
16
  renderView(viewId: string): ReactNode;
17
+ /** Dispatch an action with optional payload */
10
18
  dispatchAction(actionId: string, payload?: unknown): void;
19
+ /** The Ikon client instance */
11
20
  client?: IkonClient;
21
+ /** Video playback API */
12
22
  video?: IkonVideoPlayback;
23
+ /** The store instance for per-node subscriptions */
24
+ store: UiStreamStore;
25
+ /** The component library for resolving renderers */
26
+ library: UiComponentLibrary;
27
+ /** Handler cache for stable event handlers */
28
+ handlerCache: HandlerCache;
13
29
  }
30
+ /**
31
+ * Props passed to component renderers.
32
+ * New pattern: nodeId + store for granular updates.
33
+ */
14
34
  export interface UiComponentRendererProps {
15
- readonly node: UiNode;
35
+ /** The node ID to render */
36
+ readonly nodeId: string;
37
+ /** The rendering context */
16
38
  readonly context: UiRenderContext;
17
- readonly children: readonly ReactNode[];
39
+ /** CSS class name from styleIds */
18
40
  readonly className?: string;
19
- readonly styleIds: readonly string[];
20
41
  }
21
42
  export type UiComponentRenderer = ComponentType<UiComponentRendererProps>;
22
43
  export interface UiComponentLibrary {
@@ -1,7 +1,14 @@
1
1
  import { IkonClient, IkonVideoPlayback } from '../../../sdk/src/index.ts';
2
2
  import { UiStreamStore } from '../../../sdk-ui/src/index.ts';
3
3
  import { ReactNode } from 'react';
4
- import { UiComponentLibrary } from './types';
4
+ import { UiComponentLibrary, UiNode, UiRenderContext } from './types';
5
+ /**
6
+ * Render children nodes by their IDs.
7
+ * Used by component renderers to render their children.
8
+ * Note: This creates new JSX elements each call. For better performance,
9
+ * renderers should use context.renderChildren within useMemo.
10
+ */
11
+ export declare function renderChildren(childNodes: readonly UiNode[], context: UiRenderContext): ReactNode;
5
12
  export interface UiRendererProps {
6
13
  readonly store: UiStreamStore;
7
14
  readonly library: UiComponentLibrary;
@@ -11,4 +18,4 @@ export interface UiRendererProps {
11
18
  readonly client?: IkonClient;
12
19
  readonly video?: IkonVideoPlayback;
13
20
  }
14
- export declare function UiRenderer({ store, library, viewId, emptyFallback, onAction, client, video }: UiRendererProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
21
+ export declare const UiRenderer: import('react').NamedExoticComponent<UiRendererProps>;
@@ -0,0 +1,13 @@
1
+ import { UiStreamStore } from '../../../sdk-ui/src/index.ts';
2
+ interface RootViewState {
3
+ rootViewId: string | undefined;
4
+ rootNodeId: string | undefined;
5
+ }
6
+ /**
7
+ * Hook that only re-renders when the root view structure changes.
8
+ * Unlike useUiStore, this does NOT re-render on every node change.
9
+ * This is critical for performance - the UiRenderer should only re-render
10
+ * when the root view changes, not when individual nodes update.
11
+ */
12
+ export declare function useRootView(store: UiStreamStore, viewId?: string): RootViewState;
13
+ export {};
@@ -0,0 +1,11 @@
1
+ import { UiStreamStore } from '../../../sdk-ui/src/index.ts';
2
+ import { UiNode } from './types';
3
+ /**
4
+ * Hook for subscribing to a specific node in the UI store.
5
+ * Only re-renders when this specific node changes, not when other nodes change.
6
+ *
7
+ * @param store - The UiStreamStore instance
8
+ * @param nodeId - The ID of the node to subscribe to
9
+ * @returns The UiNode or undefined if not found
10
+ */
11
+ export declare function useUiNode(store: UiStreamStore, nodeId: string): UiNode | undefined;
package/surface.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { UIStreamCategories } from '../../../shared/generated/src/index.ts';
1
+ import { UIStreamCategories } from '../../../shared/protocol/src/index.ts';
2
2
  import { UiStreamStore } from '../../sdk-ui/src/index.ts';
3
3
  import { UiComponentLibrary } from './renderer';
4
4
  import { IkonClient, IkonVideoPlayback } from '../../sdk/src/index.ts';
@@ -13,9 +13,8 @@ export interface IkonUiSurfaceProps {
13
13
  stores: ReadonlyMap<string, IkonUiStoreEntry>;
14
14
  library: UiComponentLibrary;
15
15
  category?: IkonUiCategory;
16
- version?: number;
17
16
  onAction?: (actionId: string, payload?: string) => void;
18
17
  client?: IkonClient;
19
18
  video?: IkonVideoPlayback;
20
19
  }
21
- export declare function IkonUiSurface({ stores, library, category, version, onAction, client, video }: IkonUiSurfaceProps): import("react/jsx-runtime").JSX.Element | null;
20
+ export declare const IkonUiSurface: import('react').NamedExoticComponent<IkonUiSurfaceProps>;
@@ -0,0 +1,10 @@
1
+ import { IkonUi } from './ikon-ui';
2
+ import { IkonUiStoreEntry } from './surface';
3
+ /**
4
+ * Hook that subscribes to IkonUi store changes.
5
+ * Triggers re-renders when:
6
+ * - Stores are added/removed
7
+ * - A store transitions from empty to having valid data (rootViewId + views)
8
+ * Does NOT re-render on every node update within stores.
9
+ */
10
+ export declare function useIkonUiStores(ikonUi: IkonUi | null | undefined): ReadonlyMap<string, IkonUiStoreEntry> | undefined;