@civitai/blocks-react 0.56.0 → 0.57.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 (262) hide show
  1. package/README.md +34 -2
  2. package/dist/api/generationResources.d.ts +4 -3
  3. package/dist/hooks/returnTypeLedger.d.ts +2 -0
  4. package/dist/hooks/returnTypeLedger.js +2 -0
  5. package/dist/hooks/useAppStorage.js +2 -2
  6. package/dist/hooks/useAppWorkflows.d.ts +5 -2
  7. package/dist/hooks/useAppWorkflows.js +18 -7
  8. package/dist/hooks/useBlockAnalytics.d.ts +5 -3
  9. package/dist/hooks/useBlockAnalytics.js +1 -1
  10. package/dist/hooks/useBlockBreakpoint.d.ts +7 -1
  11. package/dist/hooks/useBlockContext.d.ts +13 -2
  12. package/dist/hooks/useBlockContext.js +1 -1
  13. package/dist/hooks/useBlockResize.d.ts +7 -1
  14. package/dist/hooks/useBlockResize.js +1 -1
  15. package/dist/hooks/useBlockSettings.d.ts +6 -1
  16. package/dist/hooks/useBlockTheme.d.ts +6 -1
  17. package/dist/hooks/useBlockToken.d.ts +8 -3
  18. package/dist/hooks/useBlockToken.js +2 -2
  19. package/dist/hooks/useBuzzAccounts.d.ts +3 -2
  20. package/dist/hooks/useBuzzAccounts.js +16 -15
  21. package/dist/hooks/useBuzzBalance.d.ts +3 -2
  22. package/dist/hooks/useBuzzBalance.js +16 -18
  23. package/dist/hooks/useBuzzPurchase.d.ts +8 -6
  24. package/dist/hooks/useBuzzPurchase.js +3 -3
  25. package/dist/hooks/useBuzzTransactions.d.ts +4 -2
  26. package/dist/hooks/useBuzzTransactions.js +16 -15
  27. package/dist/hooks/useBuzzWorkflow.d.ts +71 -28
  28. package/dist/hooks/useBuzzWorkflow.js +31 -17
  29. package/dist/hooks/useCheckpointPicker.d.ts +18 -16
  30. package/dist/hooks/useCheckpointPicker.js +3 -3
  31. package/dist/hooks/useCivitaiNavigate.d.ts +5 -3
  32. package/dist/hooks/useCivitaiNavigate.js +1 -1
  33. package/dist/hooks/useCollectionFollow.js +4 -4
  34. package/dist/hooks/useConsentUnavailable.js +2 -2
  35. package/dist/hooks/useCreatePostFromApp.js +4 -4
  36. package/dist/hooks/useDailyCompensation.d.ts +4 -2
  37. package/dist/hooks/useDailyCompensation.js +17 -15
  38. package/dist/hooks/useDirectLoad.d.ts +7 -1
  39. package/dist/hooks/useDirectLoad.js +1 -1
  40. package/dist/hooks/useDomainMaturity.d.ts +6 -2
  41. package/dist/hooks/useGatedImages.d.ts +8 -0
  42. package/dist/hooks/useGatedImages.js +10 -2
  43. package/dist/hooks/useGenerationResources.d.ts +5 -3
  44. package/dist/hooks/useHostOrigin.d.ts +7 -1
  45. package/dist/hooks/useHostOrigin.js +1 -1
  46. package/dist/hooks/useImageUpload.d.ts +44 -17
  47. package/dist/hooks/useImageUpload.js +24 -4
  48. package/dist/hooks/usePublishGenerationOutputs.js +4 -4
  49. package/dist/hooks/useRequestConsent.d.ts +7 -5
  50. package/dist/hooks/useRequestConsent.js +1 -1
  51. package/dist/hooks/useRequestSequencer.d.ts +71 -0
  52. package/dist/hooks/useRequestSequencer.js +28 -0
  53. package/dist/hooks/useRequestSignIn.d.ts +7 -5
  54. package/dist/hooks/useRequestSignIn.js +1 -1
  55. package/dist/hooks/useResourcePicker.d.ts +16 -14
  56. package/dist/hooks/useResourcePicker.js +3 -3
  57. package/dist/hooks/useSaveImage.js +2 -2
  58. package/dist/hooks/useSharedStorage.js +2 -2
  59. package/dist/hooks/useTip.js +1 -1
  60. package/dist/hooks/useTipAllowance.d.ts +13 -1
  61. package/dist/hooks/useTipAllowance.js +49 -11
  62. package/dist/hooks/useViewer.d.ts +3 -2
  63. package/dist/hooks/useViewer.js +16 -18
  64. package/dist/hooks/useWildcardPack.d.ts +3 -1
  65. package/dist/hooks/useWildcardPack.js +19 -14
  66. package/dist/index.d.ts +30 -14
  67. package/dist/index.js +7 -7
  68. package/dist/internal/consentRefusalLatch.d.ts +1 -1
  69. package/dist/internal/consentRefusalLatch.js +1 -1
  70. package/dist/internal/liveHost.d.ts +63 -11
  71. package/dist/internal/liveHost.js +240 -37
  72. package/dist/internal/mockHost.js +16 -15
  73. package/dist/internal/pickerOverlay.d.ts +52 -4
  74. package/dist/internal/pickerOverlay.js +14 -3
  75. package/dist/testing.d.ts +1 -1
  76. package/dist/testing.js +1 -1
  77. package/dist/{internal → transport}/iframeTransport.d.ts +43 -5
  78. package/dist/{internal → transport}/iframeTransport.js +142 -12
  79. package/dist/transport/originMatcher.d.ts +92 -0
  80. package/dist/transport/originMatcher.js +222 -0
  81. package/dist/transport/requestId.d.ts +113 -0
  82. package/dist/transport/requestId.js +117 -0
  83. package/dist/{internal → transport}/validate.d.ts +34 -0
  84. package/dist/{internal → transport}/validate.js +189 -48
  85. package/dist/ui/BlockGate.js +1 -1
  86. package/dist/ui/SettingsForm.d.ts +8 -2
  87. package/dist/ui/SettingsForm.js +49 -3
  88. package/package.json +7 -148
  89. package/dist/api/generationResources.d.ts.map +0 -1
  90. package/dist/api/generationResources.js.map +0 -1
  91. package/dist/hooks/SfwGate.d.ts.map +0 -1
  92. package/dist/hooks/SfwGate.js.map +0 -1
  93. package/dist/hooks/useAppStorage.d.ts.map +0 -1
  94. package/dist/hooks/useAppStorage.js.map +0 -1
  95. package/dist/hooks/useAppWorkflows.d.ts.map +0 -1
  96. package/dist/hooks/useAppWorkflows.js.map +0 -1
  97. package/dist/hooks/useBlockAnalytics.d.ts.map +0 -1
  98. package/dist/hooks/useBlockAnalytics.js.map +0 -1
  99. package/dist/hooks/useBlockBreakpoint.d.ts.map +0 -1
  100. package/dist/hooks/useBlockBreakpoint.js.map +0 -1
  101. package/dist/hooks/useBlockContext.d.ts.map +0 -1
  102. package/dist/hooks/useBlockContext.js.map +0 -1
  103. package/dist/hooks/useBlockResize.d.ts.map +0 -1
  104. package/dist/hooks/useBlockResize.js.map +0 -1
  105. package/dist/hooks/useBlockSettings.d.ts.map +0 -1
  106. package/dist/hooks/useBlockSettings.js.map +0 -1
  107. package/dist/hooks/useBlockTheme.d.ts.map +0 -1
  108. package/dist/hooks/useBlockTheme.js.map +0 -1
  109. package/dist/hooks/useBlockToken.d.ts.map +0 -1
  110. package/dist/hooks/useBlockToken.js.map +0 -1
  111. package/dist/hooks/useBuzzAccounts.d.ts.map +0 -1
  112. package/dist/hooks/useBuzzAccounts.js.map +0 -1
  113. package/dist/hooks/useBuzzBalance.d.ts.map +0 -1
  114. package/dist/hooks/useBuzzBalance.js.map +0 -1
  115. package/dist/hooks/useBuzzPurchase.d.ts.map +0 -1
  116. package/dist/hooks/useBuzzPurchase.js.map +0 -1
  117. package/dist/hooks/useBuzzTransactions.d.ts.map +0 -1
  118. package/dist/hooks/useBuzzTransactions.js.map +0 -1
  119. package/dist/hooks/useBuzzWorkflow.d.ts.map +0 -1
  120. package/dist/hooks/useBuzzWorkflow.js.map +0 -1
  121. package/dist/hooks/useCheckpointPicker.d.ts.map +0 -1
  122. package/dist/hooks/useCheckpointPicker.js.map +0 -1
  123. package/dist/hooks/useCivitaiNavigate.d.ts.map +0 -1
  124. package/dist/hooks/useCivitaiNavigate.js.map +0 -1
  125. package/dist/hooks/useCollectionFollow.d.ts.map +0 -1
  126. package/dist/hooks/useCollectionFollow.js.map +0 -1
  127. package/dist/hooks/useConsentUnavailable.d.ts.map +0 -1
  128. package/dist/hooks/useConsentUnavailable.js.map +0 -1
  129. package/dist/hooks/useCreatePostFromApp.d.ts.map +0 -1
  130. package/dist/hooks/useCreatePostFromApp.js.map +0 -1
  131. package/dist/hooks/useDailyCompensation.d.ts.map +0 -1
  132. package/dist/hooks/useDailyCompensation.js.map +0 -1
  133. package/dist/hooks/useDirectLoad.d.ts.map +0 -1
  134. package/dist/hooks/useDirectLoad.js.map +0 -1
  135. package/dist/hooks/useDomainMaturity.d.ts.map +0 -1
  136. package/dist/hooks/useDomainMaturity.js.map +0 -1
  137. package/dist/hooks/useGatedImages.d.ts.map +0 -1
  138. package/dist/hooks/useGatedImages.js.map +0 -1
  139. package/dist/hooks/useGenerationResources.d.ts.map +0 -1
  140. package/dist/hooks/useGenerationResources.js.map +0 -1
  141. package/dist/hooks/useHostOrigin.d.ts.map +0 -1
  142. package/dist/hooks/useHostOrigin.js.map +0 -1
  143. package/dist/hooks/useImageUpload.d.ts.map +0 -1
  144. package/dist/hooks/useImageUpload.js.map +0 -1
  145. package/dist/hooks/usePublishGenerationOutputs.d.ts.map +0 -1
  146. package/dist/hooks/usePublishGenerationOutputs.js.map +0 -1
  147. package/dist/hooks/useRequestConsent.d.ts.map +0 -1
  148. package/dist/hooks/useRequestConsent.js.map +0 -1
  149. package/dist/hooks/useRequestSignIn.d.ts.map +0 -1
  150. package/dist/hooks/useRequestSignIn.js.map +0 -1
  151. package/dist/hooks/useResourcePicker.d.ts.map +0 -1
  152. package/dist/hooks/useResourcePicker.js.map +0 -1
  153. package/dist/hooks/useSaveImage.d.ts.map +0 -1
  154. package/dist/hooks/useSaveImage.js.map +0 -1
  155. package/dist/hooks/useSharedStorage.d.ts.map +0 -1
  156. package/dist/hooks/useSharedStorage.js.map +0 -1
  157. package/dist/hooks/useTip.d.ts.map +0 -1
  158. package/dist/hooks/useTip.js.map +0 -1
  159. package/dist/hooks/useTipAllowance.d.ts.map +0 -1
  160. package/dist/hooks/useTipAllowance.js.map +0 -1
  161. package/dist/hooks/useViewer.d.ts.map +0 -1
  162. package/dist/hooks/useViewer.js.map +0 -1
  163. package/dist/hooks/useWildcardPack.d.ts.map +0 -1
  164. package/dist/hooks/useWildcardPack.js.map +0 -1
  165. package/dist/index.d.ts.map +0 -1
  166. package/dist/index.js.map +0 -1
  167. package/dist/internal/catalog.d.ts.map +0 -1
  168. package/dist/internal/catalog.js.map +0 -1
  169. package/dist/internal/consent.d.ts.map +0 -1
  170. package/dist/internal/consent.js.map +0 -1
  171. package/dist/internal/consentRefusalLatch.d.ts.map +0 -1
  172. package/dist/internal/consentRefusalLatch.js.map +0 -1
  173. package/dist/internal/detector.d.ts.map +0 -1
  174. package/dist/internal/detector.js.map +0 -1
  175. package/dist/internal/directLoad.d.ts.map +0 -1
  176. package/dist/internal/directLoad.js.map +0 -1
  177. package/dist/internal/iframeTransport.d.ts.map +0 -1
  178. package/dist/internal/iframeTransport.js.map +0 -1
  179. package/dist/internal/inlineTransport.d.ts.map +0 -1
  180. package/dist/internal/inlineTransport.js.map +0 -1
  181. package/dist/internal/liveHost.d.ts.map +0 -1
  182. package/dist/internal/liveHost.js.map +0 -1
  183. package/dist/internal/mockHost.d.ts.map +0 -1
  184. package/dist/internal/mockHost.js.map +0 -1
  185. package/dist/internal/originMatcher.d.ts +0 -28
  186. package/dist/internal/originMatcher.d.ts.map +0 -1
  187. package/dist/internal/originMatcher.js +0 -89
  188. package/dist/internal/originMatcher.js.map +0 -1
  189. package/dist/internal/pickerOverlay.d.ts.map +0 -1
  190. package/dist/internal/pickerOverlay.js.map +0 -1
  191. package/dist/internal/replyError.d.ts.map +0 -1
  192. package/dist/internal/replyError.js.map +0 -1
  193. package/dist/internal/requestTimeouts.d.ts.map +0 -1
  194. package/dist/internal/requestTimeouts.js.map +0 -1
  195. package/dist/internal/singleton.d.ts.map +0 -1
  196. package/dist/internal/singleton.js.map +0 -1
  197. package/dist/internal/transport.d.ts.map +0 -1
  198. package/dist/internal/transport.js.map +0 -1
  199. package/dist/internal/validate.d.ts.map +0 -1
  200. package/dist/internal/validate.js.map +0 -1
  201. package/dist/live.d.ts.map +0 -1
  202. package/dist/live.js.map +0 -1
  203. package/dist/testing.d.ts.map +0 -1
  204. package/dist/testing.js.map +0 -1
  205. package/dist/ui/Alert.d.ts.map +0 -1
  206. package/dist/ui/Alert.js.map +0 -1
  207. package/dist/ui/Badge.d.ts.map +0 -1
  208. package/dist/ui/Badge.js.map +0 -1
  209. package/dist/ui/BlockGate.d.ts.map +0 -1
  210. package/dist/ui/BlockGate.js.map +0 -1
  211. package/dist/ui/Button.d.ts.map +0 -1
  212. package/dist/ui/Button.js.map +0 -1
  213. package/dist/ui/Card.d.ts.map +0 -1
  214. package/dist/ui/Card.js.map +0 -1
  215. package/dist/ui/Collapse.d.ts.map +0 -1
  216. package/dist/ui/Collapse.js.map +0 -1
  217. package/dist/ui/FollowButton.d.ts.map +0 -1
  218. package/dist/ui/FollowButton.js.map +0 -1
  219. package/dist/ui/Group.d.ts.map +0 -1
  220. package/dist/ui/Group.js.map +0 -1
  221. package/dist/ui/Loader.d.ts.map +0 -1
  222. package/dist/ui/Loader.js.map +0 -1
  223. package/dist/ui/Modal.d.ts.map +0 -1
  224. package/dist/ui/Modal.js.map +0 -1
  225. package/dist/ui/NumberInput.d.ts.map +0 -1
  226. package/dist/ui/NumberInput.js.map +0 -1
  227. package/dist/ui/ReportButton.d.ts.map +0 -1
  228. package/dist/ui/ReportButton.js.map +0 -1
  229. package/dist/ui/ResourceCard.d.ts.map +0 -1
  230. package/dist/ui/ResourceCard.js.map +0 -1
  231. package/dist/ui/SegmentedControl.d.ts.map +0 -1
  232. package/dist/ui/SegmentedControl.js.map +0 -1
  233. package/dist/ui/Select.d.ts.map +0 -1
  234. package/dist/ui/Select.js.map +0 -1
  235. package/dist/ui/SettingsForm.d.ts.map +0 -1
  236. package/dist/ui/SettingsForm.js.map +0 -1
  237. package/dist/ui/Slider.d.ts.map +0 -1
  238. package/dist/ui/Slider.js.map +0 -1
  239. package/dist/ui/Stack.d.ts.map +0 -1
  240. package/dist/ui/Stack.js.map +0 -1
  241. package/dist/ui/TextInput.d.ts.map +0 -1
  242. package/dist/ui/TextInput.js.map +0 -1
  243. package/dist/ui/Textarea.d.ts.map +0 -1
  244. package/dist/ui/Textarea.js.map +0 -1
  245. package/dist/ui/TipButton.d.ts.map +0 -1
  246. package/dist/ui/TipButton.js.map +0 -1
  247. package/dist/ui/index.d.ts.map +0 -1
  248. package/dist/ui/index.js.map +0 -1
  249. package/dist/ui/styles.d.ts.map +0 -1
  250. package/dist/ui/styles.js.map +0 -1
  251. /package/dist/{internal → transport}/detector.d.ts +0 -0
  252. /package/dist/{internal → transport}/detector.js +0 -0
  253. /package/dist/{internal → transport}/directLoad.d.ts +0 -0
  254. /package/dist/{internal → transport}/directLoad.js +0 -0
  255. /package/dist/{internal → transport}/inlineTransport.d.ts +0 -0
  256. /package/dist/{internal → transport}/inlineTransport.js +0 -0
  257. /package/dist/{internal → transport}/requestTimeouts.d.ts +0 -0
  258. /package/dist/{internal → transport}/requestTimeouts.js +0 -0
  259. /package/dist/{internal → transport}/singleton.d.ts +0 -0
  260. /package/dist/{internal → transport}/singleton.js +0 -0
  261. /package/dist/{internal → transport}/transport.d.ts +0 -0
  262. /package/dist/{internal → transport}/transport.js +0 -0
