@atlaskit/editor-card-provider 8.1.2 → 8.1.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/editor-card-provider
2
2
 
3
+ ## 8.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`04378f6eea483`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/04378f6eea483) -
8
+ Keep Smart Link responses within the current document instead of restoring session storage, behind
9
+ platform_smartlink_document_cache. Use explicit gate branches to separate document caching from
10
+ the existing session-storage cache.
11
+
12
+ ## 8.1.3
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies
17
+
3
18
  ## 8.1.2
4
19
 
5
20
  ### Patch Changes
@@ -9,13 +9,13 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
  var _storageClient = require("@atlaskit/frontend-utilities/storage-client");
12
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
12
13
  var SMART_CARD_CACHE_CLIENT_KEY = 'smart-card-url-data';
13
14
  var SMART_CARD_CACHE_KEY = 'response-cache';
14
15
  var SMART_CARD_CACHE_DEFAULT_MAX_ITEMS = 100;
15
16
  /**
16
- * Singleton cache client for smart link responses. Uses sessionStorage for per-tab isolation (no cross-tab conflicts).
17
- * If switching to localStorage for cross-tab sharing, add a 'storage' event listener in the constructor to sync
18
- * memoryCache when other tabs modify the cache, preventing race conditions from concurrent writes.
17
+ * Singleton cache client for smart link responses shared within the current document.
18
+ * Session storage remains available only for the document-cache gate's control cohort.
19
19
  */
