@atlaskit/editor-plugin-local-id 5.0.0 → 5.0.2
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 +15 -0
- package/afm-cc/tsconfig.json +1 -1
- package/afm-jira/tsconfig.json +1 -1
- package/afm-products/tsconfig.json +1 -1
- package/dist/cjs/pm-plugins/generateShortUUID.js +35 -0
- package/dist/cjs/pm-plugins/main.js +22 -16
- package/dist/es2019/pm-plugins/generateShortUUID.js +30 -0
- package/dist/es2019/pm-plugins/main.js +22 -16
- package/dist/esm/pm-plugins/generateShortUUID.js +30 -0
- package/dist/esm/pm-plugins/main.js +22 -16
- package/dist/types/localIdPluginType.d.ts +3 -2
- package/dist/types/pm-plugins/generateShortUUID.d.ts +12 -0
- package/dist/types/pm-plugins/main.d.ts +1 -2
- package/dist/types-ts4.5/localIdPluginType.d.ts +4 -2
- package/dist/types-ts4.5/pm-plugins/generateShortUUID.d.ts +12 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -2
- package/package.json +3 -6
- package/build/tsconfig.json +0 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-local-id
|
|
2
2
|
|
|
3
|
+
## 5.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`0bae952cf6885`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0bae952cf6885) -
|
|
8
|
+
Cleanup feature gate which prevents initial localid loading on collab editors
|
|
9
|
+
|
|
10
|
+
## 5.0.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [`8d8cdcab50139`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8d8cdcab50139) -
|
|
15
|
+
Use shortened UUIDs to reduce document size.
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
|
|
3
18
|
## 5.0.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/afm-cc/tsconfig.json
CHANGED
package/afm-jira/tsconfig.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.generatedShortUUIDs = exports.generateShortUUID = void 0;
|
|
7
|
+
var _adfSchema = require("@atlaskit/adf-schema");
|
|
8
|
+
/**
|
|
9
|
+
* Global Set to track currently generated and existing short UUIDs in the document.
|
|
10
|
+
* Used to prevent duplicate short IDs when using crypto.randomUUID().
|
|
11
|
+
*/
|
|
12
|
+
var generatedShortUUIDs = exports.generatedShortUUIDs = new Set();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generates a short UUID and checks for duplicates against both
|
|
16
|
+
* generated UUIDs and existing UUIDs in the document.
|
|
17
|
+
* Retries up to 10 times if a duplicate is found.
|
|
18
|
+
* Falls back to full UUID if max retries exceeded.
|
|
19
|
+
*/
|
|
20
|
+
var generateShortUUID = exports.generateShortUUID = function generateShortUUID() {
|
|
21
|
+
var maxRetries = 10;
|
|
22
|
+
for (var attempt = 0; attempt < maxRetries; attempt++) {
|
|
23
|
+
try {
|
|
24
|
+
var shortUUID = crypto.randomUUID().split('-')[4];
|
|
25
|
+
if (!generatedShortUUIDs.has(shortUUID)) {
|
|
26
|
+
generatedShortUUIDs.add(shortUUID);
|
|
27
|
+
return shortUUID;
|
|
28
|
+
}
|
|
29
|
+
} catch (_unused) {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Fallback to full UUID if short UUID generation fails or max retries exceeded
|
|
34
|
+
return _adfSchema.uuid.generate();
|
|
35
|
+
};
|
|
@@ -14,15 +14,14 @@ var _utils = require("@atlaskit/editor-common/utils");
|
|
|
14
14
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
15
15
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
16
16
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
17
|
+
var _generateShortUUID = require("./generateShortUUID");
|
|
17
18
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
18
19
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
19
20
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
20
21
|
var localIdPluginKey = exports.localIdPluginKey = new _state.PluginKey('localIdPlugin');
|
|
21
|
-
var generateUUID = function generateUUID(
|
|
22
|
+
var generateUUID = function generateUUID() {
|
|
22
23
|
if ((0, _platformFeatureFlags.fg)('platform_editor_ai_local_id_short')) {
|
|
23
|
-
|
|
24
|
-
// Use the same technique as the anchor id which is faster and shorter
|
|
25
|
-
return (_api$core$actions$get = api === null || api === void 0 || (_api$core$actions$get2 = api.core.actions.getAnchorIdForNode(node, pos)) === null || _api$core$actions$get2 === void 0 ? void 0 : _api$core$actions$get2.replace('--anchor-', '')) !== null && _api$core$actions$get !== void 0 ? _api$core$actions$get : _adfSchema.uuid.generate();
|
|
24
|
+
return (0, _generateShortUUID.generateShortUUID)();
|
|
26
25
|
}
|
|
27
26
|
// When the flag is NOT enabled, existing uuid
|
|
28
27
|
return _adfSchema.uuid.generate();
|
|
@@ -38,6 +37,8 @@ var requestIdleCallbackWithFallback = function requestIdleCallbackWithFallback(c
|
|
|
38
37
|
}
|
|
39
38
|
};
|
|
40
39
|
var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
40
|
+
// Track if we've initialized existing UUIDs for this plugin instance
|
|
41
|
+
var hasInitializedExistingUUIDs = false;
|
|
41
42
|
return new _safePlugin.SafePlugin({
|
|
42
43
|
key: localIdPluginKey,
|
|
43
44
|
view: function view(editorView) {
|
|
@@ -46,9 +47,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
46
47
|
* to nodes that don't have them. It's designed to run only once per
|
|
47
48
|
* editor instance to avoid performance issues.
|
|
48
49
|
*/
|
|
49
|
-
|
|
50
|
-
// we will add the plugin as a dependency
|
|
51
|
-
if (api !== null && api !== void 0 && api.collabEdit && (0, _platformFeatureFlags.fg)('platform_editor_ai_aifc_avoid_initial_localId')) {
|
|
50
|
+
if (api !== null && api !== void 0 && api.collabEdit) {
|
|
52
51
|
return {
|
|
53
52
|
update: function update() {}
|
|
54
53
|
};
|
|
@@ -69,10 +68,10 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
69
68
|
var _node$type$spec$attrs;
|
|
70
69
|
if (!ignoredNodeTypes.includes(node.type.name) && !node.attrs.localId && !!((_node$type$spec$attrs = node.type.spec.attrs) !== null && _node$type$spec$attrs !== void 0 && _node$type$spec$attrs.localId)) {
|
|
71
70
|
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
72
|
-
nodesToUpdate.set(pos, generateUUID(
|
|
71
|
+
nodesToUpdate.set(pos, generateUUID());
|
|
73
72
|
} else {
|
|
74
73
|
localIdWasAdded = true;
|
|
75
|
-
addLocalIdToNode(
|
|
74
|
+
addLocalIdToNode(pos, tr);
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
77
|
return true; // Continue traversing
|
|
@@ -152,10 +151,10 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
152
151
|
} else {
|
|
153
152
|
if (!(node !== null && node !== void 0 && node.attrs.localId)) {
|
|
154
153
|
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
155
|
-
nodesToUpdate.set(pos, generateUUID(
|
|
154
|
+
nodesToUpdate.set(pos, generateUUID());
|
|
156
155
|
} else {
|
|
157
156
|
// Legacy behavior - individual steps
|
|
158
|
-
addLocalIdToNode(
|
|
157
|
+
addLocalIdToNode(pos, tr);
|
|
159
158
|
}
|
|
160
159
|
}
|
|
161
160
|
}
|
|
@@ -166,12 +165,20 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
166
165
|
});
|
|
167
166
|
if (addedNodes.size > 0 && (0, _platformFeatureFlags.fg)('platform_editor_use_localid_dedupe')) {
|
|
168
167
|
newState.doc.descendants(function (node) {
|
|
168
|
+
// Also track existing UUIDs in the global Set for short UUID collision detection
|
|
169
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_ai_local_id_short')) {
|
|
170
|
+
var _node$attrs;
|
|
171
|
+
if ((_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.localId && !hasInitializedExistingUUIDs) {
|
|
172
|
+
_generateShortUUID.generatedShortUUIDs.add(node.attrs.localId);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
169
175
|
if (addedNodes.has(node)) {
|
|
170
176
|
return true;
|
|
171
177
|
}
|
|
172
178
|
localIds.add(node.attrs.localId);
|
|
173
179
|
return true;
|
|
174
180
|
});
|
|
181
|
+
hasInitializedExistingUUIDs = true;
|
|
175
182
|
// Also ensure the added have no duplicates
|
|
176
183
|
var seenIds = new Set();
|
|
177
184
|
var _iterator = _createForOfIteratorHelper(addedNodes),
|
|
@@ -183,11 +190,11 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
183
190
|
var pos = addedNodePos.get(node);
|
|
184
191
|
if (pos !== undefined) {
|
|
185
192
|
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
186
|
-
var newId = generateUUID(
|
|
193
|
+
var newId = generateUUID();
|
|
187
194
|
nodesToUpdate.set(pos, newId);
|
|
188
195
|
seenIds.add(newId);
|
|
189
196
|
} else {
|
|
190
|
-
addLocalIdToNode(
|
|
197
|
+
addLocalIdToNode(pos, tr);
|
|
191
198
|
}
|
|
192
199
|
modified = true;
|
|
193
200
|
}
|
|
@@ -221,9 +228,8 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
221
228
|
* @param tr - The transaction to apply the change to
|
|
222
229
|
* @param node - Node reference for integer ID generator
|
|
223
230
|
*/
|
|
224
|
-
var addLocalIdToNode = exports.addLocalIdToNode = function addLocalIdToNode(
|
|
225
|
-
|
|
226
|
-
tr.setNodeAttribute(pos, 'localId', generateUUID(api, targetNode, pos));
|
|
231
|
+
var addLocalIdToNode = exports.addLocalIdToNode = function addLocalIdToNode(pos, tr) {
|
|
232
|
+
tr.setNodeAttribute(pos, 'localId', generateUUID());
|
|
227
233
|
tr.setMeta('addToHistory', false);
|
|
228
234
|
};
|
|
229
235
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { uuid } from '@atlaskit/adf-schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Global Set to track currently generated and existing short UUIDs in the document.
|
|
5
|
+
* Used to prevent duplicate short IDs when using crypto.randomUUID().
|
|
6
|
+
*/
|
|
7
|
+
export const generatedShortUUIDs = new Set();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generates a short UUID and checks for duplicates against both
|
|
11
|
+
* generated UUIDs and existing UUIDs in the document.
|
|
12
|
+
* Retries up to 10 times if a duplicate is found.
|
|
13
|
+
* Falls back to full UUID if max retries exceeded.
|
|
14
|
+
*/
|
|
15
|
+
export const generateShortUUID = () => {
|
|
16
|
+
const maxRetries = 10;
|
|
17
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
18
|
+
try {
|
|
19
|
+
const shortUUID = crypto.randomUUID().split('-')[4];
|
|
20
|
+
if (!generatedShortUUIDs.has(shortUUID)) {
|
|
21
|
+
generatedShortUUIDs.add(shortUUID);
|
|
22
|
+
return shortUUID;
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Fallback to full UUID if short UUID generation fails or max retries exceeded
|
|
29
|
+
return uuid.generate();
|
|
30
|
+
};
|
|
@@ -6,12 +6,11 @@ import { stepHasSlice } from '@atlaskit/editor-common/utils';
|
|
|
6
6
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
7
7
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
8
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
|
+
import { generateShortUUID, generatedShortUUIDs } from './generateShortUUID';
|
|
9
10
|
export const localIdPluginKey = new PluginKey('localIdPlugin');
|
|
10
|
-
const generateUUID = (
|
|
11
|
+
const generateUUID = () => {
|
|
11
12
|
if (fg('platform_editor_ai_local_id_short')) {
|
|
12
|
-
|
|
13
|
-
// Use the same technique as the anchor id which is faster and shorter
|
|
14
|
-
return (_api$core$actions$get = api === null || api === void 0 ? void 0 : (_api$core$actions$get2 = api.core.actions.getAnchorIdForNode(node, pos)) === null || _api$core$actions$get2 === void 0 ? void 0 : _api$core$actions$get2.replace('--anchor-', '')) !== null && _api$core$actions$get !== void 0 ? _api$core$actions$get : uuid.generate();
|
|
13
|
+
return generateShortUUID();
|
|
15
14
|
}
|
|
16
15
|
// When the flag is NOT enabled, existing uuid
|
|
17
16
|
return uuid.generate();
|
|
@@ -27,6 +26,8 @@ const requestIdleCallbackWithFallback = callback => {
|
|
|
27
26
|
}
|
|
28
27
|
};
|
|
29
28
|
export const createPlugin = api => {
|
|
29
|
+
// Track if we've initialized existing UUIDs for this plugin instance
|
|
30
|
+
let hasInitializedExistingUUIDs = false;
|
|
30
31
|
return new SafePlugin({
|
|
31
32
|
key: localIdPluginKey,
|
|
32
33
|
view: editorView => {
|
|
@@ -35,9 +36,7 @@ export const createPlugin = api => {
|
|
|
35
36
|
* to nodes that don't have them. It's designed to run only once per
|
|
36
37
|
* editor instance to avoid performance issues.
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
|
-
// we will add the plugin as a dependency
|
|
40
|
-
if (api !== null && api !== void 0 && api.collabEdit && fg('platform_editor_ai_aifc_avoid_initial_localId')) {
|
|
39
|
+
if (api !== null && api !== void 0 && api.collabEdit) {
|
|
41
40
|
return {
|
|
42
41
|
update: () => {}
|
|
43
42
|
};
|
|
@@ -59,10 +58,10 @@ export const createPlugin = api => {
|
|
|
59
58
|
var _node$type$spec$attrs;
|
|
60
59
|
if (!ignoredNodeTypes.includes(node.type.name) && !node.attrs.localId && !!((_node$type$spec$attrs = node.type.spec.attrs) !== null && _node$type$spec$attrs !== void 0 && _node$type$spec$attrs.localId)) {
|
|
61
60
|
if (fg('platform_editor_localid_improvements')) {
|
|
62
|
-
nodesToUpdate.set(pos, generateUUID(
|
|
61
|
+
nodesToUpdate.set(pos, generateUUID());
|
|
63
62
|
} else {
|
|
64
63
|
localIdWasAdded = true;
|
|
65
|
-
addLocalIdToNode(
|
|
64
|
+
addLocalIdToNode(pos, tr);
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
return true; // Continue traversing
|
|
@@ -143,10 +142,10 @@ export const createPlugin = api => {
|
|
|
143
142
|
} else {
|
|
144
143
|
if (!(node !== null && node !== void 0 && node.attrs.localId)) {
|
|
145
144
|
if (fg('platform_editor_localid_improvements')) {
|
|
146
|
-
nodesToUpdate.set(pos, generateUUID(
|
|
145
|
+
nodesToUpdate.set(pos, generateUUID());
|
|
147
146
|
} else {
|
|
148
147
|
// Legacy behavior - individual steps
|
|
149
|
-
addLocalIdToNode(
|
|
148
|
+
addLocalIdToNode(pos, tr);
|
|
150
149
|
}
|
|
151
150
|
}
|
|
152
151
|
}
|
|
@@ -157,12 +156,20 @@ export const createPlugin = api => {
|
|
|
157
156
|
});
|
|
158
157
|
if (addedNodes.size > 0 && fg('platform_editor_use_localid_dedupe')) {
|
|
159
158
|
newState.doc.descendants(node => {
|
|
159
|
+
// Also track existing UUIDs in the global Set for short UUID collision detection
|
|
160
|
+
if (fg('platform_editor_ai_local_id_short')) {
|
|
161
|
+
var _node$attrs;
|
|
162
|
+
if ((_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.localId && !hasInitializedExistingUUIDs) {
|
|
163
|
+
generatedShortUUIDs.add(node.attrs.localId);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
160
166
|
if (addedNodes.has(node)) {
|
|
161
167
|
return true;
|
|
162
168
|
}
|
|
163
169
|
localIds.add(node.attrs.localId);
|
|
164
170
|
return true;
|
|
165
171
|
});
|
|
172
|
+
hasInitializedExistingUUIDs = true;
|
|
166
173
|
// Also ensure the added have no duplicates
|
|
167
174
|
const seenIds = new Set();
|
|
168
175
|
for (const node of addedNodes) {
|
|
@@ -170,11 +177,11 @@ export const createPlugin = api => {
|
|
|
170
177
|
const pos = addedNodePos.get(node);
|
|
171
178
|
if (pos !== undefined) {
|
|
172
179
|
if (fg('platform_editor_localid_improvements')) {
|
|
173
|
-
const newId = generateUUID(
|
|
180
|
+
const newId = generateUUID();
|
|
174
181
|
nodesToUpdate.set(pos, newId);
|
|
175
182
|
seenIds.add(newId);
|
|
176
183
|
} else {
|
|
177
|
-
addLocalIdToNode(
|
|
184
|
+
addLocalIdToNode(pos, tr);
|
|
178
185
|
}
|
|
179
186
|
modified = true;
|
|
180
187
|
}
|
|
@@ -203,9 +210,8 @@ export const createPlugin = api => {
|
|
|
203
210
|
* @param tr - The transaction to apply the change to
|
|
204
211
|
* @param node - Node reference for integer ID generator
|
|
205
212
|
*/
|
|
206
|
-
export const addLocalIdToNode = (
|
|
207
|
-
|
|
208
|
-
tr.setNodeAttribute(pos, 'localId', generateUUID(api, targetNode, pos));
|
|
213
|
+
export const addLocalIdToNode = (pos, tr) => {
|
|
214
|
+
tr.setNodeAttribute(pos, 'localId', generateUUID());
|
|
209
215
|
tr.setMeta('addToHistory', false);
|
|
210
216
|
};
|
|
211
217
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { uuid } from '@atlaskit/adf-schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Global Set to track currently generated and existing short UUIDs in the document.
|
|
5
|
+
* Used to prevent duplicate short IDs when using crypto.randomUUID().
|
|
6
|
+
*/
|
|
7
|
+
export var generatedShortUUIDs = new Set();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generates a short UUID and checks for duplicates against both
|
|
11
|
+
* generated UUIDs and existing UUIDs in the document.
|
|
12
|
+
* Retries up to 10 times if a duplicate is found.
|
|
13
|
+
* Falls back to full UUID if max retries exceeded.
|
|
14
|
+
*/
|
|
15
|
+
export var generateShortUUID = function generateShortUUID() {
|
|
16
|
+
var maxRetries = 10;
|
|
17
|
+
for (var attempt = 0; attempt < maxRetries; attempt++) {
|
|
18
|
+
try {
|
|
19
|
+
var shortUUID = crypto.randomUUID().split('-')[4];
|
|
20
|
+
if (!generatedShortUUIDs.has(shortUUID)) {
|
|
21
|
+
generatedShortUUIDs.add(shortUUID);
|
|
22
|
+
return shortUUID;
|
|
23
|
+
}
|
|
24
|
+
} catch (_unused) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Fallback to full UUID if short UUID generation fails or max retries exceeded
|
|
29
|
+
return uuid.generate();
|
|
30
|
+
};
|
|
@@ -10,12 +10,11 @@ import { stepHasSlice } from '@atlaskit/editor-common/utils';
|
|
|
10
10
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
11
11
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
12
12
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
|
+
import { generateShortUUID, generatedShortUUIDs } from './generateShortUUID';
|
|
13
14
|
export var localIdPluginKey = new PluginKey('localIdPlugin');
|
|
14
|
-
var generateUUID = function generateUUID(
|
|
15
|
+
var generateUUID = function generateUUID() {
|
|
15
16
|
if (fg('platform_editor_ai_local_id_short')) {
|
|
16
|
-
|
|
17
|
-
// Use the same technique as the anchor id which is faster and shorter
|
|
18
|
-
return (_api$core$actions$get = api === null || api === void 0 || (_api$core$actions$get2 = api.core.actions.getAnchorIdForNode(node, pos)) === null || _api$core$actions$get2 === void 0 ? void 0 : _api$core$actions$get2.replace('--anchor-', '')) !== null && _api$core$actions$get !== void 0 ? _api$core$actions$get : uuid.generate();
|
|
17
|
+
return generateShortUUID();
|
|
19
18
|
}
|
|
20
19
|
// When the flag is NOT enabled, existing uuid
|
|
21
20
|
return uuid.generate();
|
|
@@ -31,6 +30,8 @@ var requestIdleCallbackWithFallback = function requestIdleCallbackWithFallback(c
|
|
|
31
30
|
}
|
|
32
31
|
};
|
|
33
32
|
export var createPlugin = function createPlugin(api) {
|
|
33
|
+
// Track if we've initialized existing UUIDs for this plugin instance
|
|
34
|
+
var hasInitializedExistingUUIDs = false;
|
|
34
35
|
return new SafePlugin({
|
|
35
36
|
key: localIdPluginKey,
|
|
36
37
|
view: function view(editorView) {
|
|
@@ -39,9 +40,7 @@ export var createPlugin = function createPlugin(api) {
|
|
|
39
40
|
* to nodes that don't have them. It's designed to run only once per
|
|
40
41
|
* editor instance to avoid performance issues.
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
-
// we will add the plugin as a dependency
|
|
44
|
-
if (api !== null && api !== void 0 && api.collabEdit && fg('platform_editor_ai_aifc_avoid_initial_localId')) {
|
|
43
|
+
if (api !== null && api !== void 0 && api.collabEdit) {
|
|
45
44
|
return {
|
|
46
45
|
update: function update() {}
|
|
47
46
|
};
|
|
@@ -62,10 +61,10 @@ export var createPlugin = function createPlugin(api) {
|
|
|
62
61
|
var _node$type$spec$attrs;
|
|
63
62
|
if (!ignoredNodeTypes.includes(node.type.name) && !node.attrs.localId && !!((_node$type$spec$attrs = node.type.spec.attrs) !== null && _node$type$spec$attrs !== void 0 && _node$type$spec$attrs.localId)) {
|
|
64
63
|
if (fg('platform_editor_localid_improvements')) {
|
|
65
|
-
nodesToUpdate.set(pos, generateUUID(
|
|
64
|
+
nodesToUpdate.set(pos, generateUUID());
|
|
66
65
|
} else {
|
|
67
66
|
localIdWasAdded = true;
|
|
68
|
-
addLocalIdToNode(
|
|
67
|
+
addLocalIdToNode(pos, tr);
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
return true; // Continue traversing
|
|
@@ -145,10 +144,10 @@ export var createPlugin = function createPlugin(api) {
|
|
|
145
144
|
} else {
|
|
146
145
|
if (!(node !== null && node !== void 0 && node.attrs.localId)) {
|
|
147
146
|
if (fg('platform_editor_localid_improvements')) {
|
|
148
|
-
nodesToUpdate.set(pos, generateUUID(
|
|
147
|
+
nodesToUpdate.set(pos, generateUUID());
|
|
149
148
|
} else {
|
|
150
149
|
// Legacy behavior - individual steps
|
|
151
|
-
addLocalIdToNode(
|
|
150
|
+
addLocalIdToNode(pos, tr);
|
|
152
151
|
}
|
|
153
152
|
}
|
|
154
153
|
}
|
|
@@ -159,12 +158,20 @@ export var createPlugin = function createPlugin(api) {
|
|
|
159
158
|
});
|
|
160
159
|
if (addedNodes.size > 0 && fg('platform_editor_use_localid_dedupe')) {
|
|
161
160
|
newState.doc.descendants(function (node) {
|
|
161
|
+
// Also track existing UUIDs in the global Set for short UUID collision detection
|
|
162
|
+
if (fg('platform_editor_ai_local_id_short')) {
|
|
163
|
+
var _node$attrs;
|
|
164
|
+
if ((_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.localId && !hasInitializedExistingUUIDs) {
|
|
165
|
+
generatedShortUUIDs.add(node.attrs.localId);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
162
168
|
if (addedNodes.has(node)) {
|
|
163
169
|
return true;
|
|
164
170
|
}
|
|
165
171
|
localIds.add(node.attrs.localId);
|
|
166
172
|
return true;
|
|
167
173
|
});
|
|
174
|
+
hasInitializedExistingUUIDs = true;
|
|
168
175
|
// Also ensure the added have no duplicates
|
|
169
176
|
var seenIds = new Set();
|
|
170
177
|
var _iterator = _createForOfIteratorHelper(addedNodes),
|
|
@@ -176,11 +183,11 @@ export var createPlugin = function createPlugin(api) {
|
|
|
176
183
|
var pos = addedNodePos.get(node);
|
|
177
184
|
if (pos !== undefined) {
|
|
178
185
|
if (fg('platform_editor_localid_improvements')) {
|
|
179
|
-
var newId = generateUUID(
|
|
186
|
+
var newId = generateUUID();
|
|
180
187
|
nodesToUpdate.set(pos, newId);
|
|
181
188
|
seenIds.add(newId);
|
|
182
189
|
} else {
|
|
183
|
-
addLocalIdToNode(
|
|
190
|
+
addLocalIdToNode(pos, tr);
|
|
184
191
|
}
|
|
185
192
|
modified = true;
|
|
186
193
|
}
|
|
@@ -214,9 +221,8 @@ export var createPlugin = function createPlugin(api) {
|
|
|
214
221
|
* @param tr - The transaction to apply the change to
|
|
215
222
|
* @param node - Node reference for integer ID generator
|
|
216
223
|
*/
|
|
217
|
-
export var addLocalIdToNode = function addLocalIdToNode(
|
|
218
|
-
|
|
219
|
-
tr.setNodeAttribute(pos, 'localId', generateUUID(api, targetNode, pos));
|
|
224
|
+
export var addLocalIdToNode = function addLocalIdToNode(pos, tr) {
|
|
225
|
+
tr.setNodeAttribute(pos, 'localId', generateUUID());
|
|
220
226
|
tr.setMeta('addToHistory', false);
|
|
221
227
|
};
|
|
222
228
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
|
|
1
|
+
import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { CollabEditPlugin } from '@atlaskit/editor-plugin-collab-edit';
|
|
2
3
|
import type { CompositionPlugin } from '@atlaskit/editor-plugin-composition';
|
|
3
4
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
4
5
|
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
@@ -25,5 +26,5 @@ export type LocalIdPlugin = NextEditorPlugin<'localId', {
|
|
|
25
26
|
value: Node;
|
|
26
27
|
}) => boolean;
|
|
27
28
|
};
|
|
28
|
-
dependencies: [CompositionPlugin];
|
|
29
|
+
dependencies: [CompositionPlugin, OptionalPlugin<CollabEditPlugin>];
|
|
29
30
|
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Set to track currently generated and existing short UUIDs in the document.
|
|
3
|
+
* Used to prevent duplicate short IDs when using crypto.randomUUID().
|
|
4
|
+
*/
|
|
5
|
+
export declare const generatedShortUUIDs: Set<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Generates a short UUID and checks for duplicates against both
|
|
8
|
+
* generated UUIDs and existing UUIDs in the document.
|
|
9
|
+
* Retries up to 10 times if a duplicate is found.
|
|
10
|
+
* Falls back to full UUID if max retries exceeded.
|
|
11
|
+
*/
|
|
12
|
+
export declare const generateShortUUID: () => string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
-
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
3
|
import { PluginKey, type Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
5
4
|
import type { LocalIdPlugin } from '../localIdPluginType';
|
|
6
5
|
export declare const localIdPluginKey: PluginKey<any>;
|
|
@@ -14,7 +13,7 @@ export declare const createPlugin: (api: ExtractInjectionAPI<LocalIdPlugin> | un
|
|
|
14
13
|
* @param tr - The transaction to apply the change to
|
|
15
14
|
* @param node - Node reference for integer ID generator
|
|
16
15
|
*/
|
|
17
|
-
export declare const addLocalIdToNode: (
|
|
16
|
+
export declare const addLocalIdToNode: (pos: number, tr: Transaction) => void;
|
|
18
17
|
/**
|
|
19
18
|
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
20
19
|
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
|
|
1
|
+
import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { CollabEditPlugin } from '@atlaskit/editor-plugin-collab-edit';
|
|
2
3
|
import type { CompositionPlugin } from '@atlaskit/editor-plugin-composition';
|
|
3
4
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
4
5
|
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
@@ -26,6 +27,7 @@ export type LocalIdPlugin = NextEditorPlugin<'localId', {
|
|
|
26
27
|
}) => boolean;
|
|
27
28
|
};
|
|
28
29
|
dependencies: [
|
|
29
|
-
CompositionPlugin
|
|
30
|
+
CompositionPlugin,
|
|
31
|
+
OptionalPlugin<CollabEditPlugin>
|
|
30
32
|
];
|
|
31
33
|
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Set to track currently generated and existing short UUIDs in the document.
|
|
3
|
+
* Used to prevent duplicate short IDs when using crypto.randomUUID().
|
|
4
|
+
*/
|
|
5
|
+
export declare const generatedShortUUIDs: Set<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Generates a short UUID and checks for duplicates against both
|
|
8
|
+
* generated UUIDs and existing UUIDs in the document.
|
|
9
|
+
* Retries up to 10 times if a duplicate is found.
|
|
10
|
+
* Falls back to full UUID if max retries exceeded.
|
|
11
|
+
*/
|
|
12
|
+
export declare const generateShortUUID: () => string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
-
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
3
|
import { PluginKey, type Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
5
4
|
import type { LocalIdPlugin } from '../localIdPluginType';
|
|
6
5
|
export declare const localIdPluginKey: PluginKey<any>;
|
|
@@ -14,7 +13,7 @@ export declare const createPlugin: (api: ExtractInjectionAPI<LocalIdPlugin> | un
|
|
|
14
13
|
* @param tr - The transaction to apply the change to
|
|
15
14
|
* @param node - Node reference for integer ID generator
|
|
16
15
|
*/
|
|
17
|
-
export declare const addLocalIdToNode: (
|
|
16
|
+
export declare const addLocalIdToNode: (pos: number, tr: Transaction) => void;
|
|
18
17
|
/**
|
|
19
18
|
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
20
19
|
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-local-id",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "LocalId plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"@atlaskit/adf-schema": "^51.5.0",
|
|
32
32
|
"@atlaskit/editor-prosemirror": "^7.2.0",
|
|
33
33
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
34
|
-
"@atlaskit/tmp-editor-statsig": "^16.
|
|
34
|
+
"@atlaskit/tmp-editor-statsig": "^16.31.0",
|
|
35
35
|
"@babel/runtime": "^7.0.0",
|
|
36
36
|
"raf-schd": "^4.0.3"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@atlaskit/editor-common": "^111.
|
|
39
|
+
"@atlaskit/editor-common": "^111.8.0",
|
|
40
40
|
"react": "^18.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
@@ -85,9 +85,6 @@
|
|
|
85
85
|
"platform_editor_ai_local_id_short": {
|
|
86
86
|
"type": "boolean"
|
|
87
87
|
},
|
|
88
|
-
"platform_editor_ai_aifc_avoid_initial_localId": {
|
|
89
|
-
"type": "boolean"
|
|
90
|
-
},
|
|
91
88
|
"platform_editor_localid_improvements": {
|
|
92
89
|
"type": "boolean"
|
|
93
90
|
}
|
package/build/tsconfig.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../tsconfig",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"target": "es5",
|
|
5
|
-
"paths": {}
|
|
6
|
-
},
|
|
7
|
-
"include": [
|
|
8
|
-
"../src/**/*.ts",
|
|
9
|
-
"../src/**/*.tsx"
|
|
10
|
-
],
|
|
11
|
-
"exclude": [
|
|
12
|
-
"../src/**/__tests__/*",
|
|
13
|
-
"../src/**/*.test.*",
|
|
14
|
-
"../src/**/test.*",
|
|
15
|
-
"../src/**/examples.*"
|
|
16
|
-
]
|
|
17
|
-
}
|