@@ -1,6 +1,7 @@
1
- import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { getTransport } from '../internal/singleton.js';
3
- import { sendTypedRequest } from '../internal/transport.js';
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { getTransport } from '../transport/singleton.js';
3
+ import { sendTypedRequest } from '../transport/transport.js';
4
+ import { useRequestSequencer } from './useRequestSequencer.js';
4
5
  /**
5
6
  * Read the signed-in viewer (id / username / status + optional buzzBudget)
6
7
  * through the host-mediated `GET_VIEWER` → `VIEWER_RESULT` bridge. Token-bound:
@@ -17,8 +18,9 @@ import { sendTypedRequest } from '../internal/transport.js';
17
18
  *
18
19
  * Fetches once on mount and exposes `refetch` for on-demand refreshes. A host
19
20
  * that never answers surfaces as an `error` after the transport's request
20
- * timeout — the hook never hangs. Late responses that arrive after unmount are
21
- * ignored (no state update).
21
+ * timeout — the hook never hangs. Only the LATEST request may write state: a
22
+ * reply superseded by a newer `refetch` — or one that lands after unmount — is
23
+ * dropped (#392).
22
24
  *
23
25
  * @example
24
26
  * const { viewer, loading, error, refetch } = useViewer();
@@ -30,22 +32,18 @@ export function useViewer() {
30
32
  const [viewer, setViewer] = useState(null);
31
33
  const [loading, setLoading] = useState(true);
32
34
  const [error, setError] = useState(null);
33
- // Guards against a late response resolving after the component unmounted
34
- // (React would warn about a state update on an unmounted component, and the
35
- // work is wasted anyway).
36
- const mountedRef = useRef(true);
37
- useEffect(() => {
38
- mountedRef.current = true;
39
- return () => {
40
- mountedRef.current = false;
41
- };
42
- }, []);
35
+ // Latest-wins + unmount guard in one predicate (#392): a reply may write state
36
+ // only if it answers the request this hook is CURRENTLY waiting for. A bare
37
+ // mount check would let a superseded `refetch`'s slow reply overwrite newer
38
+ // state — nothing unmounted, so it passes.
39
+ const seq = useRequestSequencer();
43
40
  const refetch = useCallback(() => {
41
+ const token = seq.begin();
44
42
  setLoading(true);
45
43
  setError(null);
46
44
  sendTypedRequest(getTransport(), { type: 'GET_VIEWER', payload: {} }, 'VIEWER_RESULT')
47
45
  .then((result) => {
48
- if (!mountedRef.current)
46
+ if (!seq.isCurrent(token))
49
47
  return;
50
48
  if (result.error || !result.viewer) {
51
49
  // `||`, not `??`: `isValidViewerResult` gates `error` on SHAPE only, so a
@@ -59,12 +57,12 @@ export function useViewer() {
59
57
  setLoading(false);
60
58
  })
61
59
  .catch((err) => {
62
- if (!mountedRef.current)
60
+ if (!seq.isCurrent(token))
63
61
  return;
64
62
  setError(err instanceof Error ? err : new Error(String(err)));
65
63
  setLoading(false);
66
64
  });
67
- }, []);
65
+ }, [seq]);
68
66
  useEffect(() => {
69
67
  refetch();
70
68
  }, [refetch]);
@@ -39,7 +39,9 @@ export interface UseWildcardPack {
39
39
  * to retry a `busy` result). On failure `error` is a {@link WildcardPackError}
40
40
  * whose `.code` is the discriminated reason. A non-positive `modelVersionId` is a
41
41
  * no-op (nothing to fetch). A host that never answers surfaces as an `error`
42
- * after the transport timeout; late post-unmount responses are ignored.
42
+ * after the transport timeout. Only the LATEST request may write state: a reply
43
+ * superseded by a newer `refetch` / `modelVersionId` change — or one that lands
44
+ * after unmount — is dropped (#392).
43
45
  *
44
46
  * @example
45
47
  * const { pack, loading, error } = useWildcardPack(modelVersionId);
@@ -1,6 +1,7 @@
1
- import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { getTransport } from '../internal/singleton.js';
3
- import { sendTypedRequest } from '../internal/transport.js';
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { getTransport } from '../transport/singleton.js';
3
+ import { sendTypedRequest } from '../transport/transport.js';
4
+ import { useRequestSequencer } from './useRequestSequencer.js';
4
5
  /**
5
6
  * A wildcard-pack import failure. Unlike the buzz bridges' free-text errors, the
6
7
  * host returns a DISCRIMINATED code — this error carries it on `.code` so a block
@@ -27,7 +28,9 @@ export class WildcardPackError extends Error {
27
28
  * to retry a `busy` result). On failure `error` is a {@link WildcardPackError}
28
29
  * whose `.code` is the discriminated reason. A non-positive `modelVersionId` is a
29
30
  * no-op (nothing to fetch). A host that never answers surfaces as an `error`
30
- * after the transport timeout; late post-unmount responses are ignored.
31
+ * after the transport timeout. Only the LATEST request may write state: a reply
32
+ * superseded by a newer `refetch` / `modelVersionId` change — or one that lands
33
+ * after unmount — is dropped (#392).
31
34
  *
32
35
  * @example
33
36
  * const { pack, loading, error } = useWildcardPack(modelVersionId);
@@ -37,15 +40,17 @@ export function useWildcardPack(modelVersionId) {
37
40
  const [pack, setPack] = useState(null);
38
41
  const [loading, setLoading] = useState(true);
39
42
  const [error, setError] = useState(null);
40
- const mountedRef = useRef(true);
41
- useEffect(() => {
42
- mountedRef.current = true;
43
- return () => {
44
- mountedRef.current = false;
45
- };
46
- }, []);
43
+ // Latest-wins + unmount guard in one predicate (#392): a reply may write state
44
+ // only if it answers the request this hook is CURRENTLY waiting for. A bare
45
+ // mount check would let a superseded request's slow reply overwrite newer
46
+ // state — nothing unmounted, so it passes.
47
+ const seq = useRequestSequencer();
47
48
  const valid = Number.isInteger(modelVersionId) && modelVersionId > 0;
48
49
  const refetch = useCallback(() => {
50
+ // `begin()` runs BEFORE the validity gate on purpose: moving to a
51
+ // non-positive id must also SUPERSEDE an in-flight request for the previous
52
+ // id, or that reply would land and paint a pack the hook no longer wants.
53
+ const token = seq.begin();
49
54
  if (!valid) {
50
55
  // Nothing to fetch — don't summon a host round-trip that would only time
51
56
  // out (the host drops a non-positive modelVersionId).
@@ -56,7 +61,7 @@ export function useWildcardPack(modelVersionId) {
56
61
  setError(null);
57
62
  sendTypedRequest(getTransport(), { type: 'GET_WILDCARD_PACK', payload: { modelVersionId } }, 'WILDCARD_PACK_RESULT')
58
63
  .then((result) => {
59
- if (!mountedRef.current)
64
+ if (!seq.isCurrent(token))
60
65
  return;
61
66
  if (result.error || !result.pack) {
62
67
  // 🔴 KEEP `??` HERE — do NOT "fix" this to `||` like the sibling hooks.
@@ -73,12 +78,12 @@ export function useWildcardPack(modelVersionId) {
73
78
  setLoading(false);
74
79
  })
75
80
  .catch((err) => {
76
- if (!mountedRef.current)
81
+ if (!seq.isCurrent(token))
77
82
  return;
78
83
  setError(err instanceof Error ? err : new Error(String(err)));
79
84
  setLoading(false);
80
85
  });
81
- }, [valid, modelVersionId]);
86
+ }, [valid, modelVersionId, seq]);
82
87
  useEffect(() => {
83
88
  refetch();
84
89
  }, [refetch]);
package/dist/index.d.ts CHANGED
@@ -6,29 +6,36 @@
6
6
  * platform side can integration-test against a real iframe receiver.
7
7
  */
