@flamingo-stack/openframe-frontend-core 0.0.854 → 0.0.856
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/dist/build/export-map.json +1 -1
- package/dist/{case-study-card-WP5Z234Q.cjs → case-study-card-6VAMNHLU.cjs} +8 -8
- package/dist/{chunk-ZDPPNHA2.cjs → chunk-2BTEERLH.cjs} +3 -3
- package/dist/{chunk-FBANHIAG.cjs → chunk-2JCA7BRK.cjs} +19 -19
- package/dist/{chunk-GVHCQRUE.cjs → chunk-2P72KAG5.cjs} +23 -23
- package/dist/{chunk-YY3WP2YQ.cjs → chunk-3GJ75OUL.cjs} +183 -183
- package/dist/{chunk-FJXSKMQJ.cjs → chunk-4H3J57AN.cjs} +25 -25
- package/dist/{chunk-6GWRPW6B.cjs → chunk-5NK3FUHY.cjs} +4 -4
- package/dist/{chunk-DLTPSP5F.cjs → chunk-5TYG5JNB.cjs} +2 -2
- package/dist/{chunk-63ZV3UGG.cjs → chunk-65NMKAPQ.cjs} +12 -12
- package/dist/{chunk-IGVAPIEW.cjs → chunk-6C4OR4MZ.cjs} +2 -2
- package/dist/{chunk-GG466XFQ.cjs → chunk-6DMH4GXN.cjs} +30 -5
- package/dist/{chunk-2IJMHBOK.cjs → chunk-77GX573I.cjs} +9 -9
- package/dist/{chunk-O3EKOXFZ.cjs → chunk-AYMY2VNB.cjs} +37 -43
- package/dist/{chunk-JKBNK5U6.cjs → chunk-D6GEMVHD.cjs} +3 -3
- package/dist/{chunk-SSKMGH5O.cjs → chunk-DXVGGWLG.cjs} +10 -10
- package/dist/{chunk-S5P6CF5R.cjs → chunk-E5OQHFM6.cjs} +54 -54
- package/dist/{chunk-5TXE7BXT.cjs → chunk-EOUEUYCQ.cjs} +54 -54
- package/dist/{chunk-EIHMPQRQ.cjs → chunk-ESGE7CUX.cjs} +14 -14
- package/dist/{chunk-ETZFBB7O.cjs → chunk-EXQSIX2I.cjs} +4 -4
- package/dist/{chunk-3WXHPD6N.cjs → chunk-F33EAPD2.cjs} +124 -124
- package/dist/{chunk-4SSJ3T3N.cjs → chunk-GK577ZLJ.cjs} +3 -13
- package/dist/{chunk-ETQNMR2K.cjs → chunk-GTUQGVXH.cjs} +8 -8
- package/dist/{chunk-7MOBD44H.cjs → chunk-HGM7WDJT.cjs} +28 -28
- package/dist/{chunk-VMAOZA2V.cjs → chunk-HML3JUXF.cjs} +324 -322
- package/dist/{chunk-4O5N5CGK.cjs → chunk-J3CFRGZ2.cjs} +17 -17
- package/dist/{chunk-LQDAB5V5.cjs → chunk-KZAQPRTA.cjs} +9 -11
- package/dist/{chunk-6DCUGIGU.cjs → chunk-LSLRJJFP.cjs} +2 -2
- package/dist/{chunk-ONYANAMA.cjs → chunk-MX52LZ6M.cjs} +6 -6
- package/dist/{chunk-OH5TXFRR.cjs → chunk-O4CPT3RK.cjs} +7 -7
- package/dist/{chunk-BAA3YCLT.cjs → chunk-OW5MQKCI.cjs} +103 -103
- package/dist/{chunk-5HMENXSR.cjs → chunk-PCQ2HKU3.cjs} +5 -5
- package/dist/{chunk-D2XGRWPW.cjs → chunk-QLFNMWBP.cjs} +90 -90
- package/dist/{chunk-UPQ4MAR7.cjs → chunk-QZXCUY36.cjs} +53 -53
- package/dist/{chunk-KKFDRCQF.cjs → chunk-RY7INTYU.cjs} +14 -1
- package/dist/{chunk-PRJZMZ3X.cjs → chunk-SJZWVMBF.cjs} +678 -678
- package/dist/{chunk-GI3MMBP3.cjs → chunk-SQ7YHWEP.cjs} +228 -15
- package/dist/{chunk-ACPOJE32.cjs → chunk-STV6VJ3U.cjs} +21 -21
- package/dist/{chunk-QD727QFI.cjs → chunk-T54I5ZZY.cjs} +7 -7
- package/dist/{chunk-4LTLEUY5.cjs → chunk-TW5Y4D5I.cjs} +7 -7
- package/dist/{chunk-6XU3RCK3.cjs → chunk-UHGARY3S.cjs} +27 -27
- package/dist/{chunk-7J5NSWJG.cjs → chunk-UZIGMLTH.cjs} +100 -100
- package/dist/{chunk-FX35L4Y6.cjs → chunk-XCQ5I27Z.cjs} +3 -3
- package/dist/{chunk-5OENPMRU.cjs → chunk-XI3AMOW6.cjs} +65 -62
- package/dist/{chunk-TMPLHUUU.cjs → chunk-XTLMWLFB.cjs} +6 -6
- package/dist/{chunk-AZEO7HBB.cjs → chunk-Y44EF4JW.cjs} +2 -2
- package/dist/{chunk-RMI6O3AE.cjs → chunk-YB244RRB.cjs} +36 -36
- package/dist/{chunk-KA3L6D5N.cjs → chunk-YSXVRTGT.cjs} +9 -12
- package/dist/{chunk-H3GBPYPS.cjs → chunk-ZYAVIRQV.cjs} +25 -25
- package/dist/{cloud-tenants-5RNK4ZAT.cjs → cloud-tenants-J5T4YL2P.cjs} +28 -29
- package/dist/components/case-studies/index.cjs +44 -45
- package/dist/components/chat/chat-message-row.d.ts +1 -1
- package/dist/components/chat/chat-message-row.d.ts.map +1 -1
- package/dist/components/chat/chat-message-row.js +4 -4
- package/dist/components/chat/entity-cards/use-cover-image-fallback.d.ts +7 -13
- package/dist/components/chat/entity-cards/use-cover-image-fallback.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/use-cover-image-fallback.js +2 -8
- package/dist/components/chat/hooks/use-chat-attachment-image-gallery.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-chat-attachment-image-gallery.js +8 -4
- package/dist/components/chat/index.cjs +22 -23
- package/dist/components/contact/index.cjs +29 -30
- package/dist/components/docs/index.cjs +32 -33
- package/dist/components/embeds/index.cjs +29 -30
- package/dist/components/faq/index.cjs +30 -31
- package/dist/components/features/index.cjs +28 -29
- package/dist/components/features/remote-session/remote-session-viewers.d.ts +6 -1
- package/dist/components/features/remote-session/remote-session-viewers.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-viewers.js +10 -3
- package/dist/components/help-center-pages/index.cjs +134 -135
- package/dist/components/index.cjs +112 -113
- package/dist/components/meeting-scheduler/index.cjs +102 -103
- package/dist/components/navigation/index.cjs +31 -32
- package/dist/components/onboarding-guides/index.cjs +31 -32
- package/dist/components/product-demo/index.cjs +39 -40
- package/dist/components/related-content/index.cjs +16 -17
- package/dist/components/tickets/index.cjs +35 -36
- package/dist/components/ui/entity-image.d.ts +1 -2
- package/dist/components/ui/entity-image.d.ts.map +1 -1
- package/dist/components/ui/entity-image.js +4 -8
- package/dist/components/ui/index.cjs +28 -29
- package/dist/components/ui/markdown/base-components.d.ts +0 -13
- package/dist/components/ui/markdown/base-components.d.ts.map +1 -1
- package/dist/components/ui/markdown/base-components.js +7 -7
- package/dist/components/ui/square-avatar.d.ts.map +1 -1
- package/dist/components/ui/square-avatar.js +3 -8
- package/dist/{devices-44O5PZOW.cjs → devices-IJDF7SSK.cjs} +29 -30
- package/dist/embed-shims/index.cjs +3 -2
- package/dist/embed-shims/next-image.cjs +3 -2
- package/dist/embed-shims/next-image.d.ts +2 -0
- package/dist/embed-shims/next-image.d.ts.map +1 -1
- package/dist/embed-shims/next-image.js +14 -4
- package/dist/{embeddable-chat-W3CLMGC3.cjs → embeddable-chat-QD7NFD2H.cjs} +100 -101
- package/dist/hooks/index.cjs +23 -16
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/use-authed-asset-src.d.ts +77 -2
- package/dist/hooks/use-authed-asset-src.d.ts.map +1 -1
- package/dist/hooks/use-authed-asset-src.js +185 -73
- package/dist/hooks/use-authed-image-src.d.ts +11 -4
- package/dist/hooks/use-authed-image-src.d.ts.map +1 -1
- package/dist/hooks/use-authed-image-src.js +6 -2
- package/dist/hooks/use-image-fallback.d.ts +16 -0
- package/dist/hooks/use-image-fallback.d.ts.map +1 -0
- package/dist/hooks/use-image-fallback.js +14 -0
- package/dist/index.cjs +40 -36
- package/dist/{knowledge-UUU3WVO3.cjs → knowledge-5LIK6Q4E.cjs} +29 -30
- package/dist/{logs-DFHNSODA.cjs → logs-FMENCAXT.cjs} +35 -36
- package/dist/{policies-RGFUGDBP.cjs → policies-DKQEEKB4.cjs} +32 -33
- package/dist/{remote-session-U3H77HKR.cjs → remote-session-6X7CAHBC.cjs} +13 -14
- package/dist/{scripts-KOVO5DHW.cjs → scripts-4EPUIFHF.cjs} +35 -36
- package/dist/{software-update-4EKHVV5W.cjs → software-update-IMNRXBAI.cjs} +32 -33
- package/dist/{tickets-board-YIFOVMDX.cjs → tickets-board-POYZS7BW.cjs} +16 -17
- package/dist/utils/app-origins.d.ts +3 -6
- package/dist/utils/app-origins.d.ts.map +1 -1
- package/dist/utils/app-origins.js +8 -1
- package/dist/utils/embed-authed-fetch.d.ts +46 -26
- package/dist/utils/embed-authed-fetch.d.ts.map +1 -1
- package/dist/utils/embed-authed-fetch.js +24 -8
- package/dist/utils/index.cjs +4 -1
- package/dist/{video-file-player-XMOB234V.cjs → video-file-player-RIOT24NT.cjs} +3 -4
- package/package.json +1 -1
- package/src/components/chat/chat-message-row.tsx +8 -7
- package/src/components/chat/entity-cards/use-cover-image-fallback.ts +8 -28
- package/src/components/chat/hooks/use-chat-attachment-image-gallery.tsx +19 -8
- package/src/components/features/remote-session/remote-session-viewers.tsx +16 -3
- package/src/components/ui/entity-image.tsx +4 -12
- package/src/components/ui/markdown/base-components.tsx +15 -20
- package/src/components/ui/square-avatar.tsx +5 -8
- package/src/embed-shims/next-image.tsx +34 -3
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-authed-asset-src.ts +323 -107
- package/src/hooks/use-authed-image-src.ts +15 -5
- package/src/hooks/use-image-fallback.ts +31 -0
- package/src/utils/app-origins.ts +12 -7
- package/src/utils/embed-authed-fetch.ts +71 -32
- package/dist/chunk-YSDB6HGQ.cjs +0 -102
package/dist/hooks/index.cjs
CHANGED
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
var
|
|
64
|
+
var _chunkQZXCUY36cjs = require('../chunk-QZXCUY36.cjs');
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
var _chunk24I6RFVUcjs = require('../chunk-24I6RFVU.cjs');
|
|
@@ -70,9 +70,9 @@ var _chunk24I6RFVUcjs = require('../chunk-24I6RFVU.cjs');
|
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
var
|
|
73
|
+
var _chunkPCQ2HKU3cjs = require('../chunk-PCQ2HKU3.cjs');
|
|
74
74
|
require('../chunk-MZ4KBSH7.cjs');
|
|
75
|
-
require('../chunk-
|
|
75
|
+
require('../chunk-O4CPT3RK.cjs');
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
|
|
@@ -84,15 +84,15 @@ require('../chunk-OH5TXFRR.cjs');
|
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
|
|
87
|
-
var
|
|
87
|
+
var _chunk77GX573Icjs = require('../chunk-77GX573I.cjs');
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
var
|
|
95
|
-
require('../chunk-
|
|
94
|
+
var _chunkD6GEMVHDcjs = require('../chunk-D6GEMVHD.cjs');
|
|
95
|
+
require('../chunk-6C4OR4MZ.cjs');
|
|
96
96
|
require('../chunk-JKX2C3I2.cjs');
|
|
97
97
|
require('../chunk-WWUSFOJ7.cjs');
|
|
98
98
|
require('../chunk-SKI6NKOE.cjs');
|
|
@@ -111,7 +111,7 @@ var _chunkBLH2SFOOcjs = require('../chunk-BLH2SFOO.cjs');
|
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
|
|
114
|
-
var
|
|
114
|
+
var _chunkT54I5ZZYcjs = require('../chunk-T54I5ZZY.cjs');
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
|
|
@@ -119,29 +119,33 @@ var _chunkQD727QFIcjs = require('../chunk-QD727QFI.cjs');
|
|
|
119
119
|
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
var _chunkGK577ZLJcjs = require('../chunk-GK577ZLJ.cjs');
|
|
122
123
|
|
|
123
124
|
|
|
124
|
-
var _chunk4SSJ3T3Ncjs = require('../chunk-4SSJ3T3N.cjs');
|
|
125
125
|
|
|
126
|
+
var _chunkEXQSIX2Icjs = require('../chunk-EXQSIX2I.cjs');
|
|
126
127
|
|
|
127
128
|
|
|
128
129
|
|
|
129
|
-
var
|
|
130
|
+
var _chunkXCQ5I27Zcjs = require('../chunk-XCQ5I27Z.cjs');
|
|
130
131
|
|
|
131
132
|
|
|
133
|
+
var _chunkRY7INTYUcjs = require('../chunk-RY7INTYU.cjs');
|
|
132
134
|
|
|
133
|
-
var _chunkETZFBB7Ocjs = require('../chunk-ETZFBB7O.cjs');
|
|
134
135
|
|
|
135
136
|
|
|
137
|
+
var _chunkNTPX5GXIcjs = require('../chunk-NTPX5GXI.cjs');
|
|
136
138
|
|
|
137
|
-
var _chunkFX35L4Y6cjs = require('../chunk-FX35L4Y6.cjs');
|
|
138
|
-
require('../chunk-KKFDRCQF.cjs');
|
|
139
139
|
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
var
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
var _chunk6DMH4GXNcjs = require('../chunk-6DMH4GXN.cjs');
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
var _chunkSQ7YHWEPcjs = require('../chunk-SQ7YHWEP.cjs');
|
|
145
149
|
require('../chunk-UJ7AXHRZ.cjs');
|
|
146
150
|
require('../chunk-PMUCEUFQ.cjs');
|
|
147
151
|
require('../chunk-FCZAUK4D.cjs');
|
|
@@ -258,4 +262,7 @@ require('../chunk-QDB2JO55.cjs');
|
|
|
258
262
|
|
|
259
263
|
|
|
260
264
|
|
|
261
|
-
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
exports.AGENT_IDENTITIES_API_PATH = _chunkXCQ5I27Zcjs.AGENT_IDENTITIES_API_PATH; exports.CONTENT_BREAKPOINTS = _chunkT54I5ZZYcjs.CONTENT_BREAKPOINTS; exports.ContentAreaWidthContext = _chunkT54I5ZZYcjs.ContentAreaWidthContext; exports.DRAG_AND_DROP_MEDIA_QUERY = _chunkPCQ2HKU3cjs.DRAG_AND_DROP_MEDIA_QUERY; exports.GraphQLIntrospector = _chunkQZXCUY36cjs.GraphQLIntrospector; exports.HOVER_MEDIA_QUERY = _chunkD6GEMVHDcjs.HOVER_MEDIA_QUERY; exports.MEASURE_LAYER_CLASS = _chunkD6GEMVHDcjs.MEASURE_LAYER_CLASS; exports.NEAR_VIEWPORT_ROOT_MARGIN = _chunkNTPX5GXIcjs.NEAR_VIEWPORT_ROOT_MARGIN; exports.PREFERS_REDUCED_MOTION_QUERY = _chunk77GX573Icjs.PREFERS_REDUCED_MOTION_QUERY; exports.ViewportBreakpoints = _chunkT54I5ZZYcjs.ViewportBreakpoints; exports.batchFetchAuthenticatedImages = _chunkQZXCUY36cjs.batchFetchAuthenticatedImages; exports.breakpoints = _chunkGK577ZLJcjs.breakpoints; exports.clearAuthedAssetCache = _chunkSQ7YHWEPcjs.clearAuthedAssetCache; exports.clearAuthedImageCache = _chunk6DMH4GXNcjs.clearAuthedImageCache; exports.clearVariablesParams = _chunkQZXCUY36cjs.clearParams; exports.coerceValue = _chunkQZXCUY36cjs.coerceValue; exports.completeFormRescue = _chunkQZXCUY36cjs.completeFormRescue; exports.configureAuthenticatedImage = _chunkQZXCUY36cjs.configureAuthenticatedImage; exports.configureBatchImageFetch = _chunkQZXCUY36cjs.configureBatchImageFetch; exports.contentBreakpointFor = _chunkT54I5ZZYcjs.contentBreakpointFor; exports.contentStepFor = _chunkT54I5ZZYcjs.contentStepFor; exports.createSearchParams = _chunkBLH2SFOOcjs.createSearchParams; exports.extractVariablesFromQuery = _chunkQZXCUY36cjs.extractVariablesFromQuery; exports.flattenQueryVariables = _chunkQZXCUY36cjs.flattenQueryVariables; exports.getArrayParams = _chunkQZXCUY36cjs.getArrayParams; exports.getNestedValue = _chunkQZXCUY36cjs.getNestedValue; exports.getRequiredParams = _chunkQZXCUY36cjs.getRequiredParams; exports.introspector = _chunkQZXCUY36cjs.introspector; exports.isInputObjectType = _chunkQZXCUY36cjs.isInputObjectType; exports.isScalarType = _chunkQZXCUY36cjs.isScalarType; exports.mergeDefaults = _chunkQZXCUY36cjs.mergeDefaults; exports.mergeVariables = _chunkQZXCUY36cjs.mergeVariables; exports.resetDownloadsStore = _chunkQZXCUY36cjs.resetDownloadsStore; exports.resolveActiveSection = _chunkQZXCUY36cjs.resolveActiveSection; exports.setNestedValue = _chunkQZXCUY36cjs.setNestedValue; exports.shouldIncludeInUrl = _chunkBLH2SFOOcjs.shouldIncludeInUrl; exports.toast = _chunkQZXCUY36cjs.toast; exports.urlParamsToVariables = _chunkQZXCUY36cjs.urlParamsToVariables; exports.useAccessCodeIntegration = _chunkQZXCUY36cjs.useAccessCodeIntegration; exports.useActiveSection = _chunkQZXCUY36cjs.useActiveSection; exports.useAgentIdentities = _chunkXCQ5I27Zcjs.useAgentIdentities; exports.useApiParams = _chunkQZXCUY36cjs.useApiParams; exports.useAuthedAsset = _chunkSQ7YHWEPcjs.useAuthedAsset; exports.useAuthedAssetSrc = _chunkSQ7YHWEPcjs.useAuthedAssetSrc; exports.useAuthedImage = _chunk6DMH4GXNcjs.useAuthedImage; exports.useAuthedImageSrc = _chunk6DMH4GXNcjs.useAuthedImageSrc; exports.useAuthenticatedImage = _chunkQZXCUY36cjs.useAuthenticatedImage; exports.useAutoLimitTags = _chunkD6GEMVHDcjs.useAutoLimitTags; exports.useAutoplay = _chunk77GX573Icjs.useAutoplay; exports.useBatchImages = _chunkQZXCUY36cjs.useBatchImages; exports.useClaudeMirrorSrc = _chunkQZXCUY36cjs.useClaudeMirrorSrc; exports.useClippedLabelTooltip = _chunkD6GEMVHDcjs.useClippedLabelTooltip; exports.useContactSubmission = _chunkQZXCUY36cjs.useContactSubmission; exports.useContentBreakpoint = _chunkT54I5ZZYcjs.useContentBreakpoint; exports.useContentLgUp = _chunkT54I5ZZYcjs.useContentLgUp; exports.useContentMdUp = _chunkT54I5ZZYcjs.useContentMdUp; exports.useContentXlUp = _chunkT54I5ZZYcjs.useContentXlUp; exports.useCopyToClipboard = _chunkQZXCUY36cjs.useCopyToClipboard; exports.useCursorPaginationState = _chunkQZXCUY36cjs.useCursorPaginationState; exports.useDebounce = _chunk77GX573Icjs.useDebounce; exports.useDeferredError = _chunkQZXCUY36cjs.useDeferredError; exports.useDownloads = _chunkQZXCUY36cjs.useDownloads; exports.useDragAndDropEnabled = _chunkPCQ2HKU3cjs.useDragAndDropEnabled; exports.useFocusTrap = _chunkQZXCUY36cjs.useFocusTrap; exports.useFormRescue = _chunkQZXCUY36cjs.useFormRescue; exports.useHeaderHeight = _chunk24I6RFVUcjs.useHeaderHeight; exports.useHorizontalScrollbar = _chunkPCQ2HKU3cjs.useHorizontalScrollbar; exports.useHumanitySignals = _chunkQZXCUY36cjs.useHumanitySignals; exports.useImageEdgeColor = _chunkEXQSIX2Icjs.useImageEdgeColor; exports.useImageFallback = _chunkRY7INTYUcjs.useImageFallback; exports.useInView = _chunk77GX573Icjs.useInView; exports.useIsTruncated = _chunkGK577ZLJcjs.useIsTruncated; exports.useIsomorphicLayoutEffect = _chunkSQ7YHWEPcjs.useIsomorphicLayoutEffect; exports.useKeyboardCollisionPadding = _chunkD6GEMVHDcjs.useKeyboardCollisionPadding; exports.useLgUp = _chunkGK577ZLJcjs.useLgUp; exports.useLocalStorage = _chunkPCQ2HKU3cjs.useLocalStorage; exports.useLocationHash = _chunkQZXCUY36cjs.useLocationHash; exports.useMarqueeEngine = _chunk77GX573Icjs.useMarqueeEngine; exports.useMdUp = _chunkGK577ZLJcjs.useMdUp; exports.useMediaQuery = _chunkGK577ZLJcjs.useMediaQuery; exports.useMemoizedCallback = _chunkQZXCUY36cjs.useMemoizedCallback; exports.useNatsClient = _chunkQZXCUY36cjs.useNatsClient; exports.useNavMenus = _chunkQZXCUY36cjs.useNavMenus; exports.useNearViewport = _chunkNTPX5GXIcjs.useNearViewport; exports.useNotificationPermission = _chunkQZXCUY36cjs.useNotificationPermission; exports.useOgPlaceholderUrl = _chunkEXQSIX2Icjs.useOgPlaceholderUrl; exports.useOnboardingState = _chunkQZXCUY36cjs.useOnboardingState; exports.usePlatformByValue = _chunkQZXCUY36cjs.usePlatformByValue; exports.usePlatformConfig = _chunkQZXCUY36cjs.usePlatformConfig; exports.usePrefersReducedMotion = _chunk77GX573Icjs.usePrefersReducedMotion; exports.usePrefersReducedMotionState = _chunk77GX573Icjs.usePrefersReducedMotionState; exports.usePreventScroll = _chunkQZXCUY36cjs.usePreventScroll; exports.useQueryParams = _chunkQZXCUY36cjs.useQueryParams; exports.useRescuedForm = _chunkQZXCUY36cjs.useRescuedForm; exports.useResetOnPageHidden = _chunk77GX573Icjs.useResetOnPageHidden; exports.useResumableTimeout = _chunkQZXCUY36cjs.useResumableTimeout; exports.useScenarioPlayer = _chunkQZXCUY36cjs.useScenarioPlayer; exports.useScrollToHash = _chunkQZXCUY36cjs.useScrollToHash; exports.useSearch = _chunkQZXCUY36cjs.useSearch; exports.useSmUp = _chunkGK577ZLJcjs.useSmUp; exports.useStickyToolbar = _chunkQZXCUY36cjs.useStickyToolbar; exports.useSuppressCloneFocus = _chunk77GX573Icjs.useSuppressCloneFocus; exports.useTablePagination = _chunkQZXCUY36cjs.useTablePagination; exports.useThrottle = _chunkQZXCUY36cjs.useThrottle; exports.useToast = _chunkQZXCUY36cjs.useToast; exports.useValidatePlatform = _chunkQZXCUY36cjs.useValidatePlatform; exports.useVisitorDesktopDownload = _chunkQZXCUY36cjs.useVisitorDesktopDownload; exports.useVisitorOs = _chunk77GX573Icjs.useVisitorOs; exports.useWindowSize = _chunkQZXCUY36cjs.useWindowSize; exports.validateSchema = _chunkQZXCUY36cjs.validateSchema; exports.validateVariables = _chunkQZXCUY36cjs.validateVariables; exports.variablesToUrlParams = _chunkQZXCUY36cjs.variablesToUrlParams;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './use-batch-images';
|
|
|
9
9
|
export * from './use-authenticated-image';
|
|
10
10
|
export * from './use-authed-asset-src';
|
|
11
11
|
export * from './use-authed-image-src';
|
|
12
|
+
export * from './use-image-fallback';
|
|
12
13
|
export * from './state';
|
|
13
14
|
export * from './nats/use-nats-client';
|
|
14
15
|
export * from './use-near-viewport';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,cAAc,MAAM,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,cAAc,MAAM,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,SAAS,CAAC;AAGxB,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,uBAAuB,CAAC;AAMtC,cAAc,+BAA+B,CAAC;AAG9C,cAAc,0BAA0B,CAAC;AAIzC,cAAc,yBAAyB,CAAC;AAKxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AAIrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./use-batch-images.js";
|
|
|
9
9
|
export * from "./use-authenticated-image.js";
|
|
10
10
|
export * from "./use-authed-asset-src.js";
|
|
11
11
|
export * from "./use-authed-image-src.js";
|
|
12
|
+
export * from "./use-image-fallback.js";
|
|
12
13
|
export * from "./state/index.js";
|
|
13
14
|
export * from "./nats/use-nats-client.js";
|
|
14
15
|
export * from "./use-near-viewport.js";
|
|
@@ -1,9 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve ANY asset URL the browser would load natively — `<img src>`,
|
|
3
|
+
* `<track src>`, a font, a poster — on every host:
|
|
4
|
+
*
|
|
5
|
+
* 1. The host's `resolveAssetUrl` says where the URL lives, so a backend path
|
|
6
|
+
* the page's origin does not serve is drawn from the gateway.
|
|
7
|
+
* 2. Where auth rides in request HEADERS instead of cookies (native shells,
|
|
8
|
+
* `capacitor://` / `tauri://`, and dev-ticket web, both in bearer mode), a
|
|
9
|
+
* native subresource load can't carry the `Authorization` header and gets
|
|
10
|
+
* a 401. Such a URL is fetched through `embedAuthedFetch` (bearer + deduped
|
|
11
|
+
* 401-refresh-retry + the adapter's cross-origin guard) and drawn from a
|
|
12
|
+
* blob object-URL. Every other URL is drawn as it stands, so on the
|
|
13
|
+
* cookie-auth web this is a pass-through.
|
|
14
|
+
*
|
|
15
|
+
* The state lives in ONE module store read through `useSyncExternalStore`, so
|
|
16
|
+
* every mounted consumer follows it, memoized or not:
|
|
17
|
+
*
|
|
18
|
+
* - A shell renders before its tokens arrive. A gateway URL is then `pending`
|
|
19
|
+
* (nothing is drawn, nothing is requested) and is fetched as soon as the
|
|
20
|
+
* adapter reports a credential (`subscribeEmbedCredentialChange`), a new
|
|
21
|
+
* adapter registers, or a consumer renders and finds one. It used to be
|
|
22
|
+
* handed to a native `<img>` at that first render, which got a 401 and was
|
|
23
|
+
* never asked again.
|
|
24
|
+
* - `failed` is its own state, so a caller can show its fallback at once, and
|
|
25
|
+
* it stays `failed` while a retry runs. What is retried, and when:
|
|
26
|
+
* - no answer at all (offline, a refused redirect): on the next credential
|
|
27
|
+
* and when the browser comes back online;
|
|
28
|
+
* - a 401 that `embedAuthedFetch` could not refresh its way past (no new
|
|
29
|
+
* credential came of it): on the next credential;
|
|
30
|
+
* - anything else, including a 401 to the retry `embedAuthedFetch` sent
|
|
31
|
+
* with a credential it had just refreshed (`answeredAfterRefresh`): only
|
|
32
|
+
* when a consumer mounts again after every one let go. A new credential
|
|
33
|
+
* cannot lift that refusal, and retrying it on each rotation would rotate
|
|
34
|
+
* again: two such pictures would keep rotating the session between them.
|
|
35
|
+
* - `clearAuthedAssetCache` (session end) drops every blob; consumers still
|
|
36
|
+
* mounted go back to `pending` and fetch again with whatever credential the
|
|
37
|
+
* host holds when one next asks (see there).
|
|
38
|
+
* - A 2xx `text/html` answer is a failure, not a picture: a native shell's
|
|
39
|
+
* asset server answers an unknown path with its SPA page.
|
|
40
|
+
*
|
|
41
|
+
* Reading the state through the store also keeps it correct under the React
|
|
42
|
+
* Compiler: a module map read during render is memoized on its key, so a hook
|
|
43
|
+
* that read `cache.get(src)` there would keep the `undefined` it saw before the
|
|
44
|
+
* fetch finished.
|
|
45
|
+
*
|
|
46
|
+
* Cache: keyed by the resolved URL, so the same avatar in twenty rows costs one
|
|
47
|
+
* request. Gateway URLs carry a `?v=<content-hash>` cache-buster, so changed
|
|
48
|
+
* content is a new key. Entries are reference-counted by the mounted consumers
|
|
49
|
+
* and revoked RELEASE_DELAY_MS after the last one unmounts (a remount inside
|
|
50
|
+
* that window keeps the blob): in a desktop shell open for days, every distinct
|
|
51
|
+
* picture ever shown would otherwise stay in memory.
|
|
52
|
+
*/
|
|
53
|
+
/** What a consumer draws, and why. */
|
|
54
|
+
export type AuthedAssetStatus =
|
|
55
|
+
/** Draw `src` as it stands: the browser loads it itself. */
|
|
56
|
+
'native'
|
|
57
|
+
/** Nothing to draw yet: waiting for a credential, or the first authed fetch is in flight. */
|
|
58
|
+
| 'pending'
|
|
59
|
+
/** `src` is the fetched blob. */
|
|
60
|
+
| 'ready'
|
|
61
|
+
/** The authed fetch failed (a retry may be running); `url` is what was asked for. */
|
|
62
|
+
| 'failed';
|
|
63
|
+
export interface AuthedAsset {
|
|
64
|
+
/** What to draw: the URL (`native`), its blob (`ready`), or nothing (`pending`, `failed`, or no URL given). */
|
|
65
|
+
readonly src: string | undefined;
|
|
66
|
+
/** The URL after the host's `resolveAssetUrl`; `undefined` when none was given. */
|
|
67
|
+
readonly url: string | undefined;
|
|
68
|
+
readonly status: AuthedAssetStatus;
|
|
69
|
+
}
|
|
1
70
|
/**
|
|
2
71
|
* Drop every cached blob and revoke its object URL. Hosts call this at
|
|
3
72
|
* session end (logout / forced re-login) so a follow-on login as a
|
|
4
73
|
* different identity cannot be served blobs fetched under the previous
|
|
5
|
-
* one's bearer. Fetches still in flight
|
|
6
|
-
*
|
|
74
|
+
* one's bearer. Fetches still in flight are fenced by a generation counter
|
|
75
|
+
* (their results are revoked instead of cached). Consumers still mounted go
|
|
76
|
+
* back to `pending`; the clear itself starts no fetch, so a host may clear
|
|
77
|
+
* just before it drops its credential, in the same task. A consumer that
|
|
78
|
+
* looks again later (a credential change, a mount, a render) fetches with
|
|
79
|
+
* whatever credential the host holds then.
|
|
7
80
|
*/
|
|
8
81
|
export declare function clearAuthedAssetCache(): void;
|
|
9
82
|
/**
|
|
@@ -12,5 +85,7 @@ export declare function clearAuthedAssetCache(): void;
|
|
|
12
85
|
* consumer renders (`image/*`, `text/vtt`); it also replaces
|
|
13
86
|
* `embedAuthedFetch`'s default JSON `Content-Type` on the GET.
|
|
14
87
|
*/
|
|
88
|
+
export declare function useAuthedAsset(src?: string | null, accept?: string): AuthedAsset;
|
|
89
|
+
/** `useAuthedAsset`'s `src`: what to draw, `undefined` while there is nothing to draw. */
|
|
15
90
|
export declare function useAuthedAssetSrc(src?: string | null, accept?: string): string | undefined;
|
|
16
91
|
//# sourceMappingURL=use-authed-asset-src.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-authed-asset-src.d.ts","sourceRoot":"","sources":["../../src/hooks/use-authed-asset-src.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-authed-asset-src.d.ts","sourceRoot":"","sources":["../../src/hooks/use-authed-asset-src.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,sCAAsC;AACtC,MAAM,MAAM,iBAAiB;AAC3B,4DAA4D;AAC1D,QAAQ;AACV,6FAA6F;GAC3F,SAAS;AACX,iCAAiC;GAC/B,OAAO;AACT,qFAAqF;GACnF,QAAQ,CAAC;AAEb,MAAM,WAAW,WAAW;IAC1B,+GAA+G;IAC/G,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mFAAmF;IACnF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AA8LD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAU5C;AA+BD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,SAAQ,GAAG,WAAW,CA6B/E;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,SAAQ,GAAG,MAAM,GAAG,SAAS,CAEzF"}
|
|
@@ -1,92 +1,204 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
import { useEffect, useSyncExternalStore } from "react";
|
|
6
|
+
import { subscribeRegisteredAdapter } from "../utils/embed-auth-adapter-registry.js";
|
|
7
|
+
import {
|
|
8
|
+
answeredAfterRefresh,
|
|
9
|
+
assetLoadMode,
|
|
10
|
+
embedAuthedFetch,
|
|
11
|
+
resolveAssetUrl,
|
|
12
|
+
subscribeEmbedCredentialChange
|
|
13
|
+
} from "../utils/embed-authed-fetch.js";
|
|
4
14
|
import { useIsomorphicLayoutEffect } from "./ui/use-isomorphic-layout-effect.js";
|
|
5
|
-
const resolvedCache = /* @__PURE__ */ new Map();
|
|
6
|
-
const inFlight = /* @__PURE__ */ new Map();
|
|
7
|
-
let cacheGeneration = 0;
|
|
8
15
|
const RELEASE_DELAY_MS = 6e4;
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
const IDLE = { status: "idle" };
|
|
17
|
+
class AssetResponseError extends Error {
|
|
18
|
+
constructor(response) {
|
|
19
|
+
super(`asset fetch failed: ${response.status}`);
|
|
20
|
+
__publicField(this, "status");
|
|
21
|
+
__publicField(this, "afterRefresh");
|
|
22
|
+
this.status = response.status;
|
|
23
|
+
this.afterRefresh = answeredAfterRefresh(response);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const entries = /* @__PURE__ */ new Map();
|
|
27
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
28
|
+
let cacheGeneration = 0;
|
|
29
|
+
let notifyScheduled = false;
|
|
30
|
+
let detachSources = null;
|
|
31
|
+
function notify() {
|
|
32
|
+
if (notifyScheduled) return;
|
|
33
|
+
notifyScheduled = true;
|
|
34
|
+
queueMicrotask(() => {
|
|
35
|
+
notifyScheduled = false;
|
|
36
|
+
for (const listener of [...listeners]) listener();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function settle(url, entry, generation, state) {
|
|
40
|
+
const current = entries.get(url);
|
|
41
|
+
if (generation !== cacheGeneration || current !== entry) return false;
|
|
42
|
+
current.state = state;
|
|
43
|
+
notify();
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
function due(state, trigger) {
|
|
47
|
+
if (state.status === "idle") return true;
|
|
48
|
+
if (state.status !== "failed") return false;
|
|
49
|
+
switch (trigger) {
|
|
50
|
+
case "mount":
|
|
51
|
+
return true;
|
|
52
|
+
case "credential":
|
|
53
|
+
return state.retryOn !== "remount";
|
|
54
|
+
case "online":
|
|
55
|
+
return state.retryOn === "credential-or-online";
|
|
56
|
+
default:
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function retryOnFor(error) {
|
|
61
|
+
if (error instanceof TypeError) return "credential-or-online";
|
|
62
|
+
if (error instanceof AssetResponseError && error.status === 401 && !error.afterRefresh) return "credential";
|
|
63
|
+
return "remount";
|
|
64
|
+
}
|
|
65
|
+
function kick(url, trigger) {
|
|
66
|
+
const entry = entries.get(url);
|
|
67
|
+
if (!entry || !due(entry.state, trigger) || assetLoadMode(url) !== "bearer") return;
|
|
68
|
+
const generation = cacheGeneration;
|
|
69
|
+
settle(url, entry, generation, { status: "loading", afterFailure: entry.state.status === "failed" });
|
|
70
|
+
Promise.resolve().then(() => embedAuthedFetch(url, { headers: { Accept: entry.accept } })).then(async (response) => {
|
|
71
|
+
if (!response.ok || /^\s*text\/html\b/i.test(response.headers.get("Content-Type") ?? "")) {
|
|
72
|
+
throw new AssetResponseError(response);
|
|
73
|
+
}
|
|
74
|
+
return URL.createObjectURL(await response.blob());
|
|
75
|
+
}).then(
|
|
76
|
+
(blobUrl) => {
|
|
77
|
+
if (!settle(url, entry, generation, { status: "ready", blobUrl })) URL.revokeObjectURL(blobUrl);
|
|
78
|
+
},
|
|
79
|
+
(error) => {
|
|
80
|
+
settle(url, entry, generation, { status: "failed", retryOn: retryOnFor(error) });
|
|
81
|
+
}
|
|
22
82
|
);
|
|
23
83
|
}
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
84
|
+
function sweep(trigger) {
|
|
85
|
+
for (const [url, entry] of entries) if (entry.refs > 0) kick(url, trigger);
|
|
86
|
+
notify();
|
|
87
|
+
}
|
|
88
|
+
function onCredentialChange() {
|
|
89
|
+
sweep("credential");
|
|
90
|
+
}
|
|
91
|
+
function onOnline() {
|
|
92
|
+
sweep("online");
|
|
93
|
+
}
|
|
94
|
+
function attachSources() {
|
|
95
|
+
let detachCredential = subscribeEmbedCredentialChange(onCredentialChange);
|
|
96
|
+
const detachAdapter = subscribeRegisteredAdapter(() => {
|
|
97
|
+
detachCredential();
|
|
98
|
+
detachCredential = subscribeEmbedCredentialChange(onCredentialChange);
|
|
99
|
+
onCredentialChange();
|
|
100
|
+
});
|
|
101
|
+
window.addEventListener("online", onOnline);
|
|
102
|
+
return () => {
|
|
103
|
+
detachCredential();
|
|
104
|
+
detachAdapter();
|
|
105
|
+
window.removeEventListener("online", onOnline);
|
|
106
|
+
};
|
|
28
107
|
}
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
108
|
+
function subscribeNothing() {
|
|
109
|
+
return () => {
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function subscribe(listener) {
|
|
113
|
+
listeners.add(listener);
|
|
114
|
+
detachSources ?? (detachSources = attachSources());
|
|
115
|
+
return () => {
|
|
116
|
+
listeners.delete(listener);
|
|
117
|
+
if (listeners.size === 0 && detachSources) {
|
|
118
|
+
detachSources();
|
|
119
|
+
detachSources = null;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function acquire(url, accept) {
|
|
124
|
+
let entry = entries.get(url);
|
|
125
|
+
if (!entry) {
|
|
126
|
+
entry = { state: IDLE, accept, refs: 0, releaseTimer: void 0 };
|
|
127
|
+
entries.set(url, entry);
|
|
34
128
|
}
|
|
35
|
-
|
|
36
|
-
|
|
129
|
+
clearTimeout(entry.releaseTimer);
|
|
130
|
+
entry.releaseTimer = void 0;
|
|
131
|
+
entry.refs++;
|
|
132
|
+
kick(url, entry.refs === 1 ? "mount" : "join");
|
|
133
|
+
}
|
|
134
|
+
function release(url) {
|
|
135
|
+
const entry = entries.get(url);
|
|
136
|
+
if (!entry) return;
|
|
137
|
+
entry.refs = Math.max(0, entry.refs - 1);
|
|
138
|
+
if (entry.refs > 0) return;
|
|
139
|
+
clearTimeout(entry.releaseTimer);
|
|
140
|
+
entry.releaseTimer = setTimeout(() => {
|
|
141
|
+
if (entries.get(url) !== entry || entry.refs > 0) return;
|
|
142
|
+
if (entry.state.status === "ready") URL.revokeObjectURL(entry.state.blobUrl);
|
|
143
|
+
entries.delete(url);
|
|
144
|
+
}, RELEASE_DELAY_MS);
|
|
37
145
|
}
|
|
38
146
|
function clearAuthedAssetCache() {
|
|
39
147
|
cacheGeneration++;
|
|
40
|
-
for (const url of
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
function fetchAsBlobUrl(src, accept) {
|
|
47
|
-
let pending = inFlight.get(src);
|
|
48
|
-
if (!pending) {
|
|
49
|
-
const startedGeneration = cacheGeneration;
|
|
50
|
-
pending = embedAuthedFetch(src, { headers: { Accept: accept } }).then(async (response) => {
|
|
51
|
-
if (!response.ok) throw new Error(`asset fetch failed: ${response.status}`);
|
|
52
|
-
const blobUrl = URL.createObjectURL(await response.blob());
|
|
53
|
-
if (startedGeneration === cacheGeneration) {
|
|
54
|
-
resolvedCache.set(src, blobUrl);
|
|
55
|
-
if (!refCounts.has(src)) scheduleRelease(src);
|
|
56
|
-
} else {
|
|
57
|
-
URL.revokeObjectURL(blobUrl);
|
|
58
|
-
}
|
|
59
|
-
}).finally(() => {
|
|
60
|
-
if (inFlight.get(src) === pending) inFlight.delete(src);
|
|
61
|
-
});
|
|
62
|
-
inFlight.set(src, pending);
|
|
148
|
+
for (const [url, entry] of entries) {
|
|
149
|
+
if (entry.state.status === "ready") URL.revokeObjectURL(entry.state.blobUrl);
|
|
150
|
+
clearTimeout(entry.releaseTimer);
|
|
151
|
+
entry.releaseTimer = void 0;
|
|
152
|
+
if (entry.refs > 0) entry.state = IDLE;
|
|
153
|
+
else entries.delete(url);
|
|
63
154
|
}
|
|
64
|
-
|
|
155
|
+
notify();
|
|
65
156
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
157
|
+
const NO_ASSET = Object.freeze({ src: void 0, url: void 0, status: "native" });
|
|
158
|
+
function readAsset(src) {
|
|
159
|
+
if (!src) return NO_ASSET;
|
|
160
|
+
const url = resolveAssetUrl(src);
|
|
161
|
+
const mode = assetLoadMode(url);
|
|
162
|
+
if (mode === "native") return { src: url, url, status: "native" };
|
|
163
|
+
const state = mode === "bearer" ? entries.get(url)?.state : void 0;
|
|
164
|
+
if (state?.status === "ready") return { src: state.blobUrl, url, status: "ready" };
|
|
165
|
+
if (state?.status === "failed" || state?.status === "loading" && state.afterFailure) {
|
|
166
|
+
return { src: void 0, url, status: "failed" };
|
|
167
|
+
}
|
|
168
|
+
return { src: void 0, url, status: "pending" };
|
|
169
|
+
}
|
|
170
|
+
function encode(asset) {
|
|
171
|
+
return JSON.stringify([asset.status, asset.url ?? null, asset.src ?? null]);
|
|
172
|
+
}
|
|
173
|
+
function decode(snapshot) {
|
|
174
|
+
const [status, url, src] = JSON.parse(snapshot);
|
|
175
|
+
return { status, url: url ?? void 0, src: src ?? void 0 };
|
|
176
|
+
}
|
|
177
|
+
function useAuthedAsset(src, accept = "*/*") {
|
|
178
|
+
const snapshot = useSyncExternalStore(
|
|
179
|
+
src ? subscribe : subscribeNothing,
|
|
180
|
+
() => encode(readAsset(src)),
|
|
181
|
+
// The server has no adapter: it draws the URL as given, and the client takes over after hydration.
|
|
182
|
+
() => encode(src ? { src, url: src, status: "native" } : NO_ASSET)
|
|
183
|
+
);
|
|
184
|
+
const asset = decode(snapshot);
|
|
185
|
+
const tracked = asset.status === "native" ? void 0 : asset.url;
|
|
69
186
|
useIsomorphicLayoutEffect(() => {
|
|
70
|
-
if (!
|
|
71
|
-
acquire(
|
|
72
|
-
return () => release(
|
|
73
|
-
}, [
|
|
187
|
+
if (!tracked) return void 0;
|
|
188
|
+
acquire(tracked, accept);
|
|
189
|
+
return () => release(tracked);
|
|
190
|
+
}, [tracked, accept]);
|
|
191
|
+
const waiting = tracked !== void 0 && asset.status === "pending";
|
|
74
192
|
useEffect(() => {
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return () => {
|
|
82
|
-
cancelled = true;
|
|
83
|
-
};
|
|
84
|
-
}, [bearerSrc, accept]);
|
|
85
|
-
if (!src) return void 0;
|
|
86
|
-
if (!bearerSrc) return src;
|
|
87
|
-
return resolvedCache.get(bearerSrc);
|
|
193
|
+
if (waiting) kick(tracked, "join");
|
|
194
|
+
});
|
|
195
|
+
return asset;
|
|
196
|
+
}
|
|
197
|
+
function useAuthedAssetSrc(src, accept = "*/*") {
|
|
198
|
+
return useAuthedAsset(src, accept).src;
|
|
88
199
|
}
|
|
89
200
|
export {
|
|
90
201
|
clearAuthedAssetCache,
|
|
202
|
+
useAuthedAsset,
|
|
91
203
|
useAuthedAssetSrc
|
|
92
204
|
};
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import { clearAuthedAssetCache } from './use-authed-asset-src';
|
|
1
|
+
import { type AuthedAsset, clearAuthedAssetCache } from './use-authed-asset-src';
|
|
2
2
|
/**
|
|
3
|
-
* Image flavor of `
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Image flavor of `useAuthedAsset` — see that hook for the full contract. The
|
|
4
|
+
* one place a picture's `Accept` is stated: a store entry keeps the `Accept` of
|
|
5
|
+
* whichever consumer acquired it first, so the boxed `Image` and every picture
|
|
6
|
+
* component around it must ask the same.
|
|
6
7
|
*
|
|
7
8
|
* Distinct from the legacy `useAuthenticatedImage`, which ALWAYS blob-fetches
|
|
8
9
|
* with `credentials: 'include'` and its own global config. This hook is
|
|
9
10
|
* pass-through-first and keys off the single auth knob the lib already has:
|
|
10
11
|
* the registered `EmbedAuthAdapter`.
|
|
11
12
|
*/
|
|
13
|
+
export declare function useAuthedImage(src?: string | null): AuthedAsset;
|
|
14
|
+
/**
|
|
15
|
+
* `useAuthedImage`'s `src`. Kept as its own export because it is the lib's
|
|
16
|
+
* most-used consumer (avatars, entity images, markdown `<img>`) and because
|
|
17
|
+
* hosts already import this name.
|
|
18
|
+
*/
|
|
12
19
|
export declare function useAuthedImageSrc(src?: string | null): string | undefined;
|
|
13
20
|
/**
|
|
14
21
|
* Session-end cache drop. Now an alias of `clearAuthedAssetCache` — one cache
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-authed-image-src.d.ts","sourceRoot":"","sources":["../../src/hooks/use-authed-image-src.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"use-authed-image-src.d.ts","sourceRoot":"","sources":["../../src/hooks/use-authed-image-src.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAE,qBAAqB,EAAkB,MAAM,wBAAwB,CAAC;AAEjG;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,8BAAwB,CAAC"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { clearAuthedAssetCache,
|
|
2
|
+
import { clearAuthedAssetCache, useAuthedAsset } from "./use-authed-asset-src.js";
|
|
3
|
+
function useAuthedImage(src) {
|
|
4
|
+
return useAuthedAsset(src, "image/*");
|
|
5
|
+
}
|
|
3
6
|
function useAuthedImageSrc(src) {
|
|
4
|
-
return
|
|
7
|
+
return useAuthedImage(src).src;
|
|
5
8
|
}
|
|
6
9
|
const clearAuthedImageCache = clearAuthedAssetCache;
|
|
7
10
|
export {
|
|
8
11
|
clearAuthedImageCache,
|
|
12
|
+
useAuthedImage,
|
|
9
13
|
useAuthedImageSrc
|
|
10
14
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ImageFallback {
|
|
2
|
+
/** The first candidate that has not failed, else null: draw your own fallback (initials, a placeholder, nothing). */
|
|
3
|
+
src: string | null;
|
|
4
|
+
/** Wire to the picture's `onError`. */
|
|
5
|
+
onError: () => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A picture's fallback chain, keyed by URL: how a component falls back from a picture that did not load
|
|
9
|
+
* (`SquareAvatar`, `EntityImage`, `ChatMessageRow`, the entity cards' covers). State is the SET of URLs that failed
|
|
10
|
+
* and `src` is derived, so a new URL is simply not one of them: the picture comes back with no reset effect, and a
|
|
11
|
+
* URL that failed once is not retried in a loop. Never hide the element or reveal a fallback by writing to the DOM
|
|
12
|
+
* in `onError` instead (the legacy `hideOnError`): React does not undo the write, so the fallback outlives the URL
|
|
13
|
+
* it was about.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useImageFallback(...candidates: (string | null | undefined)[]): ImageFallback;
|
|
16
|
+
//# sourceMappingURL=use-image-fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-image-fallback.d.ts","sourceRoot":"","sources":["../../src/hooks/use-image-fallback.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,qHAAqH;IACrH,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,uCAAuC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,UAAU,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,aAAa,CAW5F"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
function useImageFallback(...candidates) {
|
|
4
|
+
const [failed, setFailed] = useState(() => /* @__PURE__ */ new Set());
|
|
5
|
+
const src = candidates.find((candidate) => !!candidate && !failed.has(candidate)) ?? null;
|
|
6
|
+
const onError = useCallback(() => {
|
|
7
|
+
if (!src) return;
|
|
8
|
+
setFailed((prev) => new Set(prev).add(src));
|
|
9
|
+
}, [src]);
|
|
10
|
+
return { src, onError };
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
useImageFallback
|
|
14
|
+
};
|