@atlaskit/editor-card-provider 8.1.3 → 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,14 @@
|
|
|
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
|
+
|
|
3
12
|
## 8.1.3
|
|
4
13
|
|
|
5
14
|
### 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
|
|
17
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
45
|
+
* @param response The SmartLinkResponse to be cached
|
|
40
46
|
*/
|
|
41
47
|
(0, _defineProperty2.default)(this, "setItem", function (url, response) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
|
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
|
-
|
|
89
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
|
8
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
33
|
+
* @param response The SmartLinkResponse to be cached
|
|
28
34
|
*/
|
|
29
35
|
_defineProperty(this, "setItem", (url, response) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
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
|
-
|
|
75
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
|
10
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
38
|
+
* @param response The SmartLinkResponse to be cached
|
|
33
39
|
*/
|
|
34
40
|
_defineProperty(this, "setItem", function (url, response) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
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
|
-
|
|
82
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
8
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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",
|
|
@@ -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
|
},
|