8
8
  import '@civitai/app-sdk/safe-storage';
9
- export { IframeTransport } from './internal/iframeTransport.js';
10
- export type { IframeTransportOptions } from './internal/iframeTransport.js';
11
- export { InlineTransport } from './internal/inlineTransport.js';
12
- export { BlockTransportDetector, readAllowedOriginsFromEnv } from './internal/detector.js';
13
- export type { DetectOptions } from './internal/detector.js';
14
- export { getTransport } from './internal/singleton.js';
15
- export { sendTypedRequest } from './internal/transport.js';
16
- export type { BlockSnapshot, BlockTransport, OutboundRequest, } from './internal/transport.js';
9
+ export { IframeTransport } from './transport/iframeTransport.js';
10
+ export type { IframeTransportOptions } from './transport/iframeTransport.js';
11
+ export { InlineTransport } from './transport/inlineTransport.js';
12
+ export { BlockTransportDetector, readAllowedOriginsFromEnv } from './transport/detector.js';
13
+ export type { DetectOptions } from './transport/detector.js';
14
+ export { getTransport } from './transport/singleton.js';
15
+ export { sendTypedRequest } from './transport/transport.js';
16
+ export type { BlockSnapshot, BlockTransport, OutboundRequest, } from './transport/transport.js';
17
17
  export { useBlockContext } from './hooks/useBlockContext.js';
