# zip-ai/0.0.4/src/utils/componentInstanceId.js

ZIP AI – AI Website Builder &amp; AI Agent (Beta), version 0.0.4. 37 lines.

- Page: https://pluginprobe.com/plugins/zip-ai/0.0.4/code/src/utils/componentInstanceId.js
- Raw: https://pluginprobe.com/plugins/zip-ai/0.0.4/raw/src/utils/componentInstanceId.js
- Modified: 2026-07-02T12:36:30+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/zip-ai/0.0.4/code/src/utils/componentInstanceId.js#L10-L20`.

```javascript
/**
 * Deterministic instance ID resolver for inline components.
 *
 * The same componentType + props must produce the same instanceId in three
 * render paths (live SSE, persisted history, pending_component re-injection)
 * so the per-instance state in `useComponentStateStore` (resolved /
 * superseded / submitted values) survives reload.
 *
 * Priority: explicit `instance_id` > `call_id` (per-tool-call unique) >
 * `form_id` > derived key + props hash. call_id beats form_id because the
 * brain reuses form_id values across distinct tool calls (e.g. two smart-
 * forms with form_id "website-batch-1" in different turns), which would
 * otherwise collide on submitted state.
 */

function stablePropsHash(props) {
    try {
        const str = JSON.stringify(props);
        let hash = 5381;
        for (let i = 0; i < str.length; i += 1) {
            hash = ((hash << 5) + hash) + str.charCodeAt(i);
            hash |= 0; // keep 32-bit
        }
        return Math.abs(hash).toString(36);
    } catch {
        return '0';
    }
}

export function resolveComponentInstanceId(componentType, props = {}) {
    if (props.instance_id) return props.instance_id;
    if (props.call_id) return props.call_id;
    if (props.form_id) return `${props.form_id}-${stablePropsHash(props)}`;
    const derivedKey = props.brief?.business_name || props.title || props.action || 'default';
    return `${componentType}-${derivedKey}-${stablePropsHash(props)}`;
}

```
