@atlaskit/smart-card 44.24.2 → 44.25.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 (63) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/extractors/flexible/extract-state.js +4 -1
  3. package/dist/cjs/ssr.js +14 -3
  4. package/dist/cjs/state/actions/index.js +111 -23
  5. package/dist/cjs/state/hooks/use-resolve/index.js +7 -13
  6. package/dist/cjs/state/hooks/use-response/index.js +9 -3
  7. package/dist/cjs/state/hooks/usePrefetch.js +7 -6
  8. package/dist/cjs/state/hooks/useSmartLink.js +12 -3
  9. package/dist/cjs/state/hooks-external/useSmartLinkActions.js +3 -1
  10. package/dist/cjs/utils/analytics/analytics.js +1 -1
  11. package/dist/cjs/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +1 -1
  12. package/dist/cjs/view/CardWithUrl/component.js +25 -3
  13. package/dist/cjs/view/CardWithUrl/loader.js +7 -1
  14. package/dist/cjs/view/EmbedCard/useEmbedResolvePostMessageListener.js +4 -1
  15. package/dist/cjs/view/FlexibleCard/components/actions/action/server-action/index.js +5 -1
  16. package/dist/cjs/view/FlexibleCard/components/elements/common/base-lozenge-element/lozenge-action/index.js +5 -1
  17. package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +2 -1
  18. package/dist/cjs/view/LinkUrl/index.js +1 -1
  19. package/dist/es2019/extractors/flexible/extract-state.js +4 -1
  20. package/dist/es2019/ssr.js +14 -3
  21. package/dist/es2019/state/actions/index.js +85 -12
  22. package/dist/es2019/state/hooks/use-resolve/index.js +11 -2
  23. package/dist/es2019/state/hooks/use-response/index.js +9 -5
  24. package/dist/es2019/state/hooks/usePrefetch.js +8 -7
  25. package/dist/es2019/state/hooks/useSmartLink.js +13 -3
  26. package/dist/es2019/state/hooks-external/useSmartLinkActions.js +3 -1
  27. package/dist/es2019/utils/analytics/analytics.js +1 -1
  28. package/dist/es2019/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +1 -1
  29. package/dist/es2019/view/CardWithUrl/component.js +28 -4
  30. package/dist/es2019/view/CardWithUrl/loader.js +7 -1
  31. package/dist/es2019/view/EmbedCard/useEmbedResolvePostMessageListener.js +4 -1
  32. package/dist/es2019/view/FlexibleCard/components/actions/action/server-action/index.js +5 -1
  33. package/dist/es2019/view/FlexibleCard/components/elements/common/base-lozenge-element/lozenge-action/index.js +5 -1
  34. package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +2 -1
  35. package/dist/es2019/view/LinkUrl/index.js +1 -1
  36. package/dist/esm/extractors/flexible/extract-state.js +4 -1
  37. package/dist/esm/ssr.js +14 -3
  38. package/dist/esm/state/actions/index.js +111 -23
  39. package/dist/esm/state/hooks/use-resolve/index.js +7 -13
  40. package/dist/esm/state/hooks/use-response/index.js +9 -3
  41. package/dist/esm/state/hooks/usePrefetch.js +7 -6
  42. package/dist/esm/state/hooks/useSmartLink.js +13 -3
  43. package/dist/esm/state/hooks-external/useSmartLinkActions.js +3 -1
  44. package/dist/esm/utils/analytics/analytics.js +1 -1
  45. package/dist/esm/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +1 -1
  46. package/dist/esm/view/CardWithUrl/component.js +26 -4
  47. package/dist/esm/view/CardWithUrl/loader.js +7 -1
  48. package/dist/esm/view/EmbedCard/useEmbedResolvePostMessageListener.js +4 -1
  49. package/dist/esm/view/FlexibleCard/components/actions/action/server-action/index.js +5 -1
  50. package/dist/esm/view/FlexibleCard/components/elements/common/base-lozenge-element/lozenge-action/index.js +5 -1
  51. package/dist/esm/view/HoverCard/components/HoverCardComponent.js +2 -1
  52. package/dist/esm/view/LinkUrl/index.js +1 -1
  53. package/dist/types/state/actions/index.d.ts +3 -2
  54. package/dist/types/state/hooks/use-resolve/index.d.ts +9 -1
  55. package/dist/types/state/hooks/use-response/index.d.ts +2 -2
  56. package/dist/types/state/hooks/usePrefetch.d.ts +2 -1
  57. package/dist/types/state/hooks/useSmartLink.d.ts +14 -6
  58. package/dist/types-ts4.5/state/actions/index.d.ts +3 -2
  59. package/dist/types-ts4.5/state/hooks/use-resolve/index.d.ts +9 -1
  60. package/dist/types-ts4.5/state/hooks/use-response/index.d.ts +2 -2
  61. package/dist/types-ts4.5/state/hooks/usePrefetch.d.ts +2 -1
  62. package/dist/types-ts4.5/state/hooks/useSmartLink.d.ts +14 -6
  63. package/package.json +6 -3
