@cellarnode/ui 0.186.0 → 0.188.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.
Files changed (129) hide show
  1. package/dist/brand/brand-assets-api.d.ts +58 -0
  2. package/dist/brand/brand-assets-api.d.ts.map +1 -0
  3. package/dist/brand/brand-assets-api.js +160 -0
  4. package/dist/brand/brand-assets-api.js.map +1 -0
  5. package/dist/brand/brand-generation-api.d.ts +44 -0
  6. package/dist/brand/brand-generation-api.d.ts.map +1 -0
  7. package/dist/brand/brand-generation-api.js +2 -0
  8. package/dist/brand/brand-generation-api.js.map +1 -0
  9. package/dist/brand/brand-generation-client.d.ts +36 -0
  10. package/dist/brand/brand-generation-client.d.ts.map +1 -0
  11. package/dist/brand/brand-generation-client.js +107 -0
  12. package/dist/brand/brand-generation-client.js.map +1 -0
  13. package/dist/brand/brand-generation-copy.d.ts +44 -0
  14. package/dist/brand/brand-generation-copy.d.ts.map +1 -0
  15. package/dist/brand/brand-generation-copy.js +70 -0
  16. package/dist/brand/brand-generation-copy.js.map +1 -0
  17. package/dist/brand/brand-generation-fixtures.d.ts +32 -0
  18. package/dist/brand/brand-generation-fixtures.d.ts.map +1 -0
  19. package/dist/brand/brand-generation-fixtures.js +88 -0
  20. package/dist/brand/brand-generation-fixtures.js.map +1 -0
  21. package/dist/brand/brand-generation-flow.d.ts +34 -0
  22. package/dist/brand/brand-generation-flow.d.ts.map +1 -0
  23. package/dist/brand/brand-generation-flow.js +34 -0
  24. package/dist/brand/brand-generation-flow.js.map +1 -0
  25. package/dist/brand/brand-generation-keys.d.ts +16 -0
  26. package/dist/brand/brand-generation-keys.d.ts.map +1 -0
  27. package/dist/brand/brand-generation-keys.js +16 -0
  28. package/dist/brand/brand-generation-keys.js.map +1 -0
  29. package/dist/brand/brand-generation-progress.d.ts +27 -0
  30. package/dist/brand/brand-generation-progress.d.ts.map +1 -0
  31. package/dist/brand/brand-generation-progress.js +61 -0
  32. package/dist/brand/brand-generation-progress.js.map +1 -0
  33. package/dist/brand/brand-generation-recovery-error.d.ts +8 -0
  34. package/dist/brand/brand-generation-recovery-error.d.ts.map +1 -0
  35. package/dist/brand/brand-generation-recovery-error.js +7 -0
  36. package/dist/brand/brand-generation-recovery-error.js.map +1 -0
  37. package/dist/brand/brand-generation-response.d.ts +86 -0
  38. package/dist/brand/brand-generation-response.d.ts.map +1 -0
  39. package/dist/brand/brand-generation-response.js +261 -0
  40. package/dist/brand/brand-generation-response.js.map +1 -0
  41. package/dist/brand/brand-generation-sse-parser.d.ts +14 -0
  42. package/dist/brand/brand-generation-sse-parser.d.ts.map +1 -0
  43. package/dist/brand/brand-generation-sse-parser.js +92 -0
  44. package/dist/brand/brand-generation-sse-parser.js.map +1 -0
  45. package/dist/brand/brand-generation-start.d.ts +49 -0
  46. package/dist/brand/brand-generation-start.d.ts.map +1 -0
  47. package/dist/brand/brand-generation-start.js +48 -0
  48. package/dist/brand/brand-generation-start.js.map +1 -0
  49. package/dist/brand/brand-generation-steps.d.ts +4 -0
  50. package/dist/brand/brand-generation-steps.d.ts.map +1 -0
  51. package/dist/brand/brand-generation-steps.js +29 -0
  52. package/dist/brand/brand-generation-steps.js.map +1 -0
  53. package/dist/brand/brand-generation-surface.d.ts +50 -0
  54. package/dist/brand/brand-generation-surface.d.ts.map +1 -0
  55. package/dist/brand/brand-generation-surface.js +25 -0
  56. package/dist/brand/brand-generation-surface.js.map +1 -0
  57. package/dist/brand/brand-generation-url.d.ts +6 -0
  58. package/dist/brand/brand-generation-url.d.ts.map +1 -0
  59. package/dist/brand/brand-generation-url.js +4 -0
  60. package/dist/brand/brand-generation-url.js.map +1 -0
  61. package/dist/brand/brand-image-chooser.d.ts +3 -1
  62. package/dist/brand/brand-image-chooser.d.ts.map +1 -1
  63. package/dist/brand/brand-image-chooser.js +7 -1
  64. package/dist/brand/brand-image-chooser.js.map +1 -1
  65. package/dist/brand/brand-image-choosers.d.ts +37 -0
  66. package/dist/brand/brand-image-choosers.d.ts.map +1 -0
  67. package/dist/brand/brand-image-choosers.js +76 -0
  68. package/dist/brand/brand-image-choosers.js.map +1 -0
  69. package/dist/brand/brand-workspace-change-notice.d.ts +20 -0
  70. package/dist/brand/brand-workspace-change-notice.d.ts.map +1 -0
  71. package/dist/brand/brand-workspace-change-notice.js +19 -0
  72. package/dist/brand/brand-workspace-change-notice.js.map +1 -0
  73. package/dist/brand/index.d.ts +37 -0
  74. package/dist/brand/index.d.ts.map +1 -1
  75. package/dist/brand/index.js +29 -0
  76. package/dist/brand/index.js.map +1 -1
  77. package/dist/brand/resume-brand-generation.d.ts +17 -0
  78. package/dist/brand/resume-brand-generation.d.ts.map +1 -0
  79. package/dist/brand/resume-brand-generation.js +22 -0
  80. package/dist/brand/resume-brand-generation.js.map +1 -0
  81. package/dist/brand/use-brand-generation-discovery.d.ts +14 -0
  82. package/dist/brand/use-brand-generation-discovery.d.ts.map +1 -0
  83. package/dist/brand/use-brand-generation-discovery.js +61 -0
  84. package/dist/brand/use-brand-generation-discovery.js.map +1 -0
  85. package/dist/brand/use-brand-generation-transport.d.ts +16 -0
  86. package/dist/brand/use-brand-generation-transport.d.ts.map +1 -0
  87. package/dist/brand/use-brand-generation-transport.js +182 -0
  88. package/dist/brand/use-brand-generation-transport.js.map +1 -0
  89. package/dist/brand/use-brand-generation.d.ts +35 -0
  90. package/dist/brand/use-brand-generation.d.ts.map +1 -0
  91. package/dist/brand/use-brand-generation.js +225 -0
  92. package/dist/brand/use-brand-generation.js.map +1 -0
  93. package/dist/brand/use-brand-image-operation-result.d.ts +43 -0
  94. package/dist/brand/use-brand-image-operation-result.d.ts.map +1 -0
  95. package/dist/brand/use-brand-image-operation-result.js +162 -0
  96. package/dist/brand/use-brand-image-operation-result.js.map +1 -0
  97. package/dist/brand/use-brand-profile-acceptance.d.ts +38 -0
  98. package/dist/brand/use-brand-profile-acceptance.d.ts.map +1 -0
  99. package/dist/brand/use-brand-profile-acceptance.js +84 -0
  100. package/dist/brand/use-brand-profile-acceptance.js.map +1 -0
  101. package/dist/brand/use-brand-public-visibility.d.ts +59 -0
  102. package/dist/brand/use-brand-public-visibility.d.ts.map +1 -0
  103. package/dist/brand/use-brand-public-visibility.js +69 -0
  104. package/dist/brand/use-brand-public-visibility.js.map +1 -0
  105. package/dist/brand/use-brand-workspace-concurrency.d.ts +132 -0
  106. package/dist/brand/use-brand-workspace-concurrency.d.ts.map +1 -0
  107. package/dist/brand/use-brand-workspace-concurrency.js +255 -0
  108. package/dist/brand/use-brand-workspace-concurrency.js.map +1 -0
  109. package/dist/brand/use-brand-workspace-image-candidates.d.ts +19 -0
  110. package/dist/brand/use-brand-workspace-image-candidates.d.ts.map +1 -0
  111. package/dist/brand/use-brand-workspace-image-candidates.js +39 -0
  112. package/dist/brand/use-brand-workspace-image-candidates.js.map +1 -0
  113. package/dist/brand/use-org-scoped-state.d.ts +3 -0
  114. package/dist/brand/use-org-scoped-state.d.ts.map +1 -0
  115. package/dist/brand/use-org-scoped-state.js +22 -0
  116. package/dist/brand/use-org-scoped-state.js.map +1 -0
  117. package/dist/components/multi-step-loader.d.ts +4 -0
  118. package/dist/components/multi-step-loader.d.ts.map +1 -1
  119. package/dist/components/multi-step-loader.js +4 -3
  120. package/dist/components/multi-step-loader.js.map +1 -1
  121. package/dist/moderation/moderation-event.d.ts +2 -0
  122. package/dist/moderation/moderation-event.d.ts.map +1 -1
  123. package/dist/moderation/moderation-event.js +7 -0
  124. package/dist/moderation/moderation-event.js.map +1 -1
  125. package/dist/moderation/moderation-store.d.ts.map +1 -1
  126. package/dist/moderation/moderation-store.js +4 -2
  127. package/dist/moderation/moderation-store.js.map +1 -1
  128. package/dist/realtime/job-status/schemas.d.ts +2 -2
  129. package/package.json +1 -1