18
+ export type { UseBlockContext } from './hooks/useBlockContext.js';
18
19
  export { useBlockTheme } from './hooks/useBlockTheme.js';
20
+ export type { UseBlockTheme } from './hooks/useBlockTheme.js';
19
21
  export { useBlockSettings } from './hooks/useBlockSettings.js';
22
+ export type { UseBlockSettings } from './hooks/useBlockSettings.js';
20
23
  export { useBlockToken } from './hooks/useBlockToken.js';
24
+ export type { UseBlockToken } from './hooks/useBlockToken.js';
21
25
  export { useHostOrigin } from './hooks/useHostOrigin.js';
26
+ export type { UseHostOrigin } from './hooks/useHostOrigin.js';
22
27
  export { DEFAULT_WATCH_WAIT_SECONDS, useBuzzWorkflow, WorkflowEstimateError, WorkflowSubmitError, } from './hooks/useBuzzWorkflow.js';
23
- export type { SubmitWorkflowOptions, WatchWorkflowOptions, WorkflowSubmitErrorCode, } from './hooks/useBuzzWorkflow.js';
28
+ export type { SubmitWorkflowOptions, UseBuzzWorkflow, WatchWorkflowOptions, WorkflowSubmitErrorCode, } from './hooks/useBuzzWorkflow.js';
24
29
  export { useTip } from './hooks/useTip.js';