20
20
  var SmartCardLocalCacheClient = exports.SmartCardLocalCacheClient = /*#__PURE__*/function () {
21
21
  function SmartCardLocalCacheClient() {
@@ -25,83 +25,120 @@ var SmartCardLocalCacheClient = exports.SmartCardLocalCacheClient = /*#__PURE__*
25
25
  (0, _defineProperty2.default)(this, "storageClient", new _storageClient.StorageClient(SMART_CARD_CACHE_CLIENT_KEY, {
26
26
  storageEngine: 'sessionStorage'
27
27
  }));
28
+ (0, _defineProperty2.default)(this, "documentCache", {});
28
29
  (0, _defineProperty2.default)(this, "pendingWrite", false);
29
30
  /**
30
31
  * Retrieves the entire cache object from memory
31
32
  * @returns The entire cache object
32
33
  */
33
34
  (0, _defineProperty2.default)(this, "getCache", function () {
34
- return _this.memoryCache;
35
+ if ((0, _fg.fg)('platform_smartlink_document_cache')) {
36
+ // Keep restored session data out of this cache if the gate changes after initialization.
37
+ return _this.documentCache;
38
+ } else {
39
+ return _this.memoryCache;
40
+ }
35
41
  });
36
42
  /**
37
- * Caches the SmartLinkResponse against the provided url in storage
43
+ * Caches the SmartLinkResponse against the provided url
38
44
  * @param url The url (key) to store the response against
39
- * @param response The SmartLinkResponse to be cached in storage
45
+ * @param response The SmartLinkResponse to be cached
40
46
  */
41
47
  (0, _defineProperty2.default)(this, "setItem", function (url, response) {
42
- // Add or update the item in the cache with current timestamp
43
- _this.memoryCache[url] = {
44
- data: response,
45
- timestamp: Date.now()
46
- };
48
+ if ((0, _fg.fg)('platform_smartlink_document_cache')) {
49
+ _this.documentCache[url] = {
50
+ data: response,
51
+ timestamp: Date.now()
52
+ };
53
+ var cacheKeys = Object.keys(_this.documentCache);
54
+ if (cacheKeys.length > _this.maxItems) {
55
+ var sortedKeys = cacheKeys.sort(function (a, b) {
56
+ return _this.documentCache[a].timestamp - _this.documentCache[b].timestamp;
57
+ });
58
+ var itemsToRemove = cacheKeys.length - _this.maxItems;
59
+ var keysToRemove = sortedKeys.slice(0, itemsToRemove);
60
+ keysToRemove.forEach(function (key) {
61
+ delete _this.documentCache[key];
62
+ });
63
+ }
64
+ } else {
65
+ // Add or update the item in the cache with current timestamp
66
+ _this.memoryCache[url] = {
67
+ data: response,
68
+ timestamp: Date.now()
69
+ };
47
70
 
48
- // Apply FIFO behavior if cache exceeds maxItems
49
- var cacheKeys = Object.keys(_this.memoryCache);
50
- if (cacheKeys.length > _this.maxItems) {
51
- // Sort keys by timestamp (oldest first) and remove the oldest items
52
- var sortedKeys = cacheKeys.sort(function (a, b) {
53
- return _this.memoryCache[a].timestamp - _this.memoryCache[b].timestamp;
54
- });
55
- var itemsToRemove = cacheKeys.length - _this.maxItems;
56
- var keysToRemove = sortedKeys.slice(0, itemsToRemove);
57
- keysToRemove.forEach(function (key) {
58
- delete _this.memoryCache[key];
59
- });
60
- }
71
+ // Apply FIFO behavior if cache exceeds maxItems
72
+ var _cacheKeys = Object.keys(_this.memoryCache);
73
+ if (_cacheKeys.length > _this.maxItems) {
74
+ // Sort keys by timestamp (oldest first) and remove the oldest items
75
+ var _sortedKeys = _cacheKeys.sort(function (a, b) {
76
+ return _this.memoryCache[a].timestamp - _this.memoryCache[b].timestamp;
77
+ });
78
+ var _itemsToRemove = _cacheKeys.length - _this.maxItems;
79
+ var _keysToRemove = _sortedKeys.slice(0, _itemsToRemove);
80
+ _keysToRemove.forEach(function (key) {
81
+ delete _this.memoryCache[key];
82
+ });
83
+ }
61
84
 
62
- // Write through to storage asynchronously (non-blocking)
63
- // Debounced to batch multiple rapid calls into a single write
64
- if (!_this.pendingWrite) {
65
- _this.pendingWrite = true;
66
- queueMicrotask(function () {
67
- try {
68
- _this.storageClient.setItemWithExpiry(SMART_CARD_CACHE_KEY, JSON.stringify(_this.memoryCache));
69
- } catch (_) {
70
- // Ignore storage write errors (e.g. quota exceeded) to prevent blocking future writes
71
- // Cache will still function in-memory for the session, but won't persist
72
- } finally {
73
- _this.pendingWrite = false;
74
- }
75
- });
85
+ // Write through to storage asynchronously (non-blocking)
86
+ // Debounced to batch multiple rapid calls into a single write
87
+ if (!_this.pendingWrite) {
88
+ _this.pendingWrite = true;
89
+ queueMicrotask(function () {
90
+ try {
91
+ _this.storageClient.setItemWithExpiry(SMART_CARD_CACHE_KEY, JSON.stringify(_this.memoryCache));
92
+ } catch (_) {
93
+ // Ignore storage write errors (e.g. quota exceeded) to prevent blocking future writes
94
+ // Cache will still function in-memory for the session, but won't persist
95
+ } finally {
96
+ _this.pendingWrite = false;
97
+ }
98
+ });
99
+ }
76
100
  }
77
101
  });
78
102
  /**
79
- * Retrieves the cached SmartLinkResponse for the provided url from storage (if it exists)
103
+ * Retrieves the cached SmartLinkResponse for the provided url (if it exists)
80
104
  * @param url The url (key) to retrieve the cached response for
81
105
  * @returns The cached SmartLinkResponse if it exists, else undefined
82
106
  */
83
107
  (0, _defineProperty2.default)(this, "getItem", function (url) {
84
- var _this$memoryCache;
85
108
  if (!url) {
86
109
  return;
87
110
  }
88
- var response = (_this$memoryCache = _this.memoryCache) === null || _this$memoryCache === void 0 || (_this$memoryCache = _this$memoryCache[url]) === null || _this$memoryCache === void 0 ? void 0 : _this$memoryCache.data;
89
- return response;
111
+ if ((0, _fg.fg)('platform_smartlink_document_cache')) {
112
+ var _this$documentCache$u;
113
+ return (_this$documentCache$u = _this.documentCache[url]) === null || _this$documentCache$u === void 0 ? void 0 : _this$documentCache$u.data;
114
+ } else {
115
+ var _this$memoryCache;
116
+ var response = (_this$memoryCache = _this.memoryCache) === null || _this$memoryCache === void 0 || (_this$memoryCache = _this$memoryCache[url]) === null || _this$memoryCache === void 0 ? void 0 : _this$memoryCache.data;
117
+ return response;
118
+ }
90
119
  });
91
120
  /**
92
- * Checks if a cached entry exists for the provided url in storage
121
+ * Checks if a cached entry exists for the provided url
93
122
  * @param url The url (key) to check for existence in the cache
94
123
  * @returns True if a cached entry exists, else false
95
124
  */
96
125
  (0, _defineProperty2.default)(this, "isUrlInCache", function (url) {
97
- return url in _this.memoryCache;
126
+ if ((0, _fg.fg)('platform_smartlink_document_cache')) {
127
+ return url in _this.documentCache;
128
+ } else {
129
+ return url in _this.memoryCache;
130
+ }
98
131
  });
99
132
  this.maxItems = maxItems;
100
- // Load cache from storage into memory on instantiation
101
- var stored = this.storageClient.getItem(SMART_CARD_CACHE_KEY, {
102
- useExpiredItem: true
103
- });
104
- this.memoryCache = stored ? JSON.parse(stored) : {};
133
+ if ((0, _fg.fg)('platform_smartlink_document_cache')) {
134
+ this.memoryCache = {};
135
+ } else {
136
+ // Load cache from storage into memory on instantiation
137
+ var stored = this.storageClient.getItem(SMART_CARD_CACHE_KEY, {
138
+ useExpiredItem: true
139
+ });
140
+ this.memoryCache = stored ? JSON.parse(stored) : {};
141
+ }
105
142
  }
106
143
 
107
144
  /**
@@ -1,93 +1,128 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { StorageClient } from '@atlaskit/frontend-utilities/storage-client';
3
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
3
4
  const SMART_CARD_CACHE_CLIENT_KEY = 'smart-card-url-data';
4
5
  const SMART_CARD_CACHE_KEY = 'response-cache';
5
6
  const SMART_CARD_CACHE_DEFAULT_MAX_ITEMS = 100;
6
7
  /**
7
- * Singleton cache client for smart link responses. Uses sessionStorage for per-tab isolation (no cross-tab conflicts).
8
- * If switching to localStorage for cross-tab sharing, add a 'storage' event listener in the constructor to sync
9
- * memoryCache when other tabs modify the cache, preventing race conditions from concurrent writes.
8
+ * Singleton cache client for smart link responses shared within the current document.
9
+ * Session storage remains available only for the document-cache gate's control cohort.
10
10
  */
11
11
  export class SmartCardLocalCacheClient {
12
12
  constructor(maxItems = SMART_CARD_CACHE_DEFAULT_MAX_ITEMS) {
13
13
  _defineProperty(this, "storageClient", new StorageClient(SMART_CARD_CACHE_CLIENT_KEY, {
14
14
  storageEngine: 'sessionStorage'
15
15
  }));
16
+ _defineProperty(this, "documentCache", {});
16
17
  _defineProperty(this, "pendingWrite", false);
17
18
  /**
18
19
  * Retrieves the entire cache object from memory
19
20
  * @returns The entire cache object
20
21
  */
21
22
  _defineProperty(this, "getCache", () => {
22
- return this.memoryCache;
23
+ if (fg('platform_smartlink_document_cache')) {
24
+ // Keep restored session data out of this cache if the gate changes after initialization.
25
+ return this.documentCache;
26
+ } else {
27
+ return this.memoryCache;
28
+ }
23
29
  });
24
30
  /**
25
- * Caches the SmartLinkResponse against the provided url in storage
31
+ * Caches the SmartLinkResponse against the provided url
26
32
  * @param url The url (key) to store the response against
27
- * @param response The SmartLinkResponse to be cached in storage
33
+ * @param response The SmartLinkResponse to be cached
28
34
  */
29
35
  _defineProperty(this, "setItem", (url, response) => {
30
- // Add or update the item in the cache with current timestamp
31
- this.memoryCache[url] = {
32
- data: response,
33
- timestamp: Date.now()
34
- };
36
+ if (fg('platform_smartlink_document_cache')) {
37
+ this.documentCache[url] = {
38
+ data: response,
39
+ timestamp: Date.now()
40
+ };
41
+ const cacheKeys = Object.keys(this.documentCache);
42
+ if (cacheKeys.length > this.maxItems) {
43
+ const sortedKeys = cacheKeys.sort((a, b) => this.documentCache[a].timestamp - this.documentCache[b].timestamp);
44
+ const itemsToRemove = cacheKeys.length - this.maxItems;
45
+ const keysToRemove = sortedKeys.slice(0, itemsToRemove);
46
+ keysToRemove.forEach(key => {
47
+ delete this.documentCache[key];
48
+ });
49
+ }
50
+ } else {
51
+ // Add or update the item in the cache with current timestamp
52
+ this.memoryCache[url] = {
53
+ data: response,
54
+ timestamp: Date.now()
55
+ };
35
56
 
36
- // Apply FIFO behavior if cache exceeds maxItems
37
- const cacheKeys = Object.keys(this.memoryCache);
38
- if (cacheKeys.length > this.maxItems) {
39
- // Sort keys by timestamp (oldest first) and remove the oldest items
40
- const sortedKeys = cacheKeys.sort((a, b) => this.memoryCache[a].timestamp - this.memoryCache[b].timestamp);
41
- const itemsToRemove = cacheKeys.length - this.maxItems;
42
- const keysToRemove = sortedKeys.slice(0, itemsToRemove);
43
- keysToRemove.forEach(key => {
44
- delete this.memoryCache[key];
45
- });
46
- }
57
+ // Apply FIFO behavior if cache exceeds maxItems
58
+ const cacheKeys = Object.keys(this.memoryCache);
59
+ if (cacheKeys.length > this.maxItems) {
60
+ // Sort keys by timestamp (oldest first) and remove the oldest items
61
+ const sortedKeys = cacheKeys.sort((a, b) => this.memoryCache[a].timestamp - this.memoryCache[b].timestamp);
62
+ const itemsToRemove = cacheKeys.length - this.maxItems;
63
+ const keysToRemove = sortedKeys.slice(0, itemsToRemove);
64
+ keysToRemove.forEach(key => {
65
+ delete this.memoryCache[key];
66
+ });
67
+ }
47
68
 
48
- // Write through to storage asynchronously (non-blocking)
49
- // Debounced to batch multiple rapid calls into a single write
50
- if (!this.pendingWrite) {
51
- this.pendingWrite = true;
52
- queueMicrotask(() => {
53
- try {
54
- this.storageClient.setItemWithExpiry(SMART_CARD_CACHE_KEY, JSON.stringify(this.memoryCache));
55
- } catch (_) {
56
- // Ignore storage write errors (e.g. quota exceeded) to prevent blocking future writes
57
- // Cache will still function in-memory for the session, but won't persist
58
- } finally {
59
- this.pendingWrite = false;
60
- }
61
- });
69
+ // Write through to storage asynchronously (non-blocking)
70
+ // Debounced to batch multiple rapid calls into a single write
71
+ if (!this.pendingWrite) {
72
+ this.pendingWrite = true;
73
+ queueMicrotask(() => {
74
+ try {
75
+ this.storageClient.setItemWithExpiry(SMART_CARD_CACHE_KEY, JSON.stringify(this.memoryCache));
76
+ } catch (_) {
77
+ // Ignore storage write errors (e.g. quota exceeded) to prevent blocking future writes
78
+ // Cache will still function in-memory for the session, but won't persist
79
+ } finally {
80
+ this.pendingWrite = false;
81
+ }
82
+ });
83
+ }
62
84
  }
63
85
  });
64
86
  /**
65
- * Retrieves the cached SmartLinkResponse for the provided url from storage (if it exists)
87
+ * Retrieves the cached SmartLinkResponse for the provided url (if it exists)
66
88
  * @param url The url (key) to retrieve the cached response for
67
89
  * @returns The cached SmartLinkResponse if it exists, else undefined
68
90
  */
69
91
  _defineProperty(this, "getItem", url => {
70
- var _this$memoryCache, _this$memoryCache$url;
71
92
  if (!url) {
72
93
  return;
73
94
  }
74
- const response = (_this$memoryCache = this.memoryCache) === null || _this$memoryCache === void 0 ? void 0 : (_this$memoryCache$url = _this$memoryCache[url]) === null || _this$memoryCache$url === void 0 ? void 0 : _this$memoryCache$url.data;
75
- return response;
95
+ if (fg('platform_smartlink_document_cache')) {
96
+ var _this$documentCache$u;
97
+ return (_this$documentCache$u = this.documentCache[url]) === null || _this$documentCache$u === void 0 ? void 0 : _this$documentCache$u.data;
98
+ } else {
99
+ var _this$memoryCache, _this$memoryCache$url;
100
+ const response = (_this$memoryCache = this.memoryCache) === null || _this$memoryCache === void 0 ? void 0 : (_this$memoryCache$url = _this$memoryCache[url]) === null || _this$memoryCache$url === void 0 ? void 0 : _this$memoryCache$url.data;
101
+ return response;
102
+ }
76
103
  });
77
104
  /**
78
- * Checks if a cached entry exists for the provided url in storage
105
+ * Checks if a cached entry exists for the provided url
79
106
  * @param url The url (key) to check for existence in the cache
80
107
  * @returns True if a cached entry exists, else false
81
108
  */
82
109
  _defineProperty(this, "isUrlInCache", url => {
83
- return url in this.memoryCache;
110
+ if (fg('platform_smartlink_document_cache')) {
111
+ return url in this.documentCache;
112
+ } else {
113
+ return url in this.memoryCache;
114
+ }
84
115
  });
85
116
  this.maxItems = maxItems;
86
- // Load cache from storage into memory on instantiation
87
- const stored = this.storageClient.getItem(SMART_CARD_CACHE_KEY, {
88
- useExpiredItem: true
89
- });
90
- this.memoryCache = stored ? JSON.parse(stored) : {};
117
+ if (fg('platform_smartlink_document_cache')) {
118
+ this.memoryCache = {};
119
+ } else {
120
+ // Load cache from storage into memory on instantiation
121
+ const stored = this.storageClient.getItem(SMART_CARD_CACHE_KEY, {
122
+ useExpiredItem: true
123
+ });
124
+ this.memoryCache = stored ? JSON.parse(stored) : {};
125
+ }
91
126
  }
92
127
 
93
128
  /**
@@ -2,13 +2,13 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  import { StorageClient } from '@atlaskit/frontend-utilities/storage-client';
5
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
5
6
  var SMART_CARD_CACHE_CLIENT_KEY = 'smart-card-url-data';
6
7
  var SMART_CARD_CACHE_KEY = 'response-cache';
7
8
  var SMART_CARD_CACHE_DEFAULT_MAX_ITEMS = 100;
8
9
  /**
9
- * Singleton cache client for smart link responses. Uses sessionStorage for per-tab isolation (no cross-tab conflicts).
10
- * If switching to localStorage for cross-tab sharing, add a 'storage' event listener in the constructor to sync
11
- * memoryCache when other tabs modify the cache, preventing race conditions from concurrent writes.
10
+ * Singleton cache client for smart link responses shared within the current document.
11
+ * Session storage remains available only for the document-cache gate's control cohort.
12
12
  */
13
13
  export var SmartCardLocalCacheClient = /*#__PURE__*/function () {
14
14
  function SmartCardLocalCacheClient() {
@@ -18,83 +18,120 @@ export var SmartCardLocalCacheClient = /*#__PURE__*/function () {
18
18
  _defineProperty(this, "storageClient", new StorageClient(SMART_CARD_CACHE_CLIENT_KEY, {
19
19
  storageEngine: 'sessionStorage'
20
20
  }));
21
+ _defineProperty(this, "documentCache", {});
21
22
  _defineProperty(this, "pendingWrite", false);
22
23
  /**
23
24
  * Retrieves the entire cache object from memory
24
25
  * @returns The entire cache object
25
26
  */
26
27
  _defineProperty(this, "getCache", function () {
27
- return _this.memoryCache;
28
+ if (fg('platform_smartlink_document_cache')) {
29
+ // Keep restored session data out of this cache if the gate changes after initialization.
30
+ return _this.documentCache;
31
+ } else {
32
+ return _this.memoryCache;
33
+ }
28
34
  });
29
35
  /**
30
- * Caches the SmartLinkResponse against the provided url in storage
36
+ * Caches the SmartLinkResponse against the provided url
31
37
  * @param url The url (key) to store the response against
32
- * @param response The SmartLinkResponse to be cached in storage
38
+ * @param response The SmartLinkResponse to be cached
33
39
  */
34
40
  _defineProperty(this, "setItem", function (url, response) {
35
- // Add or update the item in the cache with current timestamp
36
- _this.memoryCache[url] = {
37
- data: response,
38
- timestamp: Date.now()
39
- };
41
+ if (fg('platform_smartlink_document_cache')) {
42
+ _this.documentCache[url] = {
43
+ data: response,
44
+ timestamp: Date.now()
45
+ };
46
+ var cacheKeys = Object.keys(_this.documentCache);
47
+ if (cacheKeys.length > _this.maxItems) {
48
+ var sortedKeys = cacheKeys.sort(function (a, b) {
49
+ return _this.documentCache[a].timestamp - _this.documentCache[b].timestamp;
50
+ });
51
+ var itemsToRemove = cacheKeys.length - _this.maxItems;
52
+ var keysToRemove = sortedKeys.slice(0, itemsToRemove);
53
+ keysToRemove.forEach(function (key) {
54
+ delete _this.documentCache[key];
55
+ });
56
+ }
57
+ } else {
58
+ // Add or update the item in the cache with current timestamp
59
+ _this.memoryCache[url] = {
60
+ data: response,
61
+ timestamp: Date.now()
62
+ };
40
63
 
41
- // Apply FIFO behavior if cache exceeds maxItems
42
- var cacheKeys = Object.keys(_this.memoryCache);
43
- if (cacheKeys.length > _this.maxItems) {
44
- // Sort keys by timestamp (oldest first) and remove the oldest items
45
- var sortedKeys = cacheKeys.sort(function (a, b) {
46
- return _this.memoryCache[a].timestamp - _this.memoryCache[b].timestamp;
47
- });
48
- var itemsToRemove = cacheKeys.length - _this.maxItems;
49
- var keysToRemove = sortedKeys.slice(0, itemsToRemove);
50
- keysToRemove.forEach(function (key) {
51
- delete _this.memoryCache[key];
52
- });
53
- }
64
+ // Apply FIFO behavior if cache exceeds maxItems
65
+ var _cacheKeys = Object.keys(_this.memoryCache);
66
+ if (_cacheKeys.length > _this.maxItems) {
67
+ // Sort keys by timestamp (oldest first) and remove the oldest items
68
+ var _sortedKeys = _cacheKeys.sort(function (a, b) {
69
+ return _this.memoryCache[a].timestamp - _this.memoryCache[b].timestamp;
70
+ });
71
+ var _itemsToRemove = _cacheKeys.length - _this.maxItems;
72
+ var _keysToRemove = _sortedKeys.slice(0, _itemsToRemove);
73
+ _keysToRemove.forEach(function (key) {
74
+ delete _this.memoryCache[key];
75
+ });
76
+ }
54
77
 
55
- // Write through to storage asynchronously (non-blocking)
56
- // Debounced to batch multiple rapid calls into a single write
57
- if (!_this.pendingWrite) {
58
- _this.pendingWrite = true;
59
- queueMicrotask(function () {
60
- try {
61
- _this.storageClient.setItemWithExpiry(SMART_CARD_CACHE_KEY, JSON.stringify(_this.memoryCache));
62
- } catch (_) {
63
- // Ignore storage write errors (e.g. quota exceeded) to prevent blocking future writes
64
- // Cache will still function in-memory for the session, but won't persist
65
- } finally {
66
- _this.pendingWrite = false;
67
- }
68
- });
78
+ // Write through to storage asynchronously (non-blocking)
79
+ // Debounced to batch multiple rapid calls into a single write
80
+ if (!_this.pendingWrite) {
81
+ _this.pendingWrite = true;
82
+ queueMicrotask(function () {
83
+ try {
84
+ _this.storageClient.setItemWithExpiry(SMART_CARD_CACHE_KEY, JSON.stringify(_this.memoryCache));
85
+ } catch (_) {
86
+ // Ignore storage write errors (e.g. quota exceeded) to prevent blocking future writes
87
+ // Cache will still function in-memory for the session, but won't persist
88
+ } finally {
89
+ _this.pendingWrite = false;
90
+ }
91
+ });
92
+ }
69
93
  }
70
94
  });
71
95
  /**
72
- * Retrieves the cached SmartLinkResponse for the provided url from storage (if it exists)
96
+ * Retrieves the cached SmartLinkResponse for the provided url (if it exists)
73
97
  * @param url The url (key) to retrieve the cached response for
74
98
  * @returns The cached SmartLinkResponse if it exists, else undefined
75
99
  */
76
100
  _defineProperty(this, "getItem", function (url) {
77
- var _this$memoryCache;
78
101
  if (!url) {
79
102
  return;
80
103
  }
81
- var response = (_this$memoryCache = _this.memoryCache) === null || _this$memoryCache === void 0 || (_this$memoryCache = _this$memoryCache[url]) === null || _this$memoryCache === void 0 ? void 0 : _this$memoryCache.data;
82
- return response;
104
+ if (fg('platform_smartlink_document_cache')) {
105
+ var _this$documentCache$u;
106
+ return (_this$documentCache$u = _this.documentCache[url]) === null || _this$documentCache$u === void 0 ? void 0 : _this$documentCache$u.data;
107
+ } else {
108
+ var _this$memoryCache;
109
+ var response = (_this$memoryCache = _this.memoryCache) === null || _this$memoryCache === void 0 || (_this$memoryCache = _this$memoryCache[url]) === null || _this$memoryCache === void 0 ? void 0 : _this$memoryCache.data;
110
+ return response;
111
+ }
83
112
  });
84
113
  /**
85
- * Checks if a cached entry exists for the provided url in storage
114
+ * Checks if a cached entry exists for the provided url
86
115
  * @param url The url (key) to check for existence in the cache
87
116
  * @returns True if a cached entry exists, else false
88
117
  */
89
118
  _defineProperty(this, "isUrlInCache", function (url) {
90
- return url in _this.memoryCache;
119
+ if (fg('platform_smartlink_document_cache')) {
120
+ return url in _this.documentCache;
121
+ } else {
122
+ return url in _this.memoryCache;
123
+ }
91
124
  });
92
125
  this.maxItems = maxItems;
93
- // Load cache from storage into memory on instantiation
94
- var stored = this.storageClient.getItem(SMART_CARD_CACHE_KEY, {
95
- useExpiredItem: true
96
- });
97
- this.memoryCache = stored ? JSON.parse(stored) : {};
126
+ if (fg('platform_smartlink_document_cache')) {
127
+ this.memoryCache = {};
128
+ } else {
129
+ // Load cache from storage into memory on instantiation
130
+ var stored = this.storageClient.getItem(SMART_CARD_CACHE_KEY, {
131
+ useExpiredItem: true
132
+ });
133
+ this.memoryCache = stored ? JSON.parse(stored) : {};
134
+ }
98
135
  }
99
136
 
100
137
  /**
@@ -4,15 +4,15 @@ type CacheEntry = {
4
4
  timestamp: number;
5
5
  };
6
6
  /**
7
- * Singleton cache client for smart link responses. Uses sessionStorage for per-tab isolation (no cross-tab conflicts).
8
- * If switching to localStorage for cross-tab sharing, add a 'storage' event listener in the constructor to sync
9
- * memoryCache when other tabs modify the cache, preventing race conditions from concurrent writes.
7
+ * Singleton cache client for smart link responses shared within the current document.
8
+ * Session storage remains available only for the document-cache gate's control cohort.
10
9
  */
11
10
  export declare class SmartCardLocalCacheClient {
12
11
  private static instance;
13
12
  private readonly storageClient;
14
13
  private maxItems;
15
14
  private memoryCache;
15
+ private documentCache;
16
16
  private pendingWrite;
17
17
  private constructor();
18
18
  /**
@@ -34,19 +34,19 @@ export declare class SmartCardLocalCacheClient {
34
34
  */
35
35
  getCache: () => Record<string, CacheEntry>;
36
36
  /**
37
- * Caches the SmartLinkResponse against the provided url in storage
37
+ * Caches the SmartLinkResponse against the provided url
38
38
  * @param url The url (key) to store the response against
39
- * @param response The SmartLinkResponse to be cached in storage
39
+ * @param response The SmartLinkResponse to be cached
40
40
  */
41
41
  setItem: (url: string, response: SmartLinkResponse) => void;
42
42
  /**
43
- * Retrieves the cached SmartLinkResponse for the provided url from storage (if it exists)
43
+ * Retrieves the cached SmartLinkResponse for the provided url (if it exists)
44
44
  * @param url The url (key) to retrieve the cached response for
45
45
  * @returns The cached SmartLinkResponse if it exists, else undefined
46
46
  */
47
47
  getItem: (url: string | undefined) => SmartLinkResponse | undefined;
48
48
  /**
49
- * Checks if a cached entry exists for the provided url in storage
49
+ * Checks if a cached entry exists for the provided url
50
50
  * @param url The url (key) to check for existence in the cache
51
51
  * @returns True if a cached entry exists, else false
52
52
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-card-provider",
3
- "version": "8.1.2",
3
+ "version": "8.1.4",
4
4
  "description": "Contains the EditorCardProvider, for determining smart card behaviour in the editor.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -32,7 +32,7 @@
32
32
  "@atlaskit/linking-types": "^16.0.0",
33
33
  "@atlaskit/node-data-provider": "^23.0.0",
34
34
  "@atlaskit/platform-feature-flags": "^2.2.0",
35
- "@atlaskit/tmp-editor-statsig": "^217.0.0",
35
+ "@atlaskit/tmp-editor-statsig": "^218.0.0",
36
36
  "@babel/runtime": "^7.0.0",
37
37
  "dataloader": "^2.1.0"
38
38
  },
@@ -45,6 +45,9 @@
45
45
  "react": "^19.2.0"
46
46
  },
47
47
  "platform-feature-flags": {
48
+ "platform_smartlink_document_cache": {
49
+ "type": "boolean"
50
+ },
48
51
  "tc_smart_link_embed_view": {
49
52
  "type": "boolean"
50
53
  },