@@ -100,6 +100,8 @@ export var useSmartCardActions = function useSmartCardActions(id, url) {
100
100
  url: url
101
101
  }, undefined, undefined, metadataStatus));
102
102
  }, [dispatch, url]);
103
+
104
+ // Original resolve function — signature kept intact for maximum safety when FG is off.
103
105
  var resolve = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
104
106
  var resourceUrl,
105
107
  isReloading,
@@ -111,45 +113,131 @@ export var useSmartCardActions = function useSmartCardActions(id, url) {
111
113
  resourceUrl = _args.length > 0 && _args[0] !== undefined ? _args[0] : url;
112
114
  isReloading = _args.length > 1 && _args[1] !== undefined ? _args[1] : false;
113
115
  isMetadataRequest = _args.length > 2 && _args[2] !== undefined ? _args[2] : false;
114
- return _context.abrupt("return", resolveUrl(resourceUrl, isReloading, isMetadataRequest, id));
116
+ return _context.abrupt("return", resolveUrl({
117
+ url: resourceUrl,
118
+ isReloading: isReloading,
119
+ isMetadataRequest: isMetadataRequest,
120
+ id: id
121
+ }));
115
122
  case 1:
116
123
  case "end":
117
124
  return _context.stop();
118
125
  }
119
126
  }, _callee);
120
127
  })), [id, resolveUrl, url]);
121
- var register = useCallback(function () {
128
+
129
+ // New resolve function accepting ResolveUrlParams (minus 'id' which is closed over).
130
+ // Used when FG is enabled to pass appearance to ORS.
131
+ var resolveNew = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
132
+ var params,
133
+ _params$url,
134
+ resourceUrl,
135
+ _params$isReloading,
136
+ isReloading,
137
+ _params$isMetadataReq,
138
+ isMetadataRequest,
139
+ appearance,
140
+ _args2 = arguments;
141
+ return _regeneratorRuntime.wrap(function (_context2) {
142
+ while (1) switch (_context2.prev = _context2.next) {
143
+ case 0:
144
+ params = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
145
+ _params$url = params.url, resourceUrl = _params$url === void 0 ? url : _params$url, _params$isReloading = params.isReloading, isReloading = _params$isReloading === void 0 ? false : _params$isReloading, _params$isMetadataReq = params.isMetadataRequest, isMetadataRequest = _params$isMetadataReq === void 0 ? false : _params$isMetadataReq, appearance = params.appearance;
146
+ return _context2.abrupt("return", resolveUrl({
147
+ url: resourceUrl,
148
+ isReloading: isReloading,
149
+ isMetadataRequest: isMetadataRequest,
150
+ id: id,
151
+ appearance: appearance
152
+ }));
153
+ case 1:
154
+ case "end":
155
+ return _context2.stop();
156
+ }
157
+ }, _callee2);
158
+ })), [id, resolveUrl, url]);
159
+
160
+ /**
161
+ * Register a smart link for resolution.
162
+ * @param appearance - Card appearance hint for ORS to optimize response payload.
163
+ * When 'inline', ORS returns minimal data (title, status).
164
+ * When 'block' or 'embed', ORS returns full data including summary.
165
+ */
166
+ var register = useCallback(function (appearance) {
122
167
  var _getSmartLinkState = getSmartLinkState(),
123
168
  details = _getSmartLinkState.details;
124
169
  if (!details) {
125
170
  dispatch(cardAction(ACTION_RESOLVING, {
126
171
  url: url
127
172
  }));
173
+ // Always set metadataStatus to 'pending' during registration to prevent
174
+ // loadMetadata from firing a duplicate concurrent fetch if a hover card
175
+ // mounts while registration is in-flight. This matches pre-PR behaviour.
128
176
  setMetadataStatus('pending');
129
177
  }
130
- return resolve();
131
- }, [getSmartLinkState, resolve, dispatch, url, setMetadataStatus]);
132
- var reload = useCallback(function () {
178
+ if (fg('platform_smartlink_inline_resolve_optimization')) {
179
+ return resolveNew({
180
+ url: url,
181
+ appearance: appearance
182
+ });
183
+ }
184
+ return resolve(url);
185
+ }, [getSmartLinkState, resolve, resolveNew, dispatch, url, setMetadataStatus]);
186
+ var reload = useCallback(function (appearance) {
133
187
  var _getSmartLinkState2 = getSmartLinkState(),
134
188
  details = _getSmartLinkState2.details;
135
189
  var definitionId = getDefinitionId(details);
136
- if (definitionId) {
137
- getByDefinitionId(definitionId, getState()).map(function (url) {
138
- return resolve(url, true);
139
- });
190
+ if (fg('platform_smartlink_inline_resolve_optimization')) {
191
+ if (definitionId) {
192
+ getByDefinitionId(definitionId, getState()).map(function (reloadUrl) {
193
+ return resolveNew({
194
+ url: reloadUrl,
195
+ isReloading: true,
196
+ appearance: appearance
197
+ });
198
+ });
199
+ } else {
200
+ resolveNew({
201
+ url: url,
202
+ isReloading: true,
203
+ appearance: appearance
204
+ });
205
+ }
140
206
  } else {
141
- resolve(url, true);
207
+ if (definitionId) {
208
+ getByDefinitionId(definitionId, getState()).map(function (reloadUrl) {
209
+ return resolve(reloadUrl, true);
210
+ });
211
+ } else {
212
+ resolve(url, true);
213
+ }
142
214
  }
143
- }, [getSmartLinkState, url, getState, resolve]);
215
+ }, [getSmartLinkState, url, getState, resolve, resolveNew]);
216
+
217
+ /**
218
+ * Load metadata for hover card preview.
219
+ * This always requests 'block' appearance to get full data including summary.
220
+ *
221
+ * Inline optimized and SSR-resolved links keep metadataStatus pending until hover
222
+ * requests the full block response.
223
+ */
144
224
  var loadMetadata = useCallback(function () {
145
225
  var _getSmartLinkState3 = getSmartLinkState(),
146
226
  metadataStatus = _getSmartLinkState3.metadataStatus;
147
- //metadataStatus will be undefined for SSR links only
148
- if (metadataStatus === undefined) {
227
+ var needsBlockData = metadataStatus === undefined || metadataStatus === 'pending' && fg('platform_smartlink_inline_resolve_optimization');
228
+ if (needsBlockData) {
149
229
  setMetadataStatus('pending');
230
+ if (fg('platform_smartlink_inline_resolve_optimization')) {
231
+ // Always request 'block' appearance for hover card metadata to get full data
232
+ return resolveNew({
233
+ url: url,
234
+ isMetadataRequest: true,
235
+ appearance: 'block'
236
+ });
237
+ }
150
238
  return resolve(url, false, true);
151
239
  }
152
- }, [getSmartLinkState, resolve, setMetadataStatus, url]);
240
+ }, [getSmartLinkState, resolve, resolveNew, setMetadataStatus, url]);
153
241
  var authorize = useCallback(function (appearance) {
154
242
  var _getSmartLinkState4 = getSmartLinkState(),
155
243
  details = _getSmartLinkState4.details,
@@ -230,18 +318,18 @@ export var useSmartCardActions = function useSmartCardActions(id, url) {
230
318
  }
231
319
  }, [getSmartLinkState, id, reload, fireEvent, flags, url]);