25
30
  export type { TipParams, TipOptions, TipResult, UseTip } from './hooks/useTip.js';
26
31
  export { useTipAllowance } from './hooks/useTipAllowance.js';
27
32
  export type { TipAllowance, UseTipAllowance } from './hooks/useTipAllowance.js';
28
33
  export { useBlockResize } from './hooks/useBlockResize.js';
34
+ export type { UseBlockResize } from './hooks/useBlockResize.js';
29
35
  export { useBlockBreakpoint, resolveBlockTier } from './hooks/useBlockBreakpoint.js';
30
- export type { BlockBreakpoint, BlockSizeTier } from './hooks/useBlockBreakpoint.js';
36
+ export type { BlockBreakpoint, BlockSizeTier, UseBlockBreakpoint, } from './hooks/useBlockBreakpoint.js';
31
37
  export { useBuzzPurchase } from './hooks/useBuzzPurchase.js';
38
+ export type { UseBuzzPurchase } from './hooks/useBuzzPurchase.js';
32
39
  export { useBuzzBalance } from './hooks/useBuzzBalance.js';
33
40
  export type { BuzzBalance, UseBuzzBalance } from './hooks/useBuzzBalance.js';
34
41
  export { useViewer } from './hooks/useViewer.js';
@@ -49,30 +56,39 @@ export { useGatedImages } from './hooks/useGatedImages.js';
49
56
  export type { UseGatedImages } from './hooks/useGatedImages.js';
