@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.
- package/README.md +34 -2
- package/dist/api/generationResources.d.ts +4 -3
- package/dist/hooks/returnTypeLedger.d.ts +2 -0
- package/dist/hooks/returnTypeLedger.js +2 -0
- package/dist/hooks/useAppStorage.js +2 -2
- package/dist/hooks/useAppWorkflows.d.ts +5 -2
- package/dist/hooks/useAppWorkflows.js +18 -7
- package/dist/hooks/useBlockAnalytics.d.ts +5 -3
- package/dist/hooks/useBlockAnalytics.js +1 -1
- package/dist/hooks/useBlockBreakpoint.d.ts +7 -1
- package/dist/hooks/useBlockContext.d.ts +13 -2
- package/dist/hooks/useBlockContext.js +1 -1
- package/dist/hooks/useBlockResize.d.ts +7 -1
- package/dist/hooks/useBlockResize.js +1 -1
- package/dist/hooks/useBlockSettings.d.ts +6 -1
- package/dist/hooks/useBlockTheme.d.ts +6 -1
- package/dist/hooks/useBlockToken.d.ts +8 -3
- package/dist/hooks/useBlockToken.js +2 -2
- package/dist/hooks/useBuzzAccounts.d.ts +3 -2
- package/dist/hooks/useBuzzAccounts.js +16 -15
- package/dist/hooks/useBuzzBalance.d.ts +3 -2
- package/dist/hooks/useBuzzBalance.js +16 -18
- package/dist/hooks/useBuzzPurchase.d.ts +8 -6
- package/dist/hooks/useBuzzPurchase.js +3 -3
- package/dist/hooks/useBuzzTransactions.d.ts +4 -2
- package/dist/hooks/useBuzzTransactions.js +16 -15
- package/dist/hooks/useBuzzWorkflow.d.ts +71 -28
- package/dist/hooks/useBuzzWorkflow.js +31 -17
- package/dist/hooks/useCheckpointPicker.d.ts +18 -16
- package/dist/hooks/useCheckpointPicker.js +3 -3
- package/dist/hooks/useCivitaiNavigate.d.ts +5 -3
- package/dist/hooks/useCivitaiNavigate.js +1 -1
- package/dist/hooks/useCollectionFollow.js +4 -4
- package/dist/hooks/useConsentUnavailable.js +2 -2
- package/dist/hooks/useCreatePostFromApp.js +4 -4
- package/dist/hooks/useDailyCompensation.d.ts +4 -2
- package/dist/hooks/useDailyCompensation.js +17 -15
- package/dist/hooks/useDirectLoad.d.ts +7 -1
- package/dist/hooks/useDirectLoad.js +1 -1
- package/dist/hooks/useDomainMaturity.d.ts +6 -2
- package/dist/hooks/useGatedImages.d.ts +8 -0
- package/dist/hooks/useGatedImages.js +10 -2
- package/dist/hooks/useGenerationResources.d.ts +5 -3
- package/dist/hooks/useHostOrigin.d.ts +7 -1
- package/dist/hooks/useHostOrigin.js +1 -1
- package/dist/hooks/useImageUpload.d.ts +44 -17
- package/dist/hooks/useImageUpload.js +24 -4
- package/dist/hooks/usePublishGenerationOutputs.js +4 -4
- package/dist/hooks/useRequestConsent.d.ts +7 -5
- package/dist/hooks/useRequestConsent.js +1 -1
- package/dist/hooks/useRequestSequencer.d.ts +71 -0
- package/dist/hooks/useRequestSequencer.js +28 -0
- package/dist/hooks/useRequestSignIn.d.ts +7 -5
- package/dist/hooks/useRequestSignIn.js +1 -1
- package/dist/hooks/useResourcePicker.d.ts +16 -14
- package/dist/hooks/useResourcePicker.js +3 -3
- package/dist/hooks/useSaveImage.js +2 -2
- package/dist/hooks/useSharedStorage.js +2 -2
- package/dist/hooks/useTip.js +1 -1
- package/dist/hooks/useTipAllowance.d.ts +13 -1
- package/dist/hooks/useTipAllowance.js +49 -11
- package/dist/hooks/useViewer.d.ts +3 -2
- package/dist/hooks/useViewer.js +16 -18
- package/dist/hooks/useWildcardPack.d.ts +3 -1
- package/dist/hooks/useWildcardPack.js +19 -14
- package/dist/index.d.ts +30 -14
- package/dist/index.js +7 -7
- package/dist/internal/consentRefusalLatch.d.ts +1 -1
- package/dist/internal/consentRefusalLatch.js +1 -1
- package/dist/internal/liveHost.d.ts +63 -11
- package/dist/internal/liveHost.js +240 -37
- package/dist/internal/mockHost.js +16 -15
- package/dist/internal/pickerOverlay.d.ts +52 -4
- package/dist/internal/pickerOverlay.js +14 -3
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{internal → transport}/iframeTransport.d.ts +43 -5
- package/dist/{internal → transport}/iframeTransport.js +142 -12
- package/dist/transport/originMatcher.d.ts +92 -0
- package/dist/transport/originMatcher.js +222 -0
- package/dist/transport/requestId.d.ts +113 -0
- package/dist/transport/requestId.js +117 -0
- package/dist/{internal → transport}/validate.d.ts +34 -0
- package/dist/{internal → transport}/validate.js +189 -48
- package/dist/ui/BlockGate.js +1 -1
- package/dist/ui/SettingsForm.d.ts +8 -2
- package/dist/ui/SettingsForm.js +49 -3
- package/package.json +7 -148
- package/dist/api/generationResources.d.ts.map +0 -1
- package/dist/api/generationResources.js.map +0 -1
- package/dist/hooks/SfwGate.d.ts.map +0 -1
- package/dist/hooks/SfwGate.js.map +0 -1
- package/dist/hooks/useAppStorage.d.ts.map +0 -1
- package/dist/hooks/useAppStorage.js.map +0 -1
- package/dist/hooks/useAppWorkflows.d.ts.map +0 -1
- package/dist/hooks/useAppWorkflows.js.map +0 -1
- package/dist/hooks/useBlockAnalytics.d.ts.map +0 -1
- package/dist/hooks/useBlockAnalytics.js.map +0 -1
- package/dist/hooks/useBlockBreakpoint.d.ts.map +0 -1
- package/dist/hooks/useBlockBreakpoint.js.map +0 -1
- package/dist/hooks/useBlockContext.d.ts.map +0 -1
- package/dist/hooks/useBlockContext.js.map +0 -1
- package/dist/hooks/useBlockResize.d.ts.map +0 -1
- package/dist/hooks/useBlockResize.js.map +0 -1
- package/dist/hooks/useBlockSettings.d.ts.map +0 -1
- package/dist/hooks/useBlockSettings.js.map +0 -1
- package/dist/hooks/useBlockTheme.d.ts.map +0 -1
- package/dist/hooks/useBlockTheme.js.map +0 -1
- package/dist/hooks/useBlockToken.d.ts.map +0 -1
- package/dist/hooks/useBlockToken.js.map +0 -1
- package/dist/hooks/useBuzzAccounts.d.ts.map +0 -1
- package/dist/hooks/useBuzzAccounts.js.map +0 -1
- package/dist/hooks/useBuzzBalance.d.ts.map +0 -1
- package/dist/hooks/useBuzzBalance.js.map +0 -1
- package/dist/hooks/useBuzzPurchase.d.ts.map +0 -1
- package/dist/hooks/useBuzzPurchase.js.map +0 -1
- package/dist/hooks/useBuzzTransactions.d.ts.map +0 -1
- package/dist/hooks/useBuzzTransactions.js.map +0 -1
- package/dist/hooks/useBuzzWorkflow.d.ts.map +0 -1
- package/dist/hooks/useBuzzWorkflow.js.map +0 -1
- package/dist/hooks/useCheckpointPicker.d.ts.map +0 -1
- package/dist/hooks/useCheckpointPicker.js.map +0 -1
- package/dist/hooks/useCivitaiNavigate.d.ts.map +0 -1
- package/dist/hooks/useCivitaiNavigate.js.map +0 -1
- package/dist/hooks/useCollectionFollow.d.ts.map +0 -1
- package/dist/hooks/useCollectionFollow.js.map +0 -1
- package/dist/hooks/useConsentUnavailable.d.ts.map +0 -1
- package/dist/hooks/useConsentUnavailable.js.map +0 -1
- package/dist/hooks/useCreatePostFromApp.d.ts.map +0 -1
- package/dist/hooks/useCreatePostFromApp.js.map +0 -1
- package/dist/hooks/useDailyCompensation.d.ts.map +0 -1
- package/dist/hooks/useDailyCompensation.js.map +0 -1
- package/dist/hooks/useDirectLoad.d.ts.map +0 -1
- package/dist/hooks/useDirectLoad.js.map +0 -1
- package/dist/hooks/useDomainMaturity.d.ts.map +0 -1
- package/dist/hooks/useDomainMaturity.js.map +0 -1
- package/dist/hooks/useGatedImages.d.ts.map +0 -1
- package/dist/hooks/useGatedImages.js.map +0 -1
- package/dist/hooks/useGenerationResources.d.ts.map +0 -1
- package/dist/hooks/useGenerationResources.js.map +0 -1
- package/dist/hooks/useHostOrigin.d.ts.map +0 -1
- package/dist/hooks/useHostOrigin.js.map +0 -1
- package/dist/hooks/useImageUpload.d.ts.map +0 -1
- package/dist/hooks/useImageUpload.js.map +0 -1
- package/dist/hooks/usePublishGenerationOutputs.d.ts.map +0 -1
- package/dist/hooks/usePublishGenerationOutputs.js.map +0 -1
- package/dist/hooks/useRequestConsent.d.ts.map +0 -1
- package/dist/hooks/useRequestConsent.js.map +0 -1
- package/dist/hooks/useRequestSignIn.d.ts.map +0 -1
- package/dist/hooks/useRequestSignIn.js.map +0 -1
- package/dist/hooks/useResourcePicker.d.ts.map +0 -1
- package/dist/hooks/useResourcePicker.js.map +0 -1
- package/dist/hooks/useSaveImage.d.ts.map +0 -1
- package/dist/hooks/useSaveImage.js.map +0 -1
- package/dist/hooks/useSharedStorage.d.ts.map +0 -1
- package/dist/hooks/useSharedStorage.js.map +0 -1
- package/dist/hooks/useTip.d.ts.map +0 -1
- package/dist/hooks/useTip.js.map +0 -1
- package/dist/hooks/useTipAllowance.d.ts.map +0 -1
- package/dist/hooks/useTipAllowance.js.map +0 -1
- package/dist/hooks/useViewer.d.ts.map +0 -1
- package/dist/hooks/useViewer.js.map +0 -1
- package/dist/hooks/useWildcardPack.d.ts.map +0 -1
- package/dist/hooks/useWildcardPack.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal/catalog.d.ts.map +0 -1
- package/dist/internal/catalog.js.map +0 -1
- package/dist/internal/consent.d.ts.map +0 -1
- package/dist/internal/consent.js.map +0 -1
- package/dist/internal/consentRefusalLatch.d.ts.map +0 -1
- package/dist/internal/consentRefusalLatch.js.map +0 -1
- package/dist/internal/detector.d.ts.map +0 -1
- package/dist/internal/detector.js.map +0 -1
- package/dist/internal/directLoad.d.ts.map +0 -1
- package/dist/internal/directLoad.js.map +0 -1
- package/dist/internal/iframeTransport.d.ts.map +0 -1
- package/dist/internal/iframeTransport.js.map +0 -1
- package/dist/internal/inlineTransport.d.ts.map +0 -1
- package/dist/internal/inlineTransport.js.map +0 -1
- package/dist/internal/liveHost.d.ts.map +0 -1
- package/dist/internal/liveHost.js.map +0 -1
- package/dist/internal/mockHost.d.ts.map +0 -1
- package/dist/internal/mockHost.js.map +0 -1
- package/dist/internal/originMatcher.d.ts +0 -28
- package/dist/internal/originMatcher.d.ts.map +0 -1
- package/dist/internal/originMatcher.js +0 -89
- package/dist/internal/originMatcher.js.map +0 -1
- package/dist/internal/pickerOverlay.d.ts.map +0 -1
- package/dist/internal/pickerOverlay.js.map +0 -1
- package/dist/internal/replyError.d.ts.map +0 -1
- package/dist/internal/replyError.js.map +0 -1
- package/dist/internal/requestTimeouts.d.ts.map +0 -1
- package/dist/internal/requestTimeouts.js.map +0 -1
- package/dist/internal/singleton.d.ts.map +0 -1
- package/dist/internal/singleton.js.map +0 -1
- package/dist/internal/transport.d.ts.map +0 -1
- package/dist/internal/transport.js.map +0 -1
- package/dist/internal/validate.d.ts.map +0 -1
- package/dist/internal/validate.js.map +0 -1
- package/dist/live.d.ts.map +0 -1
- package/dist/live.js.map +0 -1
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js.map +0 -1
- package/dist/ui/Alert.d.ts.map +0 -1
- package/dist/ui/Alert.js.map +0 -1
- package/dist/ui/Badge.d.ts.map +0 -1
- package/dist/ui/Badge.js.map +0 -1
- package/dist/ui/BlockGate.d.ts.map +0 -1
- package/dist/ui/BlockGate.js.map +0 -1
- package/dist/ui/Button.d.ts.map +0 -1
- package/dist/ui/Button.js.map +0 -1
- package/dist/ui/Card.d.ts.map +0 -1
- package/dist/ui/Card.js.map +0 -1
- package/dist/ui/Collapse.d.ts.map +0 -1
- package/dist/ui/Collapse.js.map +0 -1
- package/dist/ui/FollowButton.d.ts.map +0 -1
- package/dist/ui/FollowButton.js.map +0 -1
- package/dist/ui/Group.d.ts.map +0 -1
- package/dist/ui/Group.js.map +0 -1
- package/dist/ui/Loader.d.ts.map +0 -1
- package/dist/ui/Loader.js.map +0 -1
- package/dist/ui/Modal.d.ts.map +0 -1
- package/dist/ui/Modal.js.map +0 -1
- package/dist/ui/NumberInput.d.ts.map +0 -1
- package/dist/ui/NumberInput.js.map +0 -1
- package/dist/ui/ReportButton.d.ts.map +0 -1
- package/dist/ui/ReportButton.js.map +0 -1
- package/dist/ui/ResourceCard.d.ts.map +0 -1
- package/dist/ui/ResourceCard.js.map +0 -1
- package/dist/ui/SegmentedControl.d.ts.map +0 -1
- package/dist/ui/SegmentedControl.js.map +0 -1
- package/dist/ui/Select.d.ts.map +0 -1
- package/dist/ui/Select.js.map +0 -1
- package/dist/ui/SettingsForm.d.ts.map +0 -1
- package/dist/ui/SettingsForm.js.map +0 -1
- package/dist/ui/Slider.d.ts.map +0 -1
- package/dist/ui/Slider.js.map +0 -1
- package/dist/ui/Stack.d.ts.map +0 -1
- package/dist/ui/Stack.js.map +0 -1
- package/dist/ui/TextInput.d.ts.map +0 -1
- package/dist/ui/TextInput.js.map +0 -1
- package/dist/ui/Textarea.d.ts.map +0 -1
- package/dist/ui/Textarea.js.map +0 -1
- package/dist/ui/TipButton.d.ts.map +0 -1
- package/dist/ui/TipButton.js.map +0 -1
- package/dist/ui/index.d.ts.map +0 -1
- package/dist/ui/index.js.map +0 -1
- package/dist/ui/styles.d.ts.map +0 -1
- package/dist/ui/styles.js.map +0 -1
- /package/dist/{internal → transport}/detector.d.ts +0 -0
- /package/dist/{internal → transport}/detector.js +0 -0
- /package/dist/{internal → transport}/directLoad.d.ts +0 -0
- /package/dist/{internal → transport}/directLoad.js +0 -0
- /package/dist/{internal → transport}/inlineTransport.d.ts +0 -0
- /package/dist/{internal → transport}/inlineTransport.js +0 -0
- /package/dist/{internal → transport}/requestTimeouts.d.ts +0 -0
- /package/dist/{internal → transport}/requestTimeouts.js +0 -0
- /package/dist/{internal → transport}/singleton.d.ts +0 -0
- /package/dist/{internal → transport}/singleton.js +0 -0
- /package/dist/{internal → transport}/transport.d.ts +0 -0
- /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
|