232
320
  var invoke = useCallback( /*#__PURE__*/function () {
233
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(opts, appearance) {
321
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(opts, appearance) {
234
322
  var key, action, source;
235
- return _regeneratorRuntime.wrap(function (_context2) {
236
- while (1) switch (_context2.prev = _context2.next) {
323
+ return _regeneratorRuntime.wrap(function (_context3) {
324
+ while (1) switch (_context3.prev = _context3.next) {
237
325
  case 0:
238
326
  key = opts.key, action = opts.action;
239
327
  source = opts.source || appearance;
240
328
  if (!(opts.type === 'client')) {
241
- _context2.next = 2;
329
+ _context3.next = 2;
242
330
  break;
243
331
  }
244
- _context2.next = 1;
332
+ _context3.next = 1;
245
333
  return invokeClientAction({
246
334
  actionFn: opts.action.promise,
247
335
  actionType: action.type,
@@ -249,15 +337,15 @@ export var useSmartCardActions = function useSmartCardActions(id, url) {
249
337
  extensionKey: key
250
338
  });
251
339
  case 1:
252
- return _context2.abrupt("return", _context2.sent);
340
+ return _context3.abrupt("return", _context3.sent);
253
341
  case 2:
254
342
  case "end":
255
- return _context2.stop();
343
+ return _context3.stop();
256
344
  }
257
- }, _callee2);
345
+ }, _callee3);
258
346
  }));
259
347
  return function (_x, _x2) {
260
- return _ref3.apply(this, arguments);
348
+ return _ref4.apply(this, arguments);
261
349
  };
262
350
  }(), [invokeClientAction]);
263
351
  return useMemo(function () {
@@ -3,6 +3,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { useCallback } from 'react';
4
4
  import { isEntityPresent } from '@atlaskit/link-extractors';
5
5
  import { useSmartLinkContext } from '@atlaskit/link-provider';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { SmartLinkStatus } from '../../../constants';
7
8
  import { addMetadataToExperience } from '../../analytics';
8
9
  import useResponse from '../use-response';
@@ -19,20 +20,12 @@ var useResolve = function useResolve() {
19
20
  handleResolvedLinkResponse = _useResponse.handleResolvedLinkResponse,
20
21
  handleResolvedLinkError = _useResponse.handleResolvedLinkError;
21
22
  return useCallback( /*#__PURE__*/function () {
22
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
23
- var isReloading,
24
- isMetadataRequest,
25
- id,
26
- _ref2,
27
- details,
28
- hasData,
29
- _args = arguments;
23
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(params) {
24
+ var url, _params$isReloading, isReloading, _params$isMetadataReq, isMetadataRequest, _params$id, id, appearance, _ref2, details, hasData, metadataStatus;
30
25
  return _regeneratorRuntime.wrap(function (_context) {
31
26
  while (1) switch (_context.prev = _context.next) {
32
27
  case 0:
33
- isReloading = _args.length > 1 && _args[1] !== undefined ? _args[1] : false;
34
- isMetadataRequest = _args.length > 2 && _args[2] !== undefined ? _args[2] : false;
35
- id = _args.length > 3 && _args[3] !== undefined ? _args[3] : '';
28
+ url = params.url, _params$isReloading = params.isReloading, isReloading = _params$isReloading === void 0 ? false : _params$isReloading, _params$isMetadataReq = params.isMetadataRequest, isMetadataRequest = _params$isMetadataReq === void 0 ? false : _params$isMetadataReq, _params$id = params.id, id = _params$id === void 0 ? '' : _params$id, appearance = params.appearance;
36
29
  _ref2 = getState()[url] || {
37
30
  status: SmartLinkStatus.Pending,
38
31
  details: undefined
@@ -42,8 +35,9 @@ var useResolve = function useResolve() {
42
35
  _context.next = 1;
43
36
  break;
44
37
  }
45
- return _context.abrupt("return", connections.client.fetchData(url, isReloading).then(function (response) {
46
- return handleResolvedLinkResponse(url, response, isReloading, isMetadataRequest);
38
+ metadataStatus = appearance === 'inline' && !isMetadataRequest && fg('platform_smartlink_inline_resolve_optimization') ? 'pending' : undefined;
39
+ return _context.abrupt("return", connections.client.fetchData(url, isReloading, appearance).then(function (response) {
40
+ return handleResolvedLinkResponse(url, response, isReloading, isMetadataRequest, metadataStatus);
47
41
  }).catch(function (error) {
48
42
  return handleResolvedLinkError(url, error, undefined, isMetadataRequest);
49
43
  }));
@@ -2,6 +2,7 @@ import { useCallback, useMemo } from 'react';
2
2
  import { unstable_batchedUpdates } from 'react-dom';
3
3
  import { useSmartLinkContext } from '@atlaskit/link-provider';
4
4
  import { ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, ACTION_RESOLVED, ACTION_UPDATE_METADATA_STATUS, APIError, cardAction, getStatus } from '@atlaskit/linking-common';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import { SmartLinkStatus } from '../../../constants';
6
7
  import { getUnauthorizedJsonLd } from '../../../utils/jsonld';
7
8
  import { ERROR_MESSAGE_FATAL, ERROR_MESSAGE_METADATA, ERROR_MESSAGE_OAUTH } from '../../actions/constants';
@@ -71,8 +72,9 @@ var useResponse = function useResponse() {
71
72
  }
72
73
  }, [getState, setMetadataStatus, dispatch]);
73
74
  var handleResolvedLinkSuccess = useCallback(function (resourceUrl, response, isReloading, isMetadataRequest) {
74
- //if a link resolves normally, metadata will also always be resolved
75
- setMetadataStatus(resourceUrl, 'resolved');
75
+ var metadataStatus = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'resolved';
76
+ // Some optimized resolves intentionally leave metadata pending so hover can fetch it.
77
+ setMetadataStatus(resourceUrl, fg('platform_smartlink_inline_resolve_optimization') ? metadataStatus : 'resolved');
76
78
  // Dispatch Analytics and resolved card action - including unauthorized states.
77
79
  if (isReloading) {
78
80
  dispatch(cardAction(ACTION_RELOADING, {
@@ -87,6 +89,10 @@ var useResponse = function useResponse() {
87
89
  var handleResolvedLinkResponse = useCallback(function (resourceUrl, response) {
88
90
  var isReloading = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
89
91
  var isMetadataRequest = arguments.length > 3 ? arguments[3] : undefined;
92
+ var metadataStatus = arguments.length > 4 ? arguments[4] : undefined;
93
+ if (!resourceUrl) {
94
+ return;
95
+ }
90
96
  var hostname = new URL(resourceUrl).hostname;
91
97
  var nextStatus = response ? getStatus(response) : 'fatal';
92
98
 
@@ -116,7 +122,7 @@ var useResponse = function useResponse() {
116
122
  * https://react-redux.js.org/api/batch
117
123
  */
118
124
  unstable_batchedUpdates(function () {
119
- handleResolvedLinkSuccess(resourceUrl, response, isReloading, isMetadataRequest);
125
+ handleResolvedLinkSuccess(resourceUrl, response, isReloading, isMetadataRequest, metadataStatus);
120
126
  });
121
127
  }, [handleResolvedLinkError, handleResolvedLinkSuccess, hasAuthFlowSupported]);
122
128
  return useMemo(function () {
@@ -3,7 +3,8 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { useCallback } from 'react';
4
4
  import { useSmartLinkContext } from '@atlaskit/link-provider';
5
5
  import { ACTION_UPDATE_METADATA_STATUS, cardAction } from '@atlaskit/linking-common';
6
- export function usePrefetch(url) {
6
+ import { fg } from '@atlaskit/platform-feature-flags';
7
+ export function usePrefetch(url, appearance) {
7
8
  var _useSmartLinkContext = useSmartLinkContext(),
8
9
  store = _useSmartLinkContext.store,
9
10
  prefetchStore = _useSmartLinkContext.prefetchStore,
@@ -47,7 +48,7 @@ export function usePrefetch(url) {
47
48
  // we create between browser -> ORS when making network requests.
48
49
  _context.prev = 2;
49
50
  _context.next = 3;
50
- return client.prefetchData(url);
51
+ return client.prefetchData(url, appearance);
51
52
  case 3:
52
53
  response = _context.sent;
53
54
  // Once the data comes back, we put the link in the `resolved` status. This ensures
@@ -59,11 +60,11 @@ export function usePrefetch(url) {
59
60
  url: url,
60
61
  payload: response
61
62
  });
62
- // Put the metadata in resolved state, theres no need for a pending or errored state as
63
- // we are following the same render flow as described by the comments above and below.
63
+ // Put the metadata status: 'pending' for inline appearance when FG is on, so HoverCard
64
+ // can upgrade to full block data. Otherwise 'resolved' preserves existing behaviour.
64
65
  dispatch(cardAction(ACTION_UPDATE_METADATA_STATUS, {
65
66
  url: url
66
- }, undefined, undefined, 'resolved'));
67
+ }, undefined, undefined, appearance === 'inline' && fg('platform_smartlink_inline_resolve_optimization') ? 'pending' : 'resolved'));
67
68
  }
68
69
  _context.next = 5;
69
70
  break;
@@ -75,5 +76,5 @@ export function usePrefetch(url) {
75
76
  return _context.stop();
76
77
  }
77
78
  }, _callee, null, [[2, 4]]);
78
- })), [store, prefetchStore, connections, url, getState, client, dispatch]);
79
+ })), [store, prefetchStore, connections, url, getState, client, dispatch, appearance]);
79
80
  }
@@ -1,11 +1,21 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import { useEffect, useState } from 'react';
3
3
  import { useSmartLinkContext } from '@atlaskit/link-provider';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  import { useSmartCardActions as useSmartLinkActions } from '../actions';
5
6
  import { useSmartLinkConfig } from '../config';
6
7
  import { useSmartLinkRenderers } from '../renderers';
7
8
  import { useSmartCardState as useSmartLinkState } from '../store';
8
- export function useSmartLink(id, url) {
9
+
10
+ /**
11
+ * Hook for smart link state and actions.
12
+ * @param id - Unique identifier for the smart link
13
+ * @param url - The URL to resolve
14
+ * @param appearance - Card appearance hint for ORS to optimize response payload.
15
+ * When 'inline', ORS returns minimal data (title, status).
16
+ * When 'block' or 'embed', ORS returns full data including summary.
17
+ */
18
+ export function useSmartLink(id, url, appearance) {
9
19
  var state = useSmartLinkState(url);
10
20
  var _useSmartLinkContext = useSmartLinkContext(),
11
21
  store = _useSmartLinkContext.store,
@@ -20,9 +30,9 @@ export function useSmartLink(id, url) {
20
30
  _useState2 = _slicedToArray(_useState, 2),
21
31
  error = _useState2[0],
22
32
  setError = _useState2[1];
23
- // Register the current card.
33
+ // Register the current card with appearance hint for optimized ORS response.
24
34
  var register = function register() {
25
- actions.register().catch(function (err) {
35
+ actions.register(fg('platform_smartlink_inline_resolve_optimization') ? appearance : undefined).catch(function (err) {
26
36
  return setError(err);
27
37
  });
28
38
  };
@@ -42,7 +42,9 @@ export function useSmartLinkActions(_ref) {
42
42
  details: linkState.details
43
43
  });
44
44
  if (expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && prefetch && !linkState.details) {
45
- resolve(url);
45
+ resolve({
46
+ url: url
47
+ });
46
48
  }
47
49
  if (linkState.details && !(actionOptions !== null && actionOptions !== void 0 && actionOptions.hide)) {
48
50
  var actions = [];
@@ -4,7 +4,7 @@ export var ANALYTICS_CHANNEL = 'media';
4
4
  export var context = {
5
5
  componentName: 'smart-cards',
6
6
  packageName: "@atlaskit/smart-card" || '',
7
- packageVersion: "44.24.1" || ''
7
+ packageVersion: "44.24.2" || ''
8
8
  };
9
9
  export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
10
10
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -28,7 +28,7 @@ function LazyIntersectionObserverCardOld(props) {
28
28
  var appearance = props.appearance,
29
29
  url = props.url,
30
30
  id = props.id;
31
- var prefetch = usePrefetch(url);
31
+ var prefetch = usePrefetch(url, appearance);
32
32
  var Component = appearance === 'inline' ? 'span' : 'div';
33
33
  var ComponentObserver = Component;
34
34
  var onIntersection = useCallback(function (entries, observer) {
@@ -1,7 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
- import React, { useCallback, useEffect, useMemo } from 'react';
4
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
5
5
  import { useAnalyticsEvents as useAnalyticsEventsNext } from '@atlaskit/analytics-next';
6
6
  import { extractSmartLinkEmbed } from '@atlaskit/link-extractors';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -68,7 +68,10 @@ function Component(_ref) {
68
68
  }, [children, ui]);
69
69
 
70
70
  // Get state, actions for this card.
71
- var _useSmartLink = useSmartLink(id, url),
71
+ // appearance is pre-resolved by the caller (loader.tsx for Card, ssr.tsx for CardSSR):
72
+ // FlexibleCards are always passed appearance='block' when FG is on, so component.tsx
73
+ // simply consumes whatever appearance it receives.
74
+ var _useSmartLink = useSmartLink(id, url, appearance),
72
75
  state = _useSmartLink.state,
73
76
  actions = _useSmartLink.actions,
74
77
  config = _useSmartLink.config,
@@ -261,12 +264,31 @@ function Component(_ref) {
261
264
  });
262
265
  }
263
266
  }, [fire3PClickEvent, shouldFire3PClickEvent]);
267
+ var reload = actions.reload;
264
268
  var handleAuthorize = useCallback(function () {
265
269
  return actions.authorize(appearance);
266
270
  }, [actions, appearance]);
267
271
  var handleRetry = useCallback(function () {
268
- actions.reload();
269
- }, [actions]);
272
+ reload();
273
+ }, [reload]);
274
+ var hasMounted = useRef(false);
275
+ var prevAppearance = useRef(appearance);
276
+
277
+ // When appearance changes from inline to non-inline on a mounted card
278
+ // (e.g. direct consumer changes inline → block/embed), reload with the new appearance
279
+ // so ORS can return the appropriate full data. We intentionally do NOT reload on
280
+ // block → embed or embed → block transitions since both already have full ORS data.
281
+ useEffect(function () {
282
+ if (!hasMounted.current) {
283
+ hasMounted.current = true;
284
+ prevAppearance.current = appearance;
285
+ return;
286
+ }
287
+ if (prevAppearance.current === 'inline' && appearance !== 'inline' && fg('platform_smartlink_inline_resolve_optimization')) {
288
+ reload(appearance);
289
+ }
290
+ prevAppearance.current = appearance;
291
+ }, [appearance, reload]);
270
292
  var handleInvoke = useCallback(function (opts) {
271
293
  return actions.invoke(opts, appearance);
272
294
  }, [actions, appearance]);
@@ -7,6 +7,7 @@ import { ErrorBoundary } from 'react-error-boundary';
7
7
  import { di } from 'react-magnetic-di';
8
8
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
9
9
  import uuid from 'uuid';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { useAnalyticsEvents } from '../../common/analytics/generated/use-analytics-events';
11
12
  import { failUfoExperience, startUfoExperience } from '../../state/analytics';
12
13
  import { importWithRetry } from '../../utils';
@@ -112,10 +113,15 @@ export function CardWithURLRenderer(props) {
112
113
  var ErrorFallback = function ErrorFallback() {
113
114
  return /*#__PURE__*/React.createElement(FallbackComponent, null);
114
115
  };
116
+
117
+ // FlexibleCards always need full ORS data regardless of appearance prop,
118
+ // because they render custom blocks (TitleBlock etc.) requiring complete response.
119
+ // Override appearance to 'block' for all FlexibleCards when FG is enabled.
120
+ var effectiveAppearance = isFlexibleUi && fg('platform_smartlink_inline_resolve_optimization') ? 'block' : appearance;
115
121
  var cardWithUrlProps = {
116
122
  id: id,
117
123
  url: url,
118
- appearance: appearance,
124
+ appearance: effectiveAppearance,
119
125
  onClick: onClick,
120
126
  isSelected: isSelected,
121
127
  isHovered: isHovered,
@@ -12,7 +12,10 @@ export var useEmbedResolvePostMessageListener = function useEmbedResolvePostMess
12
12
  }
13
13
  var isFromExpectedIframe = embedIframeRef && event.source === ((_embedIframeRef$curre = embedIframeRef.current) === null || _embedIframeRef$curre === void 0 ? void 0 : _embedIframeRef$curre.contentWindow);
14
14
  if (event.data === 'force-resolve-smart-link' && isFromExpectedIframe) {
15
- resolve(url, true);
15
+ resolve({
16
+ url: url,
17
+ isReloading: true
18
+ });
16
19
  }
17
20
  };
18
21
  window.addEventListener('message', messageCallback);
@@ -56,7 +56,11 @@ var ServerAction = function ServerAction(_ref) {
56
56
  break;
57
57
  }
58
58
  _context.next = 3;
59
- return reload(action.reload.url, true, undefined, action.reload.id);
59
+ return reload({
60
+ url: action.reload.url,
61
+ isReloading: true,
62
+ id: action.reload.id
63
+ });
60
64
  case 3:
61
65
  setIsLoading(false);
62
66
  if (onClick) {
@@ -183,7 +183,11 @@ var LozengeAction = function LozengeAction(_ref) {
183
183
  break;
184
184
  }
185
185
  _context2.next = 2;
186
- return reload(url, true, undefined, linkId);
186
+ return reload({
187
+ url: url,
188
+ isReloading: true,
189
+ id: linkId
190
+ });
187
191
  case 2:
188
192
  _context2.next = 4;
189
193
  break;
@@ -3,6 +3,7 @@ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProper
3
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
4
  var _excluded = ["aria-haspopup", "aria-expanded"];
5
5
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import Popup from '@atlaskit/popup';
7
8
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
9
  import { ActionName, CardDisplay } from '../../../constants';
@@ -135,7 +136,7 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
135
136
  // to minimize the loading state
136
137
  var initResolve = useCallback(function () {
137
138
  // this check covers both non-SSR (status) & SSR case (metadataStatus)
138
- var isLinkUnresolved = linkState.status === 'pending' || !linkState.metadataStatus;
139
+ var isLinkUnresolved = linkState.status === 'pending' || !linkState.metadataStatus || linkState.status === 'resolved' && linkState.metadataStatus === 'pending' && fg('platform_smartlink_inline_resolve_optimization');
139
140
  if (!resolveTimeOutId.current && isLinkUnresolved) {
140
141
  resolveTimeOutId.current = setTimeout(function () {
141
142
  if (linkState.status === 'pending') {
@@ -12,7 +12,7 @@ import LinkWarningModal from './LinkWarningModal';
12
12
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
13
13
  var PACKAGE_DATA = {
14
14
  packageName: "@atlaskit/smart-card",
15
- packageVersion: "44.24.1",
15
+ packageVersion: "44.24.2",
16
16
  componentName: 'linkUrl'
17
17
  };
18
18
  var LinkUrl = function LinkUrl(_ref) {
@@ -1,10 +1,11 @@
1
1
  import { type JsonLd } from '@atlaskit/json-ld-types';
2
+ import { type CardAppearance } from '@atlaskit/linking-common';
2
3
  import { type InvokeClientOpts, type InvokeServerOpts } from '../../model/invoke-opts';
3
4
  import { type CardInnerAppearance } from '../../view/Card/types';
4
5
  export declare const useSmartCardActions: (id: string, url: string) => {
5
6
  authorize: (appearance: CardInnerAppearance) => void;
6
7
  invoke: (opts: InvokeClientOpts | InvokeServerOpts, appearance: CardInnerAppearance) => Promise<JsonLd.Response | void>;
7
8
  loadMetadata: () => Promise<void> | undefined;
8
- register: () => Promise<void>;
9
- reload: () => void;
9
+ register: (appearance?: CardAppearance) => Promise<void>;
10
+ reload: (appearance?: CardAppearance) => void;
10
11
  };
@@ -1,3 +1,11 @@
1
- declare const useResolve: () => ((url: string, isReloading?: boolean, isMetadataRequest?: boolean, id?: string) => Promise<void>);
1
+ import type { CardAppearance } from '@atlaskit/linking-common';
2
+ export interface ResolveUrlParams {
3
+ appearance?: CardAppearance;
4
+ id?: string;
5
+ isMetadataRequest?: boolean;
6
+ isReloading?: boolean;
7
+ url: string;
8
+ }
9
+ declare const useResolve: () => ((params: ResolveUrlParams) => Promise<void>);
2
10
  export default useResolve;
3
11
  export type ResolveFunction = ReturnType<typeof useResolve>;
@@ -1,7 +1,7 @@
1
1
  import { type JsonLd } from '@atlaskit/json-ld-types';
2
- import { APIError } from '@atlaskit/linking-common';
2
+ import { APIError, type MetadataStatus } from '@atlaskit/linking-common';
3
3
  declare const useResponse: () => {
4
4
  handleResolvedLinkError: (url: string, error: APIError, response?: JsonLd.Response, isMetadataRequest?: boolean) => void;
5
- handleResolvedLinkResponse: (resourceUrl: string, response: JsonLd.Response | undefined, isReloading?: boolean, isMetadataRequest?: boolean) => void;
5
+ handleResolvedLinkResponse: (resourceUrl: string, response: JsonLd.Response | undefined, isReloading?: boolean, isMetadataRequest?: boolean, metadataStatus?: MetadataStatus) => void;
6
6
  };
7
7
  export default useResponse;
@@ -1 +1,2 @@
1
- export declare function usePrefetch(url: string): () => Promise<void>;
1
+ import { type CardAppearance } from '@atlaskit/linking-common';
2
+ export declare function usePrefetch(url: string, appearance?: CardAppearance): () => Promise<void>;
@@ -1,19 +1,25 @@
1
1
  import type { JsonLd } from '@atlaskit/json-ld-types';
2
2
  import { type CardAuthFlowOpts, type CardProviderRenderers } from '@atlaskit/link-provider';
3
- import type { CardState } from '@atlaskit/linking-common';
3
+ import type { CardAppearance, CardState } from '@atlaskit/linking-common';
4
4
  import type { InvokeClientOpts, InvokeServerOpts } from '../../model/invoke-opts';
5
5
  import type { CardInnerAppearance } from '../../view/Card/types';
6
- export declare function useSmartLink(id: string, url: string): {
7
- state: CardState;
6
+ /**
7
+ * Hook for smart link state and actions.
8
+ * @param id - Unique identifier for the smart link
9
+ * @param url - The URL to resolve
10
+ * @param appearance - Card appearance hint for ORS to optimize response payload.
11
+ * When 'inline', ORS returns minimal data (title, status).
12
+ * When 'block' or 'embed', ORS returns full data including summary.
13
+ */
14
+ export declare function useSmartLink(id: string, url: string, appearance?: CardAppearance): {
8
15
  actions: {
9
- register: () => Promise<void>;
10
- reload: () => void;
11
16
  authorize: (appearance: CardInnerAppearance) => void;
12
17
  invoke: (opts: InvokeClientOpts | InvokeServerOpts, appearance: CardInnerAppearance) => Promise<JsonLd.Response | void>;
13
18
  loadMetadata: () => Promise<void> | undefined;
19
+ register: () => Promise<void>;
20
+ reload: (appearance?: CardAppearance) => void;
14
21
  };
15
22
  config: CardAuthFlowOpts | undefined;
16
- renderers: CardProviderRenderers | undefined;
17
23
  error: Error | null;
18
24
  isPreviewPanelAvailable: ((props: {
19
25
  ari: string;
@@ -27,4 +33,6 @@ export declare function useSmartLink(id: string, url: string): {
27
33
  };
28
34
  url: string;
29
35
  }) => void) | undefined;
36
+ renderers: CardProviderRenderers | undefined;
37
+ state: CardState;
30
38
  };
@@ -1,10 +1,11 @@
1
1
  import { type JsonLd } from '@atlaskit/json-ld-types';
2
+ import { type CardAppearance } from '@atlaskit/linking-common';
2
3
  import { type InvokeClientOpts, type InvokeServerOpts } from '../../model/invoke-opts';
3
4
  import { type CardInnerAppearance } from '../../view/Card/types';
4
5
  export declare const useSmartCardActions: (id: string, url: string) => {
5
6
  authorize: (appearance: CardInnerAppearance) => void;
6
7
  invoke: (opts: InvokeClientOpts | InvokeServerOpts, appearance: CardInnerAppearance) => Promise<JsonLd.Response | void>;
7
8
  loadMetadata: () => Promise<void> | undefined;
8
- register: () => Promise<void>;
9
- reload: () => void;
9
+ register: (appearance?: CardAppearance) => Promise<void>;
10
+ reload: (appearance?: CardAppearance) => void;
10
11
  };