@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
@@ -0,0 +1,113 @@
1
+ /**
2
+ * The two — and only two — questions anyone asks about a `requestId`.
3
+ *
4
+ * Before #395 this file did not exist and both questions were open-coded at 64
5
+ * sites in five different spellings. Measured on `e993cf0`:
6
+ *
7
+ * ```
8
+ * 33 x p.requestId !== undefined && typeof p.requestId !== 'string' validate.ts
9
+ * 1 x !isNonEmptyString(p.requestId) validate.ts
10
+ * 26 x typeof requestId !== 'string' liveHost/mockHost
11
+ * 2 x typeof <expr>.requestId === 'string' iframeTransport.ts
12
+ * 2 x ...(requestId ? { requestId } : {}) liveHost/mockHost
13
+ * ```
14
+ *
15
+ * (The issue's "~45 sites" undercounts: it was written before #378/#416 moved
16
+ * nine modules out of `internal/`, and it counted two TYPE ANNOTATIONS as if
17
+ * they were predicates. The 64 above are runtime decisions only.)
18
+ *
19
+ * ⚠️ NOT ROUTED THROUGH HERE, DELIBERATELY: the 37 `requestId ?? ''`
20
+ * expressions in `liveHost.ts`. They are nullish DEFAULTS on an EMIT path, not
21
+ * routability decisions — nobody branches on the result; it is written straight
22
+ * onto the wire. **MEASURED, not assumed: none of the 37 sits downstream of a
23
+ * routability guard** (checked by walking back to each one's enclosing `case`),
24
+ * so `liveHost` answers an id-less request with an unroutable `requestId: ''`
25
+ * reply where `mockHost` declines to answer at all. Both end the same way — the
26
+ * block cannot correlate either, and the request times out — and the arm is
27
+ * unreachable in practice, because only `sendRequest` produces a request that
28
+ * gets a reply and it always assigns an id (`nextRequestId()`); every `case`
29
+ * reachable by the id-less `sendMessage` path returns before replying.
30
+ *
31
+ * Unifying those 37 onto an early `return` would be a 37-site behaviour change
32
+ * on a dev-harness emit path, which is out of scope for a consolidation; they
33
+ * are instead an ASSERTED COUNT in the guard, so a 38th cannot appear without
34
+ * someone deciding. Filed as the follow-up in #395's PR, not fixed here.
35
+ *
36
+ * ## The two questions are NOT the same question, and collapsing them is a bug
37
+ *
38
+ * - **`isRoutableRequestId`** — "can this value correlate a reply to an entry in
39
+ * the transport's `pending` table?" A **non-empty string**. This is the
40
+ * decision every routing site makes.
41
+ * - **`isWireRequestIdShape`** — "is the `requestId` field on this inbound
42
+ * payload well-formed?" **Absent, or any string — including `''`.** This is a
43
+ * trust-boundary *shape* check, and it is DELIBERATELY LOOSER than routability.
44
+ *
45
+ * 🔴 DO NOT "SIMPLIFY" THE VALIDATORS ONTO `isRoutableRequestId`. A validator
46
+ * that returns `false` DROPS the whole message at the trust boundary, with
47
+ * nothing but a `console.warn`. `isValidTokenRefreshResponse`'s docblock spells
48
+ * out what that costs: a `TOKEN_REFRESH_RESPONSE` that cannot correlate still
49
+ * carries a token that `handleMessage` applies to the snapshot regardless of
50
+ * correlation, so dropping it converts a degraded path into a broken one. The
51
+ * looseness is the back-compat story for a new SDK against a pre-v2 host, not an
52
+ * oversight. Routability is decided LATER, by `isRoutableRequestId`, and an
53
+ * unroutable-but-well-formed reply is delivered to push listeners rather than
54
+ * discarded.
55
+ *
56
+ * The relationship is a strict containment and it is the whole contract:
57
+ *
58
+ * ```
59
+ * isRoutableRequestId(v) => isWireRequestIdShape(v) (always)
60
+ * isWireRequestIdShape(v) =/> isRoutableRequestId(v) (v === undefined, v === '')
61
+ * ```
62
+ *
63
+ * ## `null` is not routable, and never was
64
+ *
65
+ * #395 was filed on the theory that the spellings disagreed about
66
+ * `requestId: null`. They do not — every one of the 64 sites above rejects
67
+ * `null` (`typeof null === 'object'`; `null` is falsy; `null ?? ''` is `''`).
68
+ * The two spellings the issue counted as differing on `null` were TYPE
69
+ * ANNOTATIONS on the *payload* (`{ requestId?: unknown } | undefined` vs
70
+ * `... | null | undefined`), not runtime predicates, and both sites runtime-guard
71
+ * the payload anyway. `null` is therefore pinned here as the behaviour that
72
+ * already held, not chosen: see `requestId.test.ts`.
73
+ *
74
+ * What the spellings DID disagree about is the EMPTY STRING — see
75
+ * `isRoutableRequestId` below.
76
+ *
77
+ * Enforced by `tests/guards/blocks-react-requestid-routability.test.mjs`, which
78
+ * fails when a routability or wire-shape decision is open-coded anywhere in
79
+ * `packages/civitai-blocks-react/src` outside this module.
80
+ */
81
+ /**
82
+ * Can this value correlate a reply to a pending request?
83
+ *
84
+ * A **non-empty string**. Nothing else — not `null`, not `undefined`, not a
85
+ * number a buggy host echoed, not `''`.
86
+ *
87
+ * 🔴 WHY NON-EMPTY, WHEN THREE OF THE FOUR OLD SPELLINGS ACCEPTED `''`.
88
+ * `nextRequestId()` (transport.ts) returns `` `${base36}-${counter}` ``, which is
89
+ * never empty, so `''` can never be a key in the transport's `pending` table:
90
+ * `pending.get('')` was already a guaranteed miss at both routing sites. Making
91
+ * the emptiness explicit costs nothing there and makes this predicate agree with
92
+ * `isValidImageScanResolved`, the one site that already required non-empty. The
93
+ * sites where it does move behaviour — the dev/mock hosts, which used to answer
94
+ * a `requestId: ''` request with an equally unroutable `requestId: ''` reply, and
95
+ * now decline to answer at all — are enumerated and pinned in `requestId.test.ts`.
96
+ */
97
+ export declare function isRoutableRequestId(v: unknown): v is string;
98
+ /**
99
+ * Is the OPTIONAL `requestId` field of an inbound payload well-formed?
100
+ *
101
+ * `true` when the field is absent (`undefined`) or is any string, `''` included.
102
+ * `false` for every other type — a non-string cannot masquerade as a correlation
103
+ * id, which is the only thing these validators need to rule out.
104
+ *
105
+ * Pass the FIELD, not the payload: `isWireRequestIdShape(p.requestId)`.
106
+ *
107
+ * Exactly equivalent to the 33 open-coded copies it replaced —
108
+ * `!(v === undefined || typeof v === 'string')` is `v !== undefined &&
109
+ * typeof v !== 'string'` — so no validator's behaviour moved. Read the module
110
+ * docblock before tightening it.
111
+ */
112
+ export declare function isWireRequestIdShape(v: unknown): boolean;
113
+ //# sourceMappingURL=requestId.d.ts.map
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The two — and only two — questions anyone asks about a `requestId`.
3
+ *
4
+ * Before #395 this file did not exist and both questions were open-coded at 64
5
+ * sites in five different spellings. Measured on `e993cf0`:
6
+ *
7
+ * ```
8
+ * 33 x p.requestId !== undefined && typeof p.requestId !== 'string' validate.ts
9
+ * 1 x !isNonEmptyString(p.requestId) validate.ts
10
+ * 26 x typeof requestId !== 'string' liveHost/mockHost
11
+ * 2 x typeof <expr>.requestId === 'string' iframeTransport.ts
12
+ * 2 x ...(requestId ? { requestId } : {}) liveHost/mockHost
13
+ * ```
14
+ *
15
+ * (The issue's "~45 sites" undercounts: it was written before #378/#416 moved
16
+ * nine modules out of `internal/`, and it counted two TYPE ANNOTATIONS as if
17
+ * they were predicates. The 64 above are runtime decisions only.)
18
+ *
19
+ * ⚠️ NOT ROUTED THROUGH HERE, DELIBERATELY: the 37 `requestId ?? ''`
20
+ * expressions in `liveHost.ts`. They are nullish DEFAULTS on an EMIT path, not
21
+ * routability decisions — nobody branches on the result; it is written straight
22
+ * onto the wire. **MEASURED, not assumed: none of the 37 sits downstream of a
23
+ * routability guard** (checked by walking back to each one's enclosing `case`),
24
+ * so `liveHost` answers an id-less request with an unroutable `requestId: ''`
25
+ * reply where `mockHost` declines to answer at all. Both end the same way — the
26
+ * block cannot correlate either, and the request times out — and the arm is
27
+ * unreachable in practice, because only `sendRequest` produces a request that
28
+ * gets a reply and it always assigns an id (`nextRequestId()`); every `case`
29
+ * reachable by the id-less `sendMessage` path returns before replying.
30
+ *
31
+ * Unifying those 37 onto an early `return` would be a 37-site behaviour change
32
+ * on a dev-harness emit path, which is out of scope for a consolidation; they
33
+ * are instead an ASSERTED COUNT in the guard, so a 38th cannot appear without
34
+ * someone deciding. Filed as the follow-up in #395's PR, not fixed here.
35
+ *
36
+ * ## The two questions are NOT the same question, and collapsing them is a bug
37
+ *
38
+ * - **`isRoutableRequestId`** — "can this value correlate a reply to an entry in
39
+ * the transport's `pending` table?" A **non-empty string**. This is the
40
+ * decision every routing site makes.
41
+ * - **`isWireRequestIdShape`** — "is the `requestId` field on this inbound
42
+ * payload well-formed?" **Absent, or any string — including `''`.** This is a
43
+ * trust-boundary *shape* check, and it is DELIBERATELY LOOSER than routability.
44
+ *
45
+ * 🔴 DO NOT "SIMPLIFY" THE VALIDATORS ONTO `isRoutableRequestId`. A validator
46
+ * that returns `false` DROPS the whole message at the trust boundary, with
47
+ * nothing but a `console.warn`. `isValidTokenRefreshResponse`'s docblock spells
48
+ * out what that costs: a `TOKEN_REFRESH_RESPONSE` that cannot correlate still
49
+ * carries a token that `handleMessage` applies to the snapshot regardless of
50
+ * correlation, so dropping it converts a degraded path into a broken one. The
51
+ * looseness is the back-compat story for a new SDK against a pre-v2 host, not an
52
+ * oversight. Routability is decided LATER, by `isRoutableRequestId`, and an
53
+ * unroutable-but-well-formed reply is delivered to push listeners rather than
54
+ * discarded.
55
+ *
56
+ * The relationship is a strict containment and it is the whole contract:
57
+ *
58
+ * ```
59
+ * isRoutableRequestId(v) => isWireRequestIdShape(v) (always)
60
+ * isWireRequestIdShape(v) =/> isRoutableRequestId(v) (v === undefined, v === '')
61
+ * ```
62
+ *
63
+ * ## `null` is not routable, and never was
64
+ *
65
+ * #395 was filed on the theory that the spellings disagreed about
66
+ * `requestId: null`. They do not — every one of the 64 sites above rejects
67
+ * `null` (`typeof null === 'object'`; `null` is falsy; `null ?? ''` is `''`).
68
+ * The two spellings the issue counted as differing on `null` were TYPE
69
+ * ANNOTATIONS on the *payload* (`{ requestId?: unknown } | undefined` vs
70
+ * `... | null | undefined`), not runtime predicates, and both sites runtime-guard
71
+ * the payload anyway. `null` is therefore pinned here as the behaviour that
72
+ * already held, not chosen: see `requestId.test.ts`.
73
+ *
74
+ * What the spellings DID disagree about is the EMPTY STRING — see
75
+ * `isRoutableRequestId` below.
76
+ *
77
+ * Enforced by `tests/guards/blocks-react-requestid-routability.test.mjs`, which
78
+ * fails when a routability or wire-shape decision is open-coded anywhere in
79
+ * `packages/civitai-blocks-react/src` outside this module.
80
+ */
81
+ /**
82
+ * Can this value correlate a reply to a pending request?
83
+ *
84
+ * A **non-empty string**. Nothing else — not `null`, not `undefined`, not a
85
+ * number a buggy host echoed, not `''`.
86
+ *
87
+ * 🔴 WHY NON-EMPTY, WHEN THREE OF THE FOUR OLD SPELLINGS ACCEPTED `''`.
88
+ * `nextRequestId()` (transport.ts) returns `` `${base36}-${counter}` ``, which is
89
+ * never empty, so `''` can never be a key in the transport's `pending` table:
90
+ * `pending.get('')` was already a guaranteed miss at both routing sites. Making
91
+ * the emptiness explicit costs nothing there and makes this predicate agree with
92
+ * `isValidImageScanResolved`, the one site that already required non-empty. The
93
+ * sites where it does move behaviour — the dev/mock hosts, which used to answer
94
+ * a `requestId: ''` request with an equally unroutable `requestId: ''` reply, and
95
+ * now decline to answer at all — are enumerated and pinned in `requestId.test.ts`.
96
+ */
97
+ export function isRoutableRequestId(v) {
98
+ return typeof v === 'string' && v.length > 0;
99
+ }
100
+ /**
101
+ * Is the OPTIONAL `requestId` field of an inbound payload well-formed?
102
+ *
103
+ * `true` when the field is absent (`undefined`) or is any string, `''` included.
104
+ * `false` for every other type — a non-string cannot masquerade as a correlation
105
+ * id, which is the only thing these validators need to rule out.
106
+ *
107
+ * Pass the FIELD, not the payload: `isWireRequestIdShape(p.requestId)`.
108
+ *
109
+ * Exactly equivalent to the 33 open-coded copies it replaced —
110
+ * `!(v === undefined || typeof v === 'string')` is `v !== undefined &&
111
+ * typeof v !== 'string'` — so no validator's behaviour moved. Read the module
112
+ * docblock before tightening it.
113
+ */
114
+ export function isWireRequestIdShape(v) {
115
+ return v === undefined || typeof v === 'string';
116
+ }
117
+ //# sourceMappingURL=requestId.js.map
@@ -325,6 +325,10 @@ export declare function isValidPublishResult(p: unknown): boolean;
325
325
  * with neither is malformed and dropped. Each image is shape-checked via
326
326
  * {@link isValidGatedImage} — a `hidden` entry that carries a `url` DROPS the whole
327
327
  * reply (defense in depth against a leaked unclamped url).
328
+ *
329
+ * Validation only. The `hidden` ALLOWLIST is applied separately, by
330
+ * {@link projectInboundPayload} → {@link projectGatedImage}, after this returns
331
+ * true.
328
332
  */
329
333
  export declare function isValidImagesResult(p: unknown): boolean;
330
334
  /**
@@ -458,12 +462,42 @@ export declare function isValidResourcePickerResult(p: unknown): boolean;
458
462
  * (module header) — mirrors `isValidSharedUpdateResult`.
459
463
  */
460
464
  export declare function isValidUserCheckpointSetResult(p: unknown): boolean;
465
+ /**
466
+ * Narrow an already-VALIDATED inbound payload to the fields a consumer is
467
+ * allowed to see, immediately before `iframeTransport` hands it to a pending
468
+ * request or a push listener.
469
+ *
470
+ * Validation answers "may this message be delivered at all"; projection answers
471
+ * "which of its fields may cross". They are deliberately separate steps: a
472
+ * predicate can only ever say yes/no about the WHOLE reply, so expressing an
473
+ * allowlist as a predicate makes one unexpected key fatal to every entry in the
474
+ * batch. See {@link projectGatedImage} for the concrete case and the hang it
475
+ * avoids.
476
+ *
477
+ * 🔴 SCOPE, STATED HONESTLY: `IMAGES_RESULT` is the ONLY type projected today.
478
+ * Every other type is returned by identity — this is not a general sanitizer and
479
+ * must not be read as one. Add a case here (and say so in the type's validator
480
+ * docblock) if another message ever needs one.
481
+ */
482
+ export declare function projectInboundPayload(type: string, payload: unknown): unknown;
461
483
  /**
462
484
  * Returns the validator for an inbound message type, or `null` for types
463
485
  * that don't carry a payload requiring shape checks (SUSPEND/RESUME).
464
486
  *
465
487
  * Falsy result from the validator means "drop the message"; `iframeTransport`
466
488
  * pairs that with a `console.warn` carrying the type name.
489
+ *
490
+ * 🔴 EXHAUSTIVE OVER `ParentToBlockMessage` AT COMPILE TIME. The `default:` arm
491
+ * binds the switch subject to `never`, so a union member with no `case` above
492
+ * fails `tsc` with `Type '"NEW_TYPE"' is not assignable to type 'never'`. Adding
493
+ * a message type to the protocol and forgetting its validator is therefore a
494
+ * BUILD error, not a silent unvalidated path.
495
+ *
496
+ * ⚠️ The gate proves the type is MAPPED, not that it is mapped to the RIGHT
497
+ * validator, and not that it is mapped to a validator at all rather than to
498
+ * `null` — `case 'NEW_TYPE': return null;` satisfies it. `validate.test.ts`
499
+ * covers that residual by asserting a validator (not `null`) for every
500
+ * payload-carrying type, plus identity for the highest-stakes few.
467
501
  */
468
502
  export declare function payloadValidatorFor(type: string): ((payload: unknown) => boolean) | null;
469
503
  //# sourceMappingURL=validate.d.ts.map