@atlaskit/media-file-preview 0.17.2 → 1.0.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 (41) hide show
  1. package/AGENTS.md +59 -0
  2. package/CHANGELOG.md +38 -0
  3. package/dist/cjs/getPreview/getPreview.js +89 -36
  4. package/dist/cjs/getPreview/helpers.js +51 -51
  5. package/dist/cjs/getPreview/index.js +6 -0
  6. package/dist/cjs/getPreview/videoSnapshot.js +1 -1
  7. package/dist/cjs/useFilePreview.js +12 -2
  8. package/dist/es2019/getPreview/getPreview.js +54 -5
  9. package/dist/es2019/getPreview/index.js +1 -1
  10. package/dist/es2019/useFilePreview.js +13 -3
  11. package/dist/esm/getPreview/getPreview.js +88 -35
  12. package/dist/esm/getPreview/helpers.js +51 -51
  13. package/dist/esm/getPreview/index.js +1 -1
  14. package/dist/esm/getPreview/videoSnapshot.js +1 -1
  15. package/dist/esm/useFilePreview.js +13 -3
  16. package/dist/types/getPreview/getPreview.d.ts +12 -1
  17. package/dist/types/getPreview/index.d.ts +1 -1
  18. package/dist/types/useFilePreview.d.ts +4 -2
  19. package/errors/package.json +1 -8
  20. package/package.json +16 -19
  21. package/types/package.json +1 -8
  22. package/use-file-preview/package.json +1 -8
  23. package/use-media-image/package.json +1 -8
  24. package/dist/types-ts4.5/analytics.d.ts +0 -30
  25. package/dist/types-ts4.5/errors.d.ts +0 -38
  26. package/dist/types-ts4.5/getPreview/cache.d.ts +0 -25
  27. package/dist/types-ts4.5/getPreview/getPreview.d.ts +0 -11
  28. package/dist/types-ts4.5/getPreview/helpers.d.ts +0 -10
  29. package/dist/types-ts4.5/getPreview/index.d.ts +0 -3
  30. package/dist/types-ts4.5/getPreview/objectURLCache.d.ts +0 -21
  31. package/dist/types-ts4.5/getPreview/videoSnapshot.d.ts +0 -1
  32. package/dist/types-ts4.5/globalScope/getSSRData.d.ts +0 -3
  33. package/dist/types-ts4.5/globalScope/globalScope.d.ts +0 -23
  34. package/dist/types-ts4.5/globalScope/index.d.ts +0 -4
  35. package/dist/types-ts4.5/globalScope/originalScriptCode.d.ts +0 -0
  36. package/dist/types-ts4.5/globalScope/types.d.ts +0 -12
  37. package/dist/types-ts4.5/helpers.d.ts +0 -11
  38. package/dist/types-ts4.5/index.d.ts +0 -7
  39. package/dist/types-ts4.5/types.d.ts +0 -14
  40. package/dist/types-ts4.5/useFilePreview.d.ts +0 -44
  41. package/dist/types-ts4.5/useMediaImage.d.ts +0 -45