@@ -0,0 +1,16 @@
1
+ import type { BrandGenerationApi, BrandGenerationStreamConfig } from "./brand-generation-api.js";
2
+ import type { BrandGenerationJobStatus as JobStatus } from "./brand-generation-response.js";
3
+ import { type BrandGenerationUpdate } from "./brand-generation-sse-parser.js";
4
+ export type { BrandGenerationUpdate } from "./brand-generation-sse-parser.js";
5
+ interface TransportOptions {
6
+ api: Pick<BrandGenerationApi, "getStatus">;
7
+ stream: BrandGenerationStreamConfig;
8
+ onUpdate: (data: BrandGenerationUpdate) => void;
9
+ onDegraded: () => void;
10
+ isTerminal: (status: JobStatus | undefined) => boolean;
11
+ }
12
+ export declare function useBrandGenerationTransport({ api, stream, onUpdate, onDegraded, isTerminal, }: TransportOptions): {
13
+ cleanup: () => void;
14
+ connect: (jobId: string) => Promise<void>;
15
+ };
16
+ //# sourceMappingURL=use-brand-generation-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-brand-generation-transport.d.ts","sourceRoot":"","sources":["../../src/brand/use-brand-generation-transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,KAAK,EAAE,wBAAwB,IAAI,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAS3E,UAAU,gBAAgB;IACxB,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,EAAE,2BAA2B,CAAC;IACpC,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAChD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,KAAK,OAAO,CAAC;CACxD;AAED,wBAAgB,2BAA2B,CAAC,EAC1C,GAAG,EACH,MAAM,EACN,QAAQ,EACR,UAAU,EACV,UAAU,GACX,EAAE,gBAAgB;;qBA8DD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;EAwHvC"}
@@ -0,0 +1,182 @@
1
+ import { useCallback, useRef } from "react";
2
+ import { dataPayload, parseSseUpdate, } from "./brand-generation-sse-parser.js";
3
+ const DEFAULT_SSE_IDLE_TIMEOUT_MS = 15_000;
4
+ const DEFAULT_POLL_INTERVAL_MS = 2000;
5
+ function errorType(error) {
6
+ return error instanceof Error ? error.name : "UnknownError";
7
+ }
8
+ export function useBrandGenerationTransport({ api, stream, onUpdate, onDegraded, isTerminal, }) {
9
+ // `api`/`stream` are read through refs so `connect`/`cleanup` keep a stable
10
+ // identity even when a consumer passes fresh object literals each render.
11
+ const apiRef = useRef(api);
12
+ apiRef.current = api;
13
+ const streamRef = useRef(stream);
14
+ streamRef.current = stream;
15
+ const pollIntervalRef = useRef(null);
16
+ const idleTimeoutRef = useRef(null);
17
+ const abortControllerRef = useRef(null);
18
+ const connectionGenerationRef = useRef(0);
19
+ const cleanup = useCallback(() => {
20
+ connectionGenerationRef.current += 1;
21
+ abortControllerRef.current?.abort();
22
+ abortControllerRef.current = null;
23
+ if (idleTimeoutRef.current !== null) {
24
+ window.clearTimeout(idleTimeoutRef.current.timerId);
25
+ idleTimeoutRef.current = null;
26
+ }
27
+ if (pollIntervalRef.current !== null) {
28
+ window.clearInterval(pollIntervalRef.current);
29
+ pollIntervalRef.current = null;
30
+ }
31
+ }, []);
32
+ const emitUpdate = useCallback((data) => {
33
+ if (isTerminal(data.status))
34
+ cleanup();
35
+ onUpdate(data);
36
+ }, [cleanup, isTerminal, onUpdate]);
37
+ const startPolling = useCallback((jobId) => {
38
+ cleanup();
39
+ const generation = connectionGenerationRef.current;
40
+ onDegraded();
41
+ const poll = async () => {
42
+ try {
43
+ const update = await apiRef.current.getStatus(jobId);
44
+ if (connectionGenerationRef.current === generation)
45
+ emitUpdate(update);
46
+ }
47
+ catch (error) {
48
+ console.warn("[brand-generation] status poll failed; retrying", {
49
+ errorType: errorType(error),
50
+ });
51
+ }
52
+ };
53
+ void poll();
54
+ pollIntervalRef.current = window.setInterval(() => void poll(), streamRef.current.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
55
+ }, [cleanup, emitUpdate, onDegraded]);
56
+ const connect = useCallback(async (jobId) => {
57
+ cleanup();
58
+ const generation = connectionGenerationRef.current;
59
+ const isCurrent = () => connectionGenerationRef.current === generation;
60
+ try {
61
+ const config = streamRef.current;
62
+ const token = config.getAccessToken ? await config.getAccessToken() : undefined;
63
+ if (!isCurrent())
64
+ return;
65
+ // Bearer mode with no usable token (null or empty) degrades to polling,
66
+ // like producer; cookie mode (no `getAccessToken`) streams with
67
+ // credentials instead.
68
+ if (config.getAccessToken && !token) {
69
+ startPolling(jobId);
70
+ return;
71
+ }
72
+ const controller = new AbortController();
73
+ abortControllerRef.current = controller;
74
+ const clearIdleTimeout = () => {
75
+ const idleTimeout = idleTimeoutRef.current;
76
+ if (idleTimeout?.generation !== generation)
77
+ return;
78
+ window.clearTimeout(idleTimeout.timerId);
79
+ idleTimeoutRef.current = null;
80
+ };
81
+ const armIdleTimeout = () => {
82
+ clearIdleTimeout();
83
+ const timerId = window.setTimeout(() => {
84
+ const idleTimeout = idleTimeoutRef.current;
85
+ if (idleTimeout?.generation !== generation || idleTimeout.timerId !== timerId)
86
+ return;
87
+ idleTimeoutRef.current = null;
88
+ if (!isCurrent())
89
+ return;
90
+ controller.abort();
91
+ startPolling(jobId);
92
+ }, config.idleTimeoutMs ?? DEFAULT_SSE_IDLE_TIMEOUT_MS);
93
+ idleTimeoutRef.current = { generation, timerId };
94
+ };
95
+ armIdleTimeout();
96
+ const doFetch = config.fetch ?? fetch;
97
+ const response = await doFetch(`${config.baseUrl.replace(/\/+$/, "")}/brand-profiles/generate/${encodeURIComponent(jobId)}/stream`, {
98
+ headers: {
99
+ Accept: "text/event-stream",
100
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
101
+ },
102
+ ...(token ? {} : { credentials: "include" }),
103
+ signal: controller.signal,
104
+ });
105
+ if (!isCurrent()) {
106
+ controller.abort();
107
+ return;
108
+ }
109
+ if (!response.ok) {
110
+ startPolling(jobId);
111
+ return;
112
+ }
113
+ const reader = response.body?.getReader();
114
+ if (!reader) {
115
+ startPolling(jobId);
116
+ return;
117
+ }
118
+ const decoder = new TextDecoder();
119
+ let buffer = "";
120
+ let terminalSeen = false;
121
+ try {
122
+ while (true) {
123
+ const { done, value } = await reader.read();
124
+ clearIdleTimeout();
125
+ if (!isCurrent())
126
+ return;
127
+ if (done) {
128
+ if (!terminalSeen)
129
+ startPolling(jobId);
130
+ return;
131
+ }
132
+ armIdleTimeout();
133
+ buffer += decoder.decode(value, { stream: true });
134
+ let boundary = buffer.search(/\r?\n\r?\n/);
135
+ while (boundary !== -1) {
136
+ const chunk = buffer.slice(0, boundary);
137
+ const separator = buffer.slice(boundary).match(/^\r?\n\r?\n/)?.[0] ?? "\n\n";
138
+ buffer = buffer.slice(boundary + separator.length);
139
+ const payload = dataPayload(chunk);
140
+ if (payload !== null) {
141
+ const data = parseSseUpdate(payload);
142
+ if (data) {
143
+ const terminal = isTerminal(data.status);
144
+ if (terminal)
145
+ terminalSeen = true;
146
+ emitUpdate(data);
147
+ if (terminal)
148
+ return;
149
+ }
150
+ }
151
+ boundary = buffer.search(/\r?\n\r?\n/);
152
+ }
153
+ }
154
+ }
155
+ catch (error) {
156
+ if (!isCurrent())
157
+ return;
158
+ if (error instanceof Error && error.name === "AbortError")
159
+ return;
160
+ console.warn("[brand-generation] SSE read failed; polling", {
161
+ errorType: errorType(error),
162
+ });
163
+ startPolling(jobId);
164
+ }
165
+ finally {
166
+ clearIdleTimeout();
167
+ }
168
+ }
169
+ catch (error) {
170
+ if (!isCurrent())
171
+ return;
172
+ if (error instanceof Error && error.name === "AbortError")
173
+ return;
174
+ console.warn("[brand-generation] SSE connection failed; polling", {
175
+ errorType: errorType(error),
176
+ });
177
+ startPolling(jobId);
178
+ }
179
+ }, [cleanup, emitUpdate, isTerminal, startPolling]);
180
+ return { cleanup, connect };
181
+ }
182
+ //# sourceMappingURL=use-brand-generation-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-brand-generation-transport.js","sourceRoot":"","sources":["../../src/brand/use-brand-generation-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type QueryKey } from "@tanstack/react-query";
2
+ import type { BrandGenerationApi, BrandGenerationStreamConfig } from "./brand-generation-api.js";
3
+ import type { BrandGenerationContext, BrandGenerationJob } from "./brand-generation-response.js";
4
+ export interface UseBrandGenerationOptions {
5
+ /** Active org id. Every piece of generation state resets when it changes. */
6
+ readonly orgId: string;
7
+ /** The endpoint seam. See {@link BrandGenerationApi}. */
8
+ readonly api: BrandGenerationApi;
9
+ /** How the SSE stream authenticates. See {@link BrandGenerationStreamConfig}. */
10
+ readonly stream: BrandGenerationStreamConfig;
11
+ /**
12
+ * The consumer's brand-profile query key (prefix) for this org. It is
13
+ * invalidated when a job reaches a terminal state or is accepted, so the
14
+ * consumer's profile/draft queries refetch. Must not live under the
15
+ * `"brand-generation"` namespace.
16
+ */
17
+ readonly profileQueryKey: QueryKey;
18
+ }
19
+ export type UseBrandGenerationResult = ReturnType<typeof useBrandGeneration>;
20
+ export declare function useBrandGeneration({ orgId, api, stream, profileQueryKey, }: UseBrandGenerationOptions): {
21
+ job: BrandGenerationJob | null;
22
+ isGenerating: boolean;
23
+ isDiscoveringActive: boolean;
24
+ discoveryError: Error | null;
25
+ error: "start" | "resume" | "accept" | "cancel" | "prioritize" | null;
26
+ transportDegraded: boolean;
27
+ eligibility: import("./brand-generation-types.js").BrandGenerationEligibility | null;
28
+ start: (homepageUrl: string, context?: BrandGenerationContext) => Promise<void>;
29
+ resume: (jobId: string) => Promise<void>;
30
+ cancel: () => Promise<void>;
31
+ prioritizeUrl: (url: string) => Promise<void>;
32
+ accept: () => Promise<boolean>;
33
+ reset: () => void;
34
+ };
35
+ //# sourceMappingURL=use-brand-generation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-brand-generation.d.ts","sourceRoot":"","sources":["../../src/brand/use-brand-generation.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAM9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAS9F,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC;IACjC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC;CACpC;AAED,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE7E,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,GAAG,EACH,MAAM,EACN,eAAe,GAChB,EAAE,yBAAyB;;;;;;;;yBAwEQ,MAAM,YAAY,sBAAsB;oBAkHnD,MAAM;;yBA1EK,MAAM;;;EA8GzC"}
@@ -0,0 +1,225 @@
1
+ import { useEffect, useCallback, useRef } from "react";
2
+ import { useQueryClient } from "@tanstack/react-query";
3
+ import { brandGenerationKeys, isTerminalStatus, } from "./brand-generation-keys.js";
4
+ import { resumeBrandGeneration } from "./resume-brand-generation.js";
5
+ import { useBrandGenerationDiscovery } from "./use-brand-generation-discovery.js";
6
+ import { useBrandGenerationTransport, } from "./use-brand-generation-transport.js";
7
+ import { useOrgScopedState } from "./use-org-scoped-state.js";
8
+ export function useBrandGeneration({ orgId, api, stream, profileQueryKey, }) {
9
+ // Read through a ref so a fresh array literal each render cannot churn the callbacks below.
10
+ const profileKeyRef = useRef(profileQueryKey);
11
+ profileKeyRef.current = profileQueryKey;
12
+ const orgEpochRef = useRef(0);
13
+ const renderedOrgIdRef = useRef(orgId);
14
+ if (renderedOrgIdRef.current !== orgId) {
15
+ renderedOrgIdRef.current = orgId;
16
+ orgEpochRef.current += 1;
17
+ }
18
+ const orgEpoch = orgEpochRef.current;
19
+ const queryClient = useQueryClient();
20
+ const { activeQuery, activeJob, terminalQuery, terminalJob, eligibility: discoveryEligibility, needsTerminalHandoff, isDiscoveringActive, discoveryError, } = useBrandGenerationDiscovery(orgId, api, profileKeyRef);
21
+ const [job, setJob, updateJob] = useOrgScopedState(orgId, null);
22
+ const [dismissedTerminalJobId, setDismissedTerminalJobId] = useOrgScopedState(orgId, null);
23
+ const [isGenerating, setIsGenerating] = useOrgScopedState(orgId, false);
24
+ const [error, setError] = useOrgScopedState(orgId, null);
25
+ const [transportDegraded, setTransportDegraded] = useOrgScopedState(orgId, false);
26
+ const clearGenerationState = useCallback(() => {
27
+ setJob(null);
28
+ setIsGenerating(false);
29
+ setError(null);
30
+ setTransportDegraded(false);
31
+ }, [setError, setIsGenerating, setJob, setTransportDegraded]);
32
+ const markTransportDegraded = useCallback(() => {
33
+ if (orgEpochRef.current === orgEpoch)
34
+ setTransportDegraded(true);
35
+ }, [orgEpoch, setTransportDegraded]);
36
+ const invalidateGenerationHandoff = useCallback(() => {
37
+ if (!orgId)
38
+ return;
39
+ queryClient.setQueryData(brandGenerationKeys.active(orgId), null);
40
+ void Promise.all([
41
+ queryClient.invalidateQueries({ queryKey: brandGenerationKeys.active(orgId), exact: true }),
42
+ queryClient.invalidateQueries({ queryKey: profileKeyRef.current }),
43
+ ]);
44
+ }, [orgId, queryClient]);
45
+ const handleUpdate = useCallback((data) => {
46
+ if (orgEpochRef.current !== orgEpoch)
47
+ return;
48
+ const { jobId, ...update } = data;
49
+ updateJob((currentJob) => {
50
+ if (!currentJob)
51
+ return currentJob;
52
+ return { ...currentJob, ...update, id: jobId || update.id || currentJob.id };
53
+ });
54
+ if (isTerminalStatus(data.status)) {
55
+ setIsGenerating(false);
56
+ invalidateGenerationHandoff();
57
+ }
58
+ }, [invalidateGenerationHandoff, orgEpoch, setIsGenerating, updateJob]);
59
+ const { cleanup, connect: connectSSE } = useBrandGenerationTransport({
60
+ api,
61
+ stream,
62
+ onUpdate: handleUpdate,
63
+ onDegraded: markTransportDegraded,
64
+ isTerminal: isTerminalStatus,
65
+ });
66
+ // CEL-1679 contract §2: "Retry is a start with amended context" — no
67
+ // separate retry endpoint, so a retry calls this same function again with
68
+ // the operator's amended context from `BrandGenerationContextForm`.
69
+ const start = async (homepageUrl, context) => {
70
+ if (isDiscoveringActive || discoveryError !== null)
71
+ return;
72
+ const actionEpoch = orgEpoch;
73
+ try {
74
+ setError(null);
75
+ setTransportDegraded(false);
76
+ setDismissedTerminalJobId(null);
77
+ setIsGenerating(true);
78
+ const res = await api.start(homepageUrl, context);
79
+ if (orgEpochRef.current !== actionEpoch)
80
+ return;
81
+ setJob({
82
+ id: res.jobId,
83
+ workflowId: res.workflowId,
84
+ status: "pending",
85
+ progress: {},
86
+ error: null,
87
+ createdAt: new Date().toISOString(),
88
+ updatedAt: new Date().toISOString(),
89
+ });
90
+ connectSSE(res.jobId);
91
+ }
92
+ catch {
93
+ if (orgEpochRef.current !== actionEpoch)
94
+ return;
95
+ setIsGenerating(false);
96
+ setError("start");
97
+ }
98
+ };
99
+ const cancel = async () => {
100
+ if (!job?.id)
101
+ return;
102
+ const actionEpoch = orgEpoch;
103
+ try {
104
+ const res = await api.cancel(job.id);
105
+ if (orgEpochRef.current !== actionEpoch)
106
+ return;
107
+ handleUpdate(res);
108
+ }
109
+ catch {
110
+ if (orgEpochRef.current !== actionEpoch)
111
+ return;
112
+ setError("cancel");
113
+ }
114
+ };
115
+ const prioritizeUrl = async (url) => {
116
+ if (!job?.id)
117
+ return;
118
+ const actionEpoch = orgEpoch;
119
+ try {
120
+ const res = await api.prioritizeUrl(job.id, url);
121
+ if (orgEpochRef.current !== actionEpoch)
122
+ return;
123
+ handleUpdate(res);
124
+ }
125
+ catch {
126
+ if (orgEpochRef.current !== actionEpoch)
127
+ return;
128
+ setError("prioritize");
129
+ }
130
+ };
131
+ const accept = async () => {
132
+ if (!job?.id)
133
+ return false;
134
+ const actionEpoch = orgEpoch;
135
+ try {
136
+ await api.accept(job.id);
137
+ if (orgEpochRef.current !== actionEpoch)
138
+ return false;
139
+ invalidateGenerationHandoff();
140
+ if (isTerminalStatus(job.status))
141
+ setDismissedTerminalJobId(job.id);
142
+ setJob(null);
143
+ return true;
144
+ }
145
+ catch {
146
+ if (orgEpochRef.current !== actionEpoch)
147
+ return false;
148
+ setError("accept");
149
+ return false;
150
+ }
151
+ };
152
+ const reset = () => {
153
+ cleanup();
154
+ if (job && isTerminalStatus(job.status))
155
+ setDismissedTerminalJobId(job.id);
156
+ clearGenerationState();
157
+ };
158
+ useEffect(() => cleanup, [cleanup]);
159
+ useEffect(() => {
160
+ cleanup();
161
+ }, [cleanup, orgId]);
162
+ useEffect(() => {
163
+ if (activeQuery.isFetching ||
164
+ (needsTerminalHandoff && terminalQuery.isFetching) ||
165
+ (!activeJob && (!terminalJob || terminalJob.id === dismissedTerminalJobId)) ||
166
+ job ||
167
+ isGenerating)
168
+ return;
169
+ setError(null);
170
+ setTransportDegraded(false);
171
+ setJob(activeJob ?? terminalJob ?? null);
172
+ if (activeJob) {
173
+ setIsGenerating(true);
174
+ void connectSSE(activeJob.id);
175
+ }
176
+ }, [
177
+ activeJob,
178
+ activeQuery.isFetching,
179
+ connectSSE,
180
+ isGenerating,
181
+ job,
182
+ dismissedTerminalJobId,
183
+ needsTerminalHandoff,
184
+ setError,
185
+ setIsGenerating,
186
+ setJob,
187
+ setTransportDegraded,
188
+ terminalJob,
189
+ terminalQuery.isFetching,
190
+ ]);
191
+ const resume = (jobId) => resumeBrandGeneration(jobId, {
192
+ api,
193
+ isCurrent: () => orgEpochRef.current === orgEpoch,
194
+ setError,
195
+ setIsGenerating,
196
+ setTransportDegraded,
197
+ setJob,
198
+ handleUpdate,
199
+ connect: connectSSE,
200
+ });
201
+ return {
202
+ job,
203
+ isGenerating,
204
+ isDiscoveringActive,
205
+ discoveryError,
206
+ error,
207
+ transportDegraded,
208
+ // CEL-1682 (contracts §2): prefers the tracked job's own eligibility
209
+ // (populated by GET /:jobId via `resume`, and by GET /active when a job
210
+ // is active — the freshest snapshot once a specific job is in view),
211
+ // falling back to the discovery-level snapshot from
212
+ // `useBrandGenerationDiscovery`'s unconditional `/active` read. This is
213
+ // the fix for the confirmed idle-state gap: `getActiveBrandGeneration`
214
+ // no longer collapses `{ job: null, eligibility }` to a bare `null`, so
215
+ // the cooldown banner has data even when nothing is running.
216
+ eligibility: job?.eligibility ?? discoveryEligibility,
217
+ start,
218
+ resume,
219
+ cancel,
220
+ prioritizeUrl,
221
+ accept,
222
+ reset,
223
+ };
224
+ }
225
+ //# sourceMappingURL=use-brand-generation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-brand-generation.js","sourceRoot":"","sources":["../../src/brand/use-brand-generation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type ModerationPersistedRead, type ModerationSubjectMatch } from "../moderation/index.js";
2
+ import type { BrandImageOperationResult } from "./brand-image-chooser-types.js";
3
+ export interface BrandImageOperationController {
4
+ /** `null` when no operation has started yet — the chooser's own idle
5
+ * default. */
6
+ readonly operationResult: BrandImageOperationResult | null;
7
+ /**
8
+ * Call once `onApply`'s upload/candidate-select call has been accepted by
9
+ * the backend: a caller-generated id that correlates a later verdict back
10
+ * to THIS call (never a previous operation on the same subject slot), and
11
+ * the subject to watch. The subject is passed HERE rather than fixed at
12
+ * the hook call site because it depends on which slot the upload actually
13
+ * landed in — a candidate's OWN role can route it to a different slot than
14
+ * the chooser instance's own target (e.g. a favicon-role candidate picked
15
+ * through the "profile picture" chooser still saves to the favicon slot;
16
+ * see `candidateAssetSlot` in `useBrandImageCandidates.ts`). Also marks the
17
+ * subject "checking" in the shared moderation store so every OTHER surface
18
+ * watching it (e.g. `BrandAssetsSection`'s `ModerationSurfaceNotice`) sees
19
+ * it too.
20
+ */
21
+ readonly startOperation: (operationId: string, subject: ModerationSubjectMatch, startSeq?: number) => void;
22
+ /**
23
+ * Call BEFORE issuing the upload request and pass the result to
24
+ * `startOperation`. The backend can publish a verdict for the asset while
25
+ * the upload's HTTP response is still in flight; without this snapshot that
26
+ * event is gated out as "pre-existing" and the operation hangs at
27
+ * `checking` until it gives up.
28
+ */
29
+ readonly beginOperation: () => number;
30
+ /** Drops tracking — e.g. when the chooser is dismissed/closed. */
31
+ readonly reset: () => void;
32
+ }
33
+ /**
34
+ * Owns the chooser's current upload identity and adapts the shared moderation
35
+ * operation (including its exact-asset durable read) to the chooser result.
36
+ */
37
+ export declare function useBrandImageOperationResult(
38
+ /**
39
+ * The durable, asset-id-keyed read (`BrandAssetsApi.fetchModeration`) used
40
+ * when no live verdict event arrives.
41
+ */
42
+ fetchModeration: (profileId: string, assetId: string) => Promise<ModerationPersistedRead | null>): BrandImageOperationController;
43
+ //# sourceMappingURL=use-brand-image-operation-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-brand-image-operation-result.d.ts","sourceRoot":"","sources":["../../src/brand/use-brand-image-operation-result.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,yBAAyB,EAE1B,MAAM,6BAA6B,CAAC;AAmCrC,MAAM,WAAW,6BAA6B;IAC5C;kBACc;IACd,QAAQ,CAAC,eAAe,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC3D;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,cAAc,EAAE,CACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,CAAC,EAAE,MAAM,KACd,IAAI,CAAC;IACV;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,MAAM,CAAC;IACtC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,4BAA4B;AAC1C;;;GAGG;AACH,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAC/F,6BAA6B,CA0I/B"}