50
57
  export { useSaveImage } from './hooks/useSaveImage.js';
51
58
  export type { UseSaveImage, SaveImageInput } from './hooks/useSaveImage.js';
52
- export { RequestTimeoutError } from './internal/transport.js';
59
+ export { RequestTimeoutError } from './transport/transport.js';
53
60
  export { useCollectionFollow, CollectionFollowError, COLLECTION_FOLLOW_ERROR_CODES, isCollectionFollowErrorCode, } from './hooks/useCollectionFollow.js';
54
61
  export type { UseCollectionFollow } from './hooks/useCollectionFollow.js';
55
62
  export { useCreatePostFromApp, CreatePostError, CREATE_POST_ERROR_CODES, isCreatePostErrorCode, } from './hooks/useCreatePostFromApp.js';
56
63
  export type { UseCreatePostFromApp, BlockPostSource, BlockCreatePostRequest, BlockCreatePostResult, BlockCreatePostHostError, } from './hooks/useCreatePostFromApp.js';
57
64
  export type { BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, AppWorkflowImage, AppWorkflowsParams, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, } from '@civitai/app-sdk/blocks';
58
65
  export { useCheckpointPicker } from './hooks/useCheckpointPicker.js';
66
+ export type { UseCheckpointPicker } from './hooks/useCheckpointPicker.js';
59
67
  export { useResourcePicker } from './hooks/useResourcePicker.js';
68
+ export type { UseResourcePicker } from './hooks/useResourcePicker.js';
60
69
  export { useImageUpload } from './hooks/useImageUpload.js';
70
+ export type { UseImageUpload, UseImageUploadAsyncScan, UseImageUploadGenerationSource, UseImageUploadOptions, } from './hooks/useImageUpload.js';
61
71
  export { useGenerationResources } from './hooks/useGenerationResources.js';
72
+ export type { UseGenerationResources } from './hooks/useGenerationResources.js';
62
73
  export { GENERATION_RESOURCES_API_BASE, MAX_GENERATION_RESOURCE_IDS, buildGenerationResourcesUrl, responseToResources, } from './api/generationResources.js';
74
+ export type { RawGenerationResource, RawGenerationResourcesResponse, } from './api/generationResources.js';
63
75
  export { useCivitaiNavigate } from './hooks/useCivitaiNavigate.js';
76
+ export type { UseCivitaiNavigate } from './hooks/useCivitaiNavigate.js';
64
77
  export { useRequestSignIn } from './hooks/useRequestSignIn.js';
78
+ export type { UseRequestSignIn } from './hooks/useRequestSignIn.js';
65
79
  export { useRequestConsent } from './hooks/useRequestConsent.js';
80
+ export type { UseRequestConsent } from './hooks/useRequestConsent.js';
66
81
  export { useConsentUnavailable } from './hooks/useConsentUnavailable.js';
67
82
  export type { UseConsentUnavailable, ConsentUnavailablePayload, } from './hooks/useConsentUnavailable.js';
68
83
  export { useBlockAnalytics } from './hooks/useBlockAnalytics.js';
84
+ export type { UseBlockAnalytics } from './hooks/useBlockAnalytics.js';
69
85
  export { useDomainMaturity } from './hooks/useDomainMaturity.js';
70
- export type { DomainMaturity } from './hooks/useDomainMaturity.js';
86
+ export type { DomainMaturity, UseDomainMaturity } from './hooks/useDomainMaturity.js';
71
87
  export { SfwGate } from './hooks/SfwGate.js';
72
88
  export type { SfwGateProps } from './hooks/SfwGate.js';
73
89
  export { useDirectLoad } from './hooks/useDirectLoad.js';
74
- export type { UseDirectLoadOptions } from './hooks/useDirectLoad.js';
75
- export { hostToRunUrl, DIRECT_LOAD_TIMEOUT_MS } from './internal/directLoad.js';
90
+ export type { UseDirectLoad, UseDirectLoadOptions } from './hooks/useDirectLoad.js';
91
+ export { hostToRunUrl, DIRECT_LOAD_TIMEOUT_MS } from './transport/directLoad.js';
76
92
  export { useAppStorage } from './hooks/useAppStorage.js';
77
93
  export type { AppStorageKeyEntry, AppStorageListResult, AppStorageQuota, UseAppStorage, } from './hooks/useAppStorage.js';
78
94
  export { useSharedStorage } from './hooks/useSharedStorage.js';
package/dist/index.js CHANGED
@@ -12,11 +12,11 @@
12
12
  // in-memory `Storage` over those globals when (and only when) they are broken,
13
13
  // before the rest of the app's module graph runs. Inert everywhere else.
14
14
  import '@civitai/app-sdk/safe-storage';
15
- export { IframeTransport } from './internal/iframeTransport.js';
16
- export { InlineTransport } from './internal/inlineTransport.js';
17
- export { BlockTransportDetector, readAllowedOriginsFromEnv } from './internal/detector.js';
18
- export { getTransport } from './internal/singleton.js';
19
- export { sendTypedRequest } from './internal/transport.js';
15
+ export { IframeTransport } from './transport/iframeTransport.js';
16
+ export { InlineTransport } from './transport/inlineTransport.js';
17
+ export { BlockTransportDetector, readAllowedOriginsFromEnv } from './transport/detector.js';
18
+ export { getTransport } from './transport/singleton.js';
19
+ export { sendTypedRequest } from './transport/transport.js';
20
20
  // Hooks
21
21
  export { useBlockContext } from './hooks/useBlockContext.js';
22
22
  export { useBlockTheme } from './hooks/useBlockTheme.js';
@@ -42,7 +42,7 @@ export { useSaveImage } from './hooks/useSaveImage.js';
42
42
  // Exported because `sendTypedRequest` (also exported) can throw it, and its own
43
43
  // JSDoc says consumers need to distinguish "no reply" from "the host said no" —
44
44
  // which they cannot do if they cannot name the type.
45
- export { RequestTimeoutError } from './internal/transport.js';
45
+ export { RequestTimeoutError } from './transport/transport.js';
46
46
  export { useCollectionFollow, CollectionFollowError, COLLECTION_FOLLOW_ERROR_CODES, isCollectionFollowErrorCode, } from './hooks/useCollectionFollow.js';
47
47
  export { useCreatePostFromApp, CreatePostError, CREATE_POST_ERROR_CODES, isCreatePostErrorCode, } from './hooks/useCreatePostFromApp.js';
48
48
  export { useCheckpointPicker } from './hooks/useCheckpointPicker.js';
@@ -58,7 +58,7 @@ export { useBlockAnalytics } from './hooks/useBlockAnalytics.js';
58
58
  export { useDomainMaturity } from './hooks/useDomainMaturity.js';
59
59
  export { SfwGate } from './hooks/SfwGate.js';
60
60
  export { useDirectLoad } from './hooks/useDirectLoad.js';
61
- export { hostToRunUrl, DIRECT_LOAD_TIMEOUT_MS } from './internal/directLoad.js';
61
+ export { hostToRunUrl, DIRECT_LOAD_TIMEOUT_MS } from './transport/directLoad.js';
62
62
  export { useAppStorage } from './hooks/useAppStorage.js';
63
63
  export { useSharedStorage } from './hooks/useSharedStorage.js';