package/AGENTS.md ADDED
@@ -0,0 +1,59 @@
1
+ # media-file-preview — Agent Guide
2
+
3
+ > **Parent guide:** Always read [`../AGENTS.md`](../AGENTS.md) before working in this package — it
4
+ > contains workspace-wide rules covering platform guidelines, changeset workflow, accessibility
5
+ > standards, and the knowledge index protocol that applies to every Media package.
6
+
7
+ ## Package identity
8
+
9
+ | Field | Value |
10
+ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
11
+ | NPM name | `@atlaskit/media-file-preview` |
12
+ | Path | `media-file-preview/` |
13
+ | Owner | Media Exif |
14
+ | Purpose | React hooks for fetching and rendering media file previews — `useFilePreview` for general previews and `useMediaImage` for image rendering |
15
+
16
+ ## Knowledge index
17
+
18
+ > Read, search, edit, investigate, and validate the repository knowledge index at
19
+ > `.agents/knowledge-index/`. ALWAYS use this skill before making ANY repo change, or when exploring
20
+ > the codebase. The knowledge index is the canonical starting point for every coding task in this
21
+ > repo, trigger this skill aggressively whenever the user mentions architecture, conventions,
22
+ > packages, modules, services, build, coding, writing code, APIs, feature flags, testing, or
23
+ > anything similar. Also trigger when "is the knowledge index up to date?" / "update the knowledge
24
+ > index" / "what does the knowledge index say about Y?" — even if they don't say the words
25
+ > "knowledge index". Also use it (via the `validate` subcommand) to detect drift between the
26
+ > codebase and the docs after any code change. Use the `generate` subcommand to bootstrap the index
27
+ > in a new repository.
28
+
29
+ **Entry point:** `.agents/knowledge-index/INDEX.md` **Unit doc:**
30
+ `.agents/knowledge-index/domains/media/units/atlaskit-media-file-preview.md` **CLI:**
31
+ `python3 .agents/skills/knowledge-index/scripts/kg.py {find,read,edit,investigate,validate,init,explore,generate} …`
32
+ **Refresh protocol:** never silently bump `Last verified` — always re-read the listed `Sources`
33
+ first, edit, then `kg.py edit <path> --message "<reason>"`.
34
+
35
+ ## Key source files
36
+
37
+ - `src/index.ts` — public API entry point
38
+ - `src/useFilePreview.tsx` — primary hook for file preview state
39
+ - `src/useMediaImage.tsx` — hook for image blob URL resolution
40
+ - `src/getPreview/` — preview resolution strategies per media type
41
+ - `src/globalScope/` — browser globals abstraction (for SSR safety)
42
+ - `src/types.ts` — shared type definitions
43
+ - `src/errors.ts` — error types and predicates
44
+ - `src/analytics.ts` — analytics event helpers
45
+
46
+ ## Public API (key exports)
47
+
48
+ `useFilePreview`, `UseFilePreviewParams`, `useMediaImage`, `UseMediaImageParams`,
49
+ `MediaFilePreview`, `isMediaFilePreviewError`, `MediaFilePreviewErrorPrimaryReason`
50
+
51
+ ## Development notes
52
+
53
+ - React Compiler is enabled for this package
54
+ - Peer dependencies: `react`, `react-dom`
55
+ - 5 feature flags registered (see `package.json` → `platform-feature-flags`)
56
+ - Includes SSR-safe preview behaviour
57
+ - Export subpaths: `.`, `./errors`, `./types`, `./use-file-preview`, `./use-media-image`
58
+ - All new behaviour changes must be behind a feature gate (`fg()` from
59
+ `@atlaskit/platform-feature-flags`)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @atlaskit/media-file-preview
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [`f2dc9097319f0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f2dc9097319f0) - ###
8
+ Dropped support for _legacy_ Typescript 4 types. **Typescript 5 is now the new minimum**.
9
+
10
+ Removes the `typesVersions` property and `dist/types-ts4.5` directory from the dist.
11
+
12
+ Types are now exclusively via the `"types": "dist/types/index.d.ts"` property.
13
+
14
+ ```diff
15
+ - "typesVersions": {
16
+ - ">=4.5 <4.9": {
17
+ - "*": [
18
+ - "dist/types-ts4.5/*",
19
+ - "dist/types-ts4.5/index.d.ts"
20
+ - ]
21
+ - }
22
+ - },
23
+ ```
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies
28
+
29
+ ## 0.18.0
30
+
31
+ ### Minor Changes
32
+
33
+ - [`a68f551856a81`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a68f551856a81) -
34
+ Add initialFileState param to useFilePreview to support SSR-seeded file state for immediate
35
+ preview rendering.
36
+
37
+ ### Patch Changes
38
+
39
+ - Updated dependencies
40
+
3
41
  ## 0.17.2
4
42
 
5
43
  ### Patch Changes
@@ -4,10 +4,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.isSSRPreview = exports.isSSRDataPreview = exports.isSSRClientPreview = exports.isRemotePreview = exports.isLocalPreview = exports.getSSRPreview = exports.getAndCacheRemotePreview = exports.getAndCacheLocalPreview = void 0;
7
+ exports.isSSRPreview = exports.isSSRDataPreview = exports.isSSRClientPreview = exports.isRemotePreview = exports.isLocalPreview = exports.getSSRPreview = exports.getAndCacheRemotePreview = exports.getAndCacheLocalPreview = exports.extractCdnSigningParams = void 0;
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
11
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
12
  var _mediaClient = require("@atlaskit/media-client");
13
13
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
@@ -39,9 +39,62 @@ var extendAndCachePreview = function extendAndCachePreview(id, mode, preview, me
39
39
  dataURI: dataURI
40
40
  });
41
41
  };
42
- var getDataUri = function getDataUri(mediaClient, id, params, mediaBlobUrlAttrs) {
42
+
43
+ /**
44
+ * Allowlist of CDN signing query-param names that we propagate from a
45
+ * pre-signed `previewCdnUrl` onto the URL produced by `getImageUrlSync`.
46
+ * These are the standard CloudFront signed-URL params; if the upstream
47
+ * adds a new one, this list needs updating.
48
+ */
49
+ var SIGNING_PARAM_NAMES = ['token', 'Policy', 'Key-Pair-Id', 'Signature', 'Expires'];
50
+
51
+ /**
52
+ * Pull the CDN-signing query params (token / Policy / Key-Pair-Id / Signature
53
+ * / Expires) out of a pre-signed CDN URL so they can be overlaid on a URL
54
+ * built independently by `getImageUrlSync` (which constructs path, image
55
+ * params, pathBased routing, wmv, etc.). Image-shape params from the cdn URL
56
+ * itself (width/height/mode/...) are intentionally NOT extracted — those come
57
+ * from `imageURLParams` via `getImageUrlSync`.
58
+ *
59
+ * Returns `{}` on parse failure so we degrade rather than throw.
60
+ */
61
+ var extractCdnSigningParams = exports.extractCdnSigningParams = function extractCdnSigningParams(cdnUrl) {
62
+ try {
63
+ var url = new URL(cdnUrl);
64
+ var out = {};
65
+ for (var _i = 0, _SIGNING_PARAM_NAMES = SIGNING_PARAM_NAMES; _i < _SIGNING_PARAM_NAMES.length; _i++) {
66
+ var name = _SIGNING_PARAM_NAMES[_i];
67
+ var value = url.searchParams.get(name);
68
+ if (value !== null) {
69
+ out[name] = value;
70
+ }
71
+ }
72
+ return out;
73
+ } catch (_unused) {
74
+ return {};
75
+ }
76
+ };
77
+ var applyCdnSigningParams = function applyCdnSigningParams(url, cdnSigningParams) {
78
+ if (!cdnSigningParams || Object.keys(cdnSigningParams).length === 0) {
79
+ return url;
80
+ }
81
+ try {
82
+ var parsed = new URL(url);
83
+ Object.entries(cdnSigningParams).forEach(function (_ref) {
84
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
85
+ key = _ref2[0],
86
+ value = _ref2[1];
87
+ parsed.searchParams.set(key, value);
88
+ });
89
+ return parsed.toString();
90
+ } catch (_unused2) {
91
+ return url;
92
+ }
93
+ };
94
+ var getDataUri = function getDataUri(mediaClient, id, params, mediaBlobUrlAttrs, cdnSigningParams) {
43
95
  var rawDataURI = mediaClient.getImageUrlSync(id, params);
44
- return mediaBlobUrlAttrs ? (0, _mediaClient.addFileAttrsToUrl)(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
96
+ var signedDataURI = applyCdnSigningParams(rawDataURI, cdnSigningParams);
97
+ return mediaBlobUrlAttrs ? (0, _mediaClient.addFileAttrsToUrl)(signedDataURI, mediaBlobUrlAttrs) : signedDataURI;
45
98
  };
46
99
 
47
100
  /**
@@ -66,18 +119,18 @@ var mergeClientIdIntoAttrs = function mergeClientIdIntoAttrs(clientId, id, media
66
119
  collection: collectionName
67
120
  };
68
121
  };
69
- var getSSRPreview = exports.getSSRPreview = function getSSRPreview(ssr, mediaClient, id, params, mediaBlobUrlAttrs) {
122
+ var getSSRPreview = exports.getSSRPreview = function getSSRPreview(ssr, mediaClient, id, params, mediaBlobUrlAttrs, cdnSigningParams) {
70
123
  try {
71
124
  // Synchronously extract clientId from initialAuth and merge into blob URL attrs
72
125
  var clientId = (0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth') ? mediaClient.getClientIdSync() : undefined;
73
126
  var attrsWithClientId = mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, params.collection);
74
- var dataURI = getDataUri(mediaClient, id, params, attrsWithClientId);
127
+ var dataURI = getDataUri(mediaClient, id, params, attrsWithClientId, cdnSigningParams);
75
128
  var srcSet = "".concat(dataURI, " 1x");
76
129
  if (params.width) {
77
130
  var doubleDataURI = getDataUri(mediaClient, id, _objectSpread(_objectSpread({}, params), {}, {
78
131
  width: params.width * 2,
79
132
  height: params.height && params.height * 2
80
- }), attrsWithClientId);
133
+ }), attrsWithClientId, cdnSigningParams);
81
134
  // We want to embed some meta context into dataURI for Copy/Paste to work.
82
135
  srcSet += ", ".concat(doubleDataURI, " 2x");
83
136
  }
@@ -117,54 +170,54 @@ var isSSRPreview = exports.isSSRPreview = function isSSRPreview(preview) {
117
170
  * with it for cross-client copy support.
118
171
  */
119
172
  var enrichAttrsWithClientId = /*#__PURE__*/function () {
120
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mediaClient, id, mediaBlobUrlAttrs, collectionName) {
121
- var clientId;
122
- return _regenerator.default.wrap(function _callee$(_context) {
173
+ var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mediaClient, id, mediaBlobUrlAttrs, collectionName) {
174
+ var clientId, _t;
175
+ return _regenerator.default.wrap(function (_context) {
123
176
  while (1) switch (_context.prev = _context.next) {
124
177
  case 0:
125
178
  if ((0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth')) {
126
- _context.next = 2;
179
+ _context.next = 1;
127
180
  break;
128
181
  }
129
182
  return _context.abrupt("return", mediaBlobUrlAttrs);
130
- case 2:
183
+ case 1:
131
184
  // Try sync first, then async fallback
132
185
  clientId = mediaClient.getClientIdSync();
133
186
  if (clientId) {
134
- _context.next = 12;
187
+ _context.next = 5;
135
188
  break;
136
189
  }
137
- _context.prev = 4;
138
- _context.next = 7;
190
+ _context.prev = 2;
191
+ _context.next = 3;
139
192
  return mediaClient.getClientId(collectionName);
140
- case 7:
193
+ case 3:
141
194
  clientId = _context.sent;
142
- _context.next = 12;
195
+ _context.next = 5;
143
196
  break;
144
- case 10:
145
- _context.prev = 10;
146
- _context.t0 = _context["catch"](4);
147
- case 12:
197
+ case 4:
198
+ _context.prev = 4;
199
+ _t = _context["catch"](2);
200
+ case 5:
148
201
  return _context.abrupt("return", mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, collectionName));
149
- case 13:
202
+ case 6:
150
203
  case "end":
151
204
  return _context.stop();
152
205
  }
153
- }, _callee, null, [[4, 10]]);
206
+ }, _callee, null, [[2, 4]]);
154
207
  }));
155
208
  return function enrichAttrsWithClientId(_x, _x2, _x3, _x4) {
156
- return _ref.apply(this, arguments);
209
+ return _ref3.apply(this, arguments);
157
210
  };
158
211
  }();
159
212
  var getAndCacheRemotePreview = exports.getAndCacheRemotePreview = /*#__PURE__*/function () {
160
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) {
213
+ var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) {
161
214
  var _yield$Promise$all, _yield$Promise$all2, remotePreview, enrichedAttrs;
162
- return _regenerator.default.wrap(function _callee2$(_context2) {
215
+ return _regenerator.default.wrap(function (_context2) {
163
216
  while (1) switch (_context2.prev = _context2.next) {
164
217
  case 0:
165
- _context2.next = 2;
218
+ _context2.next = 1;
166
219
  return Promise.all([(0, _helpers.getRemotePreview)(mediaClient, id, params, traceContext), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, params.collection)]);
167
- case 2:
220
+ case 1:
168
221
  _yield$Promise$all = _context2.sent;
169
222
  _yield$Promise$all2 = (0, _slicedToArray2.default)(_yield$Promise$all, 2);
170
223
  remotePreview = _yield$Promise$all2[0];
@@ -172,25 +225,25 @@ var getAndCacheRemotePreview = exports.getAndCacheRemotePreview = /*#__PURE__*/f
172
225
  return _context2.abrupt("return", extendAndCachePreview(id, params.mode, _objectSpread(_objectSpread({}, remotePreview), {}, {
173
226
  dimensions: dimensions
174
227
  }), enrichedAttrs));
175
- case 7:
228
+ case 2:
176
229
  case "end":
177
230
  return _context2.stop();
178
231
  }
179
232
  }, _callee2);
180
233
  }));
181
234
  return function getAndCacheRemotePreview(_x5, _x6, _x7, _x8, _x9, _x0) {
182
- return _ref2.apply(this, arguments);
235
+ return _ref4.apply(this, arguments);
183
236
  };
184
237
  }();
185
238
  var getAndCacheLocalPreview = exports.getAndCacheLocalPreview = /*#__PURE__*/function () {
186
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(mediaClient, id, filePreview, dimensions, mode, mediaBlobUrlAttrs, collectionName) {
239
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(mediaClient, id, filePreview, dimensions, mode, mediaBlobUrlAttrs, collectionName) {
187
240
  var _yield$Promise$all3, _yield$Promise$all4, localPreview, enrichedAttrs;
188
- return _regenerator.default.wrap(function _callee3$(_context3) {
241
+ return _regenerator.default.wrap(function (_context3) {
189
242
  while (1) switch (_context3.prev = _context3.next) {
190
243
  case 0:
191
- _context3.next = 2;
244
+ _context3.next = 1;
192
245
  return Promise.all([(0, _helpers.getLocalPreview)(filePreview), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, collectionName)]);
193
- case 2:
246
+ case 1:
194
247
  _yield$Promise$all3 = _context3.sent;
195
248
  _yield$Promise$all4 = (0, _slicedToArray2.default)(_yield$Promise$all3, 2);
196
249
  localPreview = _yield$Promise$all4[0];
@@ -198,13 +251,13 @@ var getAndCacheLocalPreview = exports.getAndCacheLocalPreview = /*#__PURE__*/fun
198
251
  return _context3.abrupt("return", extendAndCachePreview(id, mode, _objectSpread(_objectSpread({}, localPreview), {}, {
199
252
  dimensions: dimensions
200
253
  }), enrichedAttrs));
201
- case 7:
254
+ case 2:
202
255
  case "end":
203
256
  return _context3.stop();
204
257
  }
205
258
  }, _callee3);
206
259
  }));
207
260
  return function getAndCacheLocalPreview(_x1, _x10, _x11, _x12, _x13, _x14, _x15) {
208
- return _ref3.apply(this, arguments);
261
+ return _ref5.apply(this, arguments);
209
262
  };
210
263
  }();
@@ -20,14 +20,14 @@ var isSupportedLocalPreview = exports.isSupportedLocalPreview = function isSuppo
20
20
  };
21
21
  var getImageLocalPreview = /*#__PURE__*/function () {
22
22
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(value) {
23
- var orientation, dataURI;
24
- return _regenerator.default.wrap(function _callee$(_context) {
23
+ var orientation, dataURI, _t;
24
+ return _regenerator.default.wrap(function (_context) {
25
25
  while (1) switch (_context.prev = _context.next) {
26
26
  case 0:
27
27
  _context.prev = 0;
28
- _context.next = 3;
28
+ _context.next = 1;
29
29
  return (0, _mediaUi.getOrientation)(value);
30
- case 3:
30
+ case 1:
31
31
  orientation = _context.sent;
32
32
  dataURI = URL.createObjectURL(value);
33
33
  return _context.abrupt("return", {
@@ -35,15 +35,15 @@ var getImageLocalPreview = /*#__PURE__*/function () {
35
35
  orientation: orientation,
36
36
  source: 'local'
37
37
  });
38
- case 8:
39
- _context.prev = 8;
40
- _context.t0 = _context["catch"](0);
41
- throw new _errors.LocalPreviewError('local-preview-image', _context.t0 instanceof Error ? _context.t0 : undefined);
42
- case 11:
38
+ case 2:
39
+ _context.prev = 2;
40
+ _t = _context["catch"](0);
41
+ throw new _errors.LocalPreviewError('local-preview-image', _t instanceof Error ? _t : undefined);
42
+ case 3:
43
43
  case "end":
44
44
  return _context.stop();
45
45
  }
46
- }, _callee, null, [[0, 8]]);
46
+ }, _callee, null, [[0, 2]]);
47
47
  }));
48
48
  return function getImageLocalPreview(_x) {
49
49
  return _ref.apply(this, arguments);
@@ -51,29 +51,29 @@ var getImageLocalPreview = /*#__PURE__*/function () {
51
51
  }();
52
52
  var getVideoLocalPreview = /*#__PURE__*/function () {
53
53
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(value) {
54
- var dataURI;
55
- return _regenerator.default.wrap(function _callee2$(_context2) {
54
+ var dataURI, _t2;
55
+ return _regenerator.default.wrap(function (_context2) {
56
56
  while (1) switch (_context2.prev = _context2.next) {
57
57
  case 0:
58
58
  _context2.prev = 0;
59
- _context2.next = 3;
59
+ _context2.next = 1;
60
60
  return (0, _videoSnapshot.takeSnapshot)(value);
61
- case 3:
61
+ case 1:
62
62
  dataURI = _context2.sent;
63
63
  return _context2.abrupt("return", {
64
64
  dataURI: dataURI,
65
65
  orientation: 1,
66
66
  source: 'local'
67
67
  });
68
- case 7:
69
- _context2.prev = 7;
70
- _context2.t0 = _context2["catch"](0);
71
- throw new _errors.LocalPreviewError('local-preview-video', _context2.t0 instanceof Error ? _context2.t0 : undefined);
72
- case 10:
68
+ case 2:
69
+ _context2.prev = 2;
70
+ _t2 = _context2["catch"](0);
71
+ throw new _errors.LocalPreviewError('local-preview-video', _t2 instanceof Error ? _t2 : undefined);
72
+ case 3:
73
73
  case "end":
74
74
  return _context2.stop();
75
75
  }
76
- }, _callee2, null, [[0, 7]]);
76
+ }, _callee2, null, [[0, 2]]);
77
77
  }));
78
78
  return function getVideoLocalPreview(_x2) {
79
79
  return _ref2.apply(this, arguments);
@@ -81,25 +81,25 @@ var getVideoLocalPreview = /*#__PURE__*/function () {
81
81
  }();
82
82
  var getLocalPreview = exports.getLocalPreview = /*#__PURE__*/function () {
83
83
  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(filePreview) {
84
- var value, resolvedFilePreview, _value, type, mediaType;
85
- return _regenerator.default.wrap(function _callee3$(_context3) {
84
+ var value, resolvedFilePreview, _value, type, mediaType, _t3, _t4;
85
+ return _regenerator.default.wrap(function (_context3) {
86
86
  while (1) switch (_context3.prev = _context3.next) {
87
87
  case 0:
88
88
  _context3.prev = 0;
89
- _context3.next = 3;
89
+ _context3.next = 1;
90
90
  return filePreview;
91
- case 3:
91
+ case 1:
92
92
  resolvedFilePreview = _context3.sent;
93
93
  value = resolvedFilePreview.value;
94
- _context3.next = 10;
94
+ _context3.next = 3;
95
95
  break;
96
- case 7:
97
- _context3.prev = 7;
98
- _context3.t0 = _context3["catch"](0);
99
- throw new _errors.LocalPreviewError('local-preview-rejected', _context3.t0 instanceof Error ? _context3.t0 : undefined);
100
- case 10:
96
+ case 2:
97
+ _context3.prev = 2;
98
+ _t3 = _context3["catch"](0);
99
+ throw new _errors.LocalPreviewError('local-preview-rejected', _t3 instanceof Error ? _t3 : undefined);
100
+ case 3:
101
101
  if (!(typeof value === 'string')) {
102
- _context3.next = 14;
102
+ _context3.next = 4;
103
103
  break;
104
104
  }
105
105
  return _context3.abrupt("return", {
@@ -107,29 +107,29 @@ var getLocalPreview = exports.getLocalPreview = /*#__PURE__*/function () {
107
107
  orientation: 1,
108
108
  source: 'local'
109
109
  });
110
- case 14:
110
+ case 4:
111
111
  if (!(value instanceof Blob)) {
112
- _context3.next = 23;
112
+ _context3.next = 8;
113
113
  break;
114
114
  }
115
115
  _value = value, type = _value.type;
116
116
  mediaType = (0, _mediaCommon.getMediaTypeFromMimeType)(type);
117
- _context3.t1 = mediaType;
118
- _context3.next = _context3.t1 === 'image' ? 20 : _context3.t1 === 'video' ? 21 : 22;
117
+ _t4 = mediaType;
118
+ _context3.next = _t4 === 'image' ? 5 : _t4 === 'video' ? 6 : 7;
119
119
  break;
120
- case 20:
120
+ case 5:
121
121
  return _context3.abrupt("return", getImageLocalPreview(value));
122
- case 21:
122
+ case 6:
123
123
  return _context3.abrupt("return", getVideoLocalPreview(value));
124
- case 22:
124
+ case 7:
125
125
  throw new _errors.LocalPreviewError('local-preview-unsupported');
126
- case 23:
126
+ case 8:
127
127
  throw new _errors.LocalPreviewError('local-preview-unsupported');
128
- case 24:
128
+ case 9:
129
129
  case "end":
130
130
  return _context3.stop();
131
131
  }
132
- }, _callee3, null, [[0, 7]]);
132
+ }, _callee3, null, [[0, 2]]);
133
133
  }));
134
134
  return function getLocalPreview(_x3) {
135
135
  return _ref3.apply(this, arguments);
@@ -137,29 +137,29 @@ var getLocalPreview = exports.getLocalPreview = /*#__PURE__*/function () {
137
137
  }();
138
138
  var getRemotePreview = exports.getRemotePreview = /*#__PURE__*/function () {
139
139
  var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(mediaClient, id, params, traceContext) {
140
- var blob;
141
- return _regenerator.default.wrap(function _callee4$(_context4) {
140
+ var blob, _t5;
141
+ return _regenerator.default.wrap(function (_context4) {
142
142
  while (1) switch (_context4.prev = _context4.next) {
143
143
  case 0:
144
144
  _context4.prev = 0;
145
- _context4.next = 3;
145
+ _context4.next = 1;
146
146
  return mediaClient.getImage(id, params, undefined, undefined, traceContext);
147
- case 3:
147
+ case 1:
148
148
  blob = _context4.sent;
149
149
  return _context4.abrupt("return", {
150
150
  dataURI: URL.createObjectURL(blob),
151
151
  orientation: 1,
152
152
  source: 'remote'
153
153
  });
154
- case 7:
155
- _context4.prev = 7;
156
- _context4.t0 = _context4["catch"](0);
157
- throw new _errors.RemotePreviewError('remote-preview-fetch', _context4.t0 instanceof Error ? _context4.t0 : undefined);
158
- case 10:
154
+ case 2:
155
+ _context4.prev = 2;
156
+ _t5 = _context4["catch"](0);
157
+ throw new _errors.RemotePreviewError('remote-preview-fetch', _t5 instanceof Error ? _t5 : undefined);
158
+ case 3:
159
159
  case "end":
160
160
  return _context4.stop();
161
161
  }
162
- }, _callee4, null, [[0, 7]]);
162
+ }, _callee4, null, [[0, 2]]);
163
163
  }));
164
164
  return function getRemotePreview(_x4, _x5, _x6, _x7) {
165
165
  return _ref4.apply(this, arguments);
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "extractCdnSigningParams", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _getPreview.extractCdnSigningParams;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "getAndCacheLocalPreview", {
7
13
  enumerable: true,
8
14
  get: function get() {
@@ -9,7 +9,7 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"))
9
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
10
  var takeSnapshot = exports.takeSnapshot = /*#__PURE__*/function () {
11
11
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(blob) {
12
- return _regenerator.default.wrap(function _callee$(_context) {
12
+ return _regenerator.default.wrap(function (_context) {
13
13
  while (1) switch (_context.prev = _context.next) {
14
14
  case 0:
15
15
  return _context.abrupt("return", new Promise(function (resolve, reject) {
@@ -45,7 +45,8 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
45
45
  allowAnimated = _ref$allowAnimated === void 0 ? true : _ref$allowAnimated,
46
46
  upscale = _ref.upscale,
47
47
  maxAge = _ref.maxAge,
48
- source = _ref.source;
48
+ source = _ref.source,
49
+ initialFileState = _ref.initialFileState;
49
50
  var mediaClient = (0, _mediaClientReact.useMediaClient)();
50
51
  var _useState = (0, _react.useState)('loading'),
51
52
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
@@ -122,7 +123,15 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
122
123
  // where no SSR occurred, so we should skip SSR preview generation entirely.
123
124
  if (ssr === 'server' || ssrData) {
124
125
  try {
125
- return (0, _getPreview.getSSRPreview)(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs);
126
+ // When the relay/SSR-seed path provided a pre-signed CDN URL,
127
+ // overlay its CDN-signing query params on the URL produced by
128
+ // getImageUrlSync. This makes the SSR-rendered HTML use the
129
+ // cdn-signed URL directly (no auth-token -> cdn-signed swap on
130
+ // hydration) and the 'ssr-data' rehydration path inherits it
131
+ // automatically via globalScope.
132
+ var seededCdnUrl = initialFileState && initialFileState.status !== 'error' ? initialFileState.previewCdnUrl : undefined;
133
+ var cdnSigningParams = seededCdnUrl && (0, _platformFeatureFlags.fg)('platform_media_ssr_data_seed') ? (0, _getPreview.extractCdnSigningParams)(seededCdnUrl) : undefined;
134
+ return (0, _getPreview.getSSRPreview)(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs, cdnSigningParams);
126
135
  } catch (e) {
127
136
  ssrReliabilityRef.current = _objectSpread(_objectSpread({}, ssrReliabilityRef.current), {}, (0, _defineProperty2.default)({}, ssr, _objectSpread({
128
137
  status: 'fail'
@@ -154,6 +163,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
154
163
  //----------------------------------------------------------------
155
164
 
156
165
  var _useFileState = (0, _mediaClientReact.useFileState)(identifier.id, {
166
+ initialFileState: initialFileState,
157
167
  skipRemote: skipRemote,
158
168
  collectionName: identifier.collectionName,
159
169
  occurrenceKey: identifier.occurrenceKey