64
64
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import type { ConsentUnavailablePayload } from '@civitai/app-sdk/blocks';
2
- import type { BlockTransport } from './transport.js';
2
+ import type { BlockTransport } from '../transport/transport.js';
3
3
  /**
4
4
  * Install the latch's subscription on `transport` if it is not already the
5
5
  * transport we are latching for. Idempotent per transport instance.
@@ -1,4 +1,4 @@
1
- import { subscribeTyped } from './transport.js';
1
+ import { subscribeTyped } from '../transport/transport.js';
2
2
  let latched = null;
3
3
  let installedOn = null;
4
4
  /**
@@ -24,12 +24,31 @@
24
24
  * viewer, decodes the token JWT payload for the block identity / scopes /
25
25
  * budget / maturity, and dispatches `BLOCK_INIT`.
26
26
  *
27
- * REAL NETWORK, REAL MONEY: unlike the mock host, this calls `fetch`. The only
28
- * network it does is (a) `GET /api/v1/blocks/me` and (b) the four
29
- * `blocks.{estimate,submit,poll,cancel}Workflow` tRPC mutations — each with the
30
- * Bearer dev token. A successful submit SPENDS the dev's OWN real Buzz against
31
- * real compute. The token's per-call budget + the per-user daily cap are the
32
- * server-side bounds (scope doc §4).
27
+ * REAL NETWORK, REAL MONEY: unlike the mock host, this calls `fetch`. Every
28
+ * call is Bearer-authed with the dev token and leaves this file through one of
29
+ * exactly two chokepoints — {@link rawTrpcCall} (every tRPC procedure) and the
30
+ * `/api/v1/blocks/me` viewer read in `resolveViewer`. A successful submit
31
+ * SPENDS the dev's OWN real Buzz against real compute. The token's per-call
32
+ * budget + the per-user daily cap are the server-side bounds (scope doc §4).
33
+ * (The picker overlay does its own catalog fetch — that lives in
34
+ * `pickerOverlay.ts`, not here; see PICKERS below.)
35
+ *
36
+ * 🔴 THE BLOCK BELOW IS DERIVED FROM THIS FILE. DO NOT HAND-EDIT IT — and do
37
+ * not re-introduce a typed "the only X is …" list anywhere in this header.
38
+ * This file grew from 5 network calls to 30 and from 1 refusal to 7 while the
39
+ * header still said "the only network it does is … the four `blocks.*Workflow`
40
+ * mutations" and "the ONE capability live mode cannot SERVE" (#387, #14). An
41
+ * exhaustive count typed into a 2,100-line file that grows every release is a
42
+ * claim nobody re-measures. So it is measured:
43
+ * `tests/guards/livehost-header-enumerations.test.mjs` regenerates the block
44
+ * from the code and fails with the exact replacement text when it drifts.
45
+ *
46
+ * --- BEGIN DERIVED ---
47
+ * fetch chokepoints ..... 2
48
+ * REST endpoints ........ GET /api/v1/blocks/me
49
+ * tRPC procedures ....... 29 = blocks.* (14) + apps.shared.* (10) + apps.storage.* (5)
50
+ * switch case labels .... 45, of which 7 REFUSE (enumerated under SCOPE below)
51
+ * --- END DERIVED ---
33
52
  *
34
53
  * PICKERS (Phase 1 of "make dev:live a faithful local host"): the live host
35
54
  * SERVES the resource pickers locally. On `OPEN_CHECKPOINT_PICKER` /
@@ -57,11 +76,44 @@
57
76
  * honest error "block token lacks modelId context"; that real outcome is
58
77
  * surfaced to the block. With a model-slot token it persists for real.
59
78
  *
60
- * SCOPE — the ONE capability live mode still cannot SERVE is OPEN_BUZZ_PURCHASE:
61
- * there is NO headless / block-token Buzz-purchase path (buying Buzz strictly
62
- * requires the interactive Stripe/Paddle host chrome). So it deep-links the real
63
- * purchase page and replies `purchased: false` — honest-by-design, never a
64
- * fabricated success. See the per-message handlers below.
79
+ * SHARED STORAGE (#386): the live host SERVES all TEN `SHARED_*` bridges —
80
+ * `apps.shared.{list,get,getCount,getCounts,append,update,vote,unvote,withdraw,
81
+ * report}` — on the same block-token convention as APP_STORAGE. `SHARED_GET`
82
+ * and `SHARED_REPORT` were the last two missing; until #386 they fell through
83
+ * the switch's `default: return` with no reply at all, so `useSharedStorage()`
84
+ * hung to the 30s protocol timeout in dev:live for code that worked in dev:mock.
85
+ *
86
+ * 🔴 SCOPE — the capabilities live mode still cannot SERVE. Each REFUSES on its
87
+ * own reply channel — `logOnce` (or `console.info`) plus an honest error, never
88
+ * a fabricated success and never silence. Two guards stand behind this list:
89
+ * `tests/guards/livehost-message-coverage.test.mjs` asserts that no block→parent
90
+ * type is left without a case at all (the failure mode a refusal is NOT), and
91
+ * `tests/guards/livehost-header-enumerations.test.mjs` derives the refusal set
92
+ * from the handlers below and asserts these bullets are exactly it — so the
93
+ * list cannot silently go stale again the way it did through #14/#387. Add a
94
+ * refusal handler without a bullet, or leave a bullet whose handler now serves,
95
+ * and that guard fails naming the difference.
96
+ *
97
+ * • OPEN_BUZZ_PURCHASE — no headless / block-token Buzz-purchase path (buying
98
+ * Buzz strictly requires the interactive Stripe/Paddle host chrome). Deep-
99
+ * links the real purchase page and replies `purchased: false`.
100
+ * • SET_COLLECTION_FOLLOW — needs the session-authed follow procedures plus
101
+ * host-chrome consent. Replies `collection-unavailable`.
102
+ * • CREATE_POST_FROM_APP — needs the server-resolved preview plus host-chrome
103
+ * confirm before a PUBLIC post is written. Replies with a refusal.
104
+ * • GET_WILDCARD_PACK — needs the session-authed resolve plus the in-tab
105
+ * zip/yaml parse that lives in civitai, not this SDK. Replies `parse-failed`.
106
+ * • OPEN_IMAGE_UPLOAD — needs the host's native modal + session-authed byte
107
+ * pipeline. Replies DISMISSED (the hook resolves `null`).
108
+ * • SAVE_IMAGE — the download bridge is the production host's unsandboxed top
109
+ * frame plus its CDN origin allowlist / gated per-viewer read. Replies with
110
+ * a refusal (#386).
111
+ * • REQUEST_CONSENT — live mode cannot grant a scope the token does not carry.
112
+ * Pushes `CONSENT_UNAVAILABLE` when the ask is genuinely ungrantable.
113
+ *
114
+ * In every case REFUSING IS THE POINT: serving a weakened local imitation would
115
+ * let a block prove out a flow production does not have, and ship having never
116
+ * handled the refusal. Use dev:mock for those paths. See the handlers below.
65
117
  */
66
118
  import { type BlockContext, type ColorDomain, type Theme, type ViewerInfo } from '@civitai/app-sdk/blocks';
67
119
  import type { MockHost } from './mockHost.js';