@atlaskit/editor-synced-block-provider 0.5.3 → 0.6.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`218e1d54178bb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/218e1d54178bb) -
8
+ Pre-fetch URL to source blocks
9
+
3
10
  ## 0.5.3
4
11
 
5
12
  ### Patch Changes
@@ -5,14 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.useMemoizedSyncedBlockProvider = exports.useHandleContentChanges = exports.useFetchDocNode = exports.SyncBlockProvider = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
10
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
11
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
12
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
13
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
12
14
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
13
15
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
14
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
17
  var _react = require("react");
18
+ var _ari = require("../utils/ari");
16
19
  var _utils = require("../utils/utils");
17
20
  var _types = require("./types");
18
21
  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; }
@@ -25,17 +28,31 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
25
28
  (0, _classCallCheck2.default)(this, SyncBlockProvider);
26
29
  _this = _callSuper(this, SyncBlockProvider);
27
30
  (0, _defineProperty2.default)(_this, "name", 'syncBlockProvider');
28
- (0, _defineProperty2.default)(_this, "isNodeSupported", function (node) {
31
+ _this.fetchProvider = fetchProvider;
32
+ _this.writeProvider = writeProvider;
33
+ _this.sourceId = sourceId;
34
+ return _this;
35
+ }
36
+ (0, _inherits2.default)(SyncBlockProvider, _SyncBlockDataProvide);
37
+ return (0, _createClass2.default)(SyncBlockProvider, [{
38
+ key: "isNodeSupported",
39
+ value: function isNodeSupported(node) {
29
40
  return node.type === 'syncBlock';
30
- });
31
- (0, _defineProperty2.default)(_this, "nodeDataKey", function (node) {
41
+ }
42
+ }, {
43
+ key: "nodeDataKey",
44
+ value: function nodeDataKey(node) {
32
45
  return node.attrs.localId;
33
- });
34
- (0, _defineProperty2.default)(_this, "fetchNodesData", function (nodes) {
46
+ }
47
+ }, {
48
+ key: "fetchNodesData",
49
+ value: function fetchNodesData(nodes) {
50
+ var _this2 = this;
35
51
  return Promise.all(nodes.map(function (node) {
36
- return _this.fetchProvider.fetchData(node.attrs.resourceId);
52
+ return _this2.fetchProvider.fetchData(node.attrs.resourceId);
37
53
  }));
38
- });
54
+ }
55
+
39
56
  /**
40
57
  *
41
58
  * @param nodes
@@ -43,28 +60,41 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
43
60
  *
44
61
  * @returns the resource ids of the nodes that were written
45
62
  */
46
- (0, _defineProperty2.default)(_this, "writeNodesData", function (nodes, data) {
63
+ }, {
64
+ key: "writeNodesData",
65
+ value: function writeNodesData(nodes, data) {
66
+ var _this3 = this;
47
67
  var resourceIds = [];
48
68
  nodes.forEach(function (node, index) {
49
69
  if (!data[index].content) {
50
70
  resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
51
71
  return;
52
72
  }
53
- var resourceId = _this.writeProvider.writeData(data[index]);
73
+ var resourceId = _this3.writeProvider.writeData(data[index]);
54
74
  resourceIds.push(resourceId);
55
75
  });
56
76
  return Promise.all(resourceIds);
57
- });
58
- (0, _defineProperty2.default)(_this, "getSourceId", function () {
59
- return _this.sourceId;
60
- });
61
- _this.fetchProvider = fetchProvider;
62
- _this.writeProvider = writeProvider;
63
- _this.sourceId = sourceId;
64
- return _this;
65
- }
66
- (0, _inherits2.default)(SyncBlockProvider, _SyncBlockDataProvide);
67
- return (0, _createClass2.default)(SyncBlockProvider);
77
+ }
78
+ }, {
79
+ key: "getSourceId",
80
+ value: function getSourceId() {
81
+ return this.sourceId;
82
+ }
83
+ }, {
84
+ key: "retrieveSyncBlockSourceUrl",
85
+ value: function retrieveSyncBlockSourceUrl(node) {
86
+ var resourceId = node.attrs.resourceId;
87
+ var pageARI;
88
+ if (resourceId && typeof resourceId === 'string') {
89
+ try {
90
+ pageARI = (0, _ari.getPageARIFromResourceId)(resourceId);
91
+ } catch (error) {
92
+ return Promise.reject(error);
93
+ }
94
+ }
95
+ return pageARI ? fetchURLfromARI(pageARI) : Promise.resolve(undefined);
96
+ }
97
+ }]);
68
98
  }(_types.SyncBlockDataProvider);
69
99
  var useFetchDocNode = exports.useFetchDocNode = function useFetchDocNode(editorView, node, defaultDocNode, provider) {
70
100
  var _useState = (0, _react.useState)(defaultDocNode),
@@ -118,4 +148,55 @@ var useHandleContentChanges = exports.useHandleContentChanges = function useHand
118
148
  };
119
149
  provider === null || provider === void 0 || provider.writeNodesData([syncBlockNode], [data]);
120
150
  }, [isSource, node, provider, updatedDoc]);
121
- };
151
+ };
152
+ var fetchURLfromARI = /*#__PURE__*/function () {
153
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(ari) {
154
+ var response, _payload$data, payload, url;
155
+ return _regenerator.default.wrap(function _callee$(_context) {
156
+ while (1) switch (_context.prev = _context.next) {
157
+ case 0:
158
+ _context.next = 2;
159
+ return fetch('/gateway/api/object-resolver/resolve/ari', {
160
+ method: 'POST',
161
+ headers: {
162
+ 'Content-Type': 'application/json',
163
+ Accept: 'application/json'
164
+ },
165
+ body: JSON.stringify({
166
+ ari: ari
167
+ })
168
+ });
169
+ case 2:
170
+ response = _context.sent;
171
+ if (!response.ok) {
172
+ _context.next = 12;
173
+ break;
174
+ }
175
+ _context.next = 6;
176
+ return response.json();
177
+ case 6:
178
+ payload = _context.sent;
179
+ url = payload === null || payload === void 0 || (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
180
+ if (!(typeof url === 'string')) {
181
+ _context.next = 10;
182
+ break;
183
+ }
184
+ return _context.abrupt("return", url);
185
+ case 10:
186
+ _context.next = 13;
187
+ break;
188
+ case 12:
189
+ //eslint-disable-next-line no-console
190
+ console.error('Failed to fetch URL from ARI', response.statusText);
191
+ case 13:
192
+ return _context.abrupt("return", undefined);
193
+ case 14:
194
+ case "end":
195
+ return _context.stop();
196
+ }
197
+ }, _callee);
198
+ }));
199
+ return function fetchURLfromARI(_x) {
200
+ return _ref.apply(this, arguments);
201
+ };
202
+ }();
@@ -25,7 +25,64 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
25
25
  this.syncBlocks = new Map();
26
26
  this.dataProvider = dataProvider;
27
27
  }
28
+
29
+ /**
30
+ * Add/update a sync block node to the store.
31
+ * @param node - The sync block node to add
32
+ * @returns True if the sync block node was added/updated
33
+ */
28
34
  return (0, _createClass2.default)(SyncBlockStoreManager, [{
35
+ key: "updateSyncBlockNode",
36
+ value: function updateSyncBlockNode(node) {
37
+ var _this = this;
38
+ var _node$attrs = node.attrs,
39
+ localId = _node$attrs.localId,
40
+ resourceId = _node$attrs.resourceId;
41
+ if (!localId || !resourceId) {
42
+ return false;
43
+ }
44
+ var existingSyncBlock = this.syncBlocks.get(resourceId);
45
+ var sourceURL = existingSyncBlock === null || existingSyncBlock === void 0 ? void 0 : existingSyncBlock.sourceURL; //avoid fetching the URL again
46
+
47
+ // if the sync block is a reference block, we need to fetch the URL to the source
48
+ // we could optimise this further by checking if the sync block is on the same page as the source
49
+ if (!sourceURL && !this.isSourceBlock(node) && this.dataProvider) {
50
+ this.syncBlocks.set(resourceId, {
51
+ resourceId: resourceId,
52
+ sourceLocalId: localId,
53
+ sourceURL: undefined
54
+ });
55
+ this.dataProvider.retrieveSyncBlockSourceUrl({
56
+ attrs: {
57
+ localId: localId,
58
+ resourceId: resourceId
59
+ },
60
+ type: 'syncBlock'
61
+ }).then(function (url) {
62
+ if (_this.syncBlocks.has(resourceId)) {
63
+ _this.syncBlocks.set(resourceId, {
64
+ resourceId: resourceId,
65
+ sourceLocalId: localId,
66
+ sourceURL: url
67
+ });
68
+ }
69
+ }); // prefetch the data for the sync block URL
70
+ }
71
+ return true;
72
+ }
73
+
74
+ /**
75
+ * Get the URL for a sync block.
76
+ * @param resourceId - The resource ID of the sync block to get the URL for
77
+ * @returns
78
+ */
79
+ }, {
80
+ key: "getSyncBlockURL",
81
+ value: function getSyncBlockURL(resourceId) {
82
+ var syncBlock = this.syncBlocks.get(resourceId);
83
+ return syncBlock === null || syncBlock === void 0 ? void 0 : syncBlock.sourceURL;
84
+ }
85
+ }, {
29
86
  key: "setEditorView",
30
87
  value: function setEditorView(editorView) {
31
88
  this.editorView = editorView;
@@ -47,9 +104,9 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
47
104
  if (node.type.name !== 'syncBlock') {
48
105
  return false;
49
106
  }
50
- var _node$attrs = node.attrs,
51
- resourceId = _node$attrs.resourceId,
52
- localId = _node$attrs.localId;
107
+ var _node$attrs2 = node.attrs,
108
+ resourceId = _node$attrs2.resourceId,
109
+ localId = _node$attrs2.localId;
53
110
  var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
54
111
  if (!sourceId) {
55
112
  return false;
@@ -59,10 +116,10 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
59
116
  }, {
60
117
  key: "registerConfirmationCallback",
61
118
  value: function registerConfirmationCallback(callback) {
62
- var _this = this;
119
+ var _this2 = this;
63
120
  this.confirmationCallback = callback;
64
121
  return function () {
65
- _this.confirmationCallback = undefined;
122
+ _this2.confirmationCallback = undefined;
66
123
  };
67
124
  }
68
125
  }, {
@@ -76,7 +133,10 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
76
133
  var _this$dataProvider2;
77
134
  var localId = (0, _uuid.default)();
78
135
  var sourceId = (_this$dataProvider2 = this.dataProvider) === null || _this$dataProvider2 === void 0 ? void 0 : _this$dataProvider2.getSourceId();
79
- var resourceId = sourceId ? (0, _ari.resourceIdFromSourceAndLocalId)(sourceId, localId) : localId;
136
+ if (!sourceId) {
137
+ throw new Error('Provider of sync block plugin is not set');
138
+ }
139
+ var resourceId = (0, _ari.resourceIdFromSourceAndLocalId)(sourceId, localId);
80
140
  var syncBlockNode = {
81
141
  attrs: {
82
142
  resourceId: resourceId,
@@ -84,17 +144,13 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
84
144
  },
85
145
  type: 'syncBlock'
86
146
  };
87
- this.syncBlocks.set(syncBlockNode.attrs.resourceId, {
88
- resourceId: syncBlockNode.attrs.resourceId,
89
- sourceLocalId: syncBlockNode.attrs.localId
90
- });
91
147
  return syncBlockNode;
92
148
  }
93
149
  }, {
94
150
  key: "deleteSyncBlocksWithConfirmation",
95
151
  value: function () {
96
152
  var _deleteSyncBlocksWithConfirmation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(tr, syncBlockIds) {
97
- var _this2 = this;
153
+ var _this3 = this;
98
154
  var confirmed, _this$editorView;
99
155
  return _regenerator.default.wrap(function _callee$(_context) {
100
156
  while (1) switch (_context.prev = _context.next) {
@@ -113,7 +169,7 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
113
169
  // Need to update the BE on deletion
114
170
  syncBlockIds.forEach(function (_ref) {
115
171
  var resourceId = _ref.resourceId;
116
- return _this2.syncBlocks.delete(resourceId);
172
+ return _this3.syncBlocks.delete(resourceId);
117
173
  });
118
174
  }
119
175
  this.confirmationTransaction = undefined;
package/dist/cjs/index.js CHANGED
@@ -27,12 +27,6 @@ Object.defineProperty(exports, "createContentAPIProvidersWithDefaultKey", {
27
27
  return _confluenceContentAPI.createContentAPIProvidersWithDefaultKey;
28
28
  }
29
29
  });
30
- Object.defineProperty(exports, "generateSyncBlockSourceUrl", {
31
- enumerable: true,
32
- get: function get() {
33
- return _utils.generateSyncBlockSourceUrl;
34
- }
35
- });
36
30
  Object.defineProperty(exports, "getConfluencePageAri", {
37
31
  enumerable: true,
38
32
  get: function get() {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.resourceIdFromSourceAndLocalId = exports.getPageIdFromAri = exports.getLocalIdFromAri = exports.getContentPropertyIdFromAri = exports.getContentPropertyAri = exports.getConfluencePageAri = void 0;
6
+ exports.resourceIdFromSourceAndLocalId = exports.getPageIdFromAri = exports.getPageARIFromResourceId = exports.getLocalIdFromAri = exports.getContentPropertyIdFromAri = exports.getContentPropertyAri = exports.getConfluencePageAri = void 0;
7
7
  var getConfluencePageAri = exports.getConfluencePageAri = function getConfluencePageAri(pageId, cloudId) {
8
8
  return "ari:cloud:confluence:".concat(cloudId, ":page/").concat(pageId);
9
9
  };
@@ -29,6 +29,14 @@ var getLocalIdFromAri = exports.getLocalIdFromAri = function getLocalIdFromAri(a
29
29
  }
30
30
  throw new Error("Invalid page ARI: ".concat(ari));
31
31
  };
32
+ var getPageARIFromResourceId = exports.getPageARIFromResourceId = function getPageARIFromResourceId(resourceId) {
33
+ // eslint-disable-next-line require-unicode-regexp
34
+ var match = resourceId.match(/(ari:cloud:confluence:[^:]+:page\/\d+)\/([a-zA-Z0-9-]+)$/);
35
+ if (match !== null && match !== void 0 && match[1]) {
36
+ return match[1];
37
+ }
38
+ throw new Error("Invalid resourceId: ".concat(resourceId));
39
+ };
32
40
  var getContentPropertyAri = exports.getContentPropertyAri = function getContentPropertyAri(contentPropertyId, cloudId) {
33
41
  return "ari:cloud:confluence:".concat(cloudId, ":content/").concat(contentPropertyId);
34
42
  };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.generateSyncBlockSourceUrl = exports.convertSyncBlockPMNodeToSyncBlockData = void 0;
6
+ exports.convertSyncBlockPMNodeToSyncBlockData = void 0;
7
7
  var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
8
8
  var convertSyncBlockPMNodeToSyncBlockData = exports.convertSyncBlockPMNodeToSyncBlockData = function convertSyncBlockPMNodeToSyncBlockData(node) {
9
9
  var includeContent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -19,15 +19,4 @@ var convertSyncBlockPMNodeToSyncBlockData = exports.convertSyncBlockPMNodeToSync
19
19
  },
20
20
  content: includeContent ? node.content.content.map(toJSON) : undefined
21
21
  };
22
- };
23
- var generateSyncBlockSourceUrl = exports.generateSyncBlockSourceUrl = function generateSyncBlockSourceUrl(node) {
24
- var _node$attrs = node.attrs,
25
- localId = _node$attrs.localId,
26
- resourceId = _node$attrs.resourceId;
27
- // TODO: EDITOR-1644 - To be implemented under EDITOR-1644
28
- // below is a temporary implementation for the url generation
29
- var url = new URL(location.origin + location.pathname);
30
- url.searchParams.set('localId', localId);
31
- url.searchParams.set('resourceId', resourceId);
32
- return url.toString();
33
22
  };
@@ -1,44 +1,64 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { useEffect, useState, useMemo } from 'react';
3
+ import { getPageARIFromResourceId } from '../utils/ari';
3
4
  import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
4
5
  import { SyncBlockDataProvider } from './types';
5
6
  export class SyncBlockProvider extends SyncBlockDataProvider {
6
7
  constructor(fetchProvider, writeProvider, sourceId) {
7
8
  super();
8
9
  _defineProperty(this, "name", 'syncBlockProvider');
9
- _defineProperty(this, "isNodeSupported", node => node.type === 'syncBlock');
10
- _defineProperty(this, "nodeDataKey", node => node.attrs.localId);
11
- _defineProperty(this, "fetchNodesData", nodes => {
12
- return Promise.all(nodes.map(node => {
13
- return this.fetchProvider.fetchData(node.attrs.resourceId);
14
- }));
15
- });
16
- /**
17
- *
18
- * @param nodes
19
- * @param data
20
- *
21
- * @returns the resource ids of the nodes that were written
22
- */
23
- _defineProperty(this, "writeNodesData", (nodes, data) => {
24
- const resourceIds = [];
25
- nodes.forEach((node, index) => {
26
- if (!data[index].content) {
27
- resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
28
- return;
29
- }
30
- const resourceId = this.writeProvider.writeData(data[index]);
31
- resourceIds.push(resourceId);
32
- });
33
- return Promise.all(resourceIds);
34
- });
35
- _defineProperty(this, "getSourceId", () => {
36
- return this.sourceId;
37
- });
38
10
  this.fetchProvider = fetchProvider;
39
11
  this.writeProvider = writeProvider;
40
12
  this.sourceId = sourceId;
41
13
  }
14
+ isNodeSupported(node) {
15
+ return node.type === 'syncBlock';
16
+ }
17
+ nodeDataKey(node) {
18
+ return node.attrs.localId;
19
+ }
20
+ fetchNodesData(nodes) {
21
+ return Promise.all(nodes.map(node => {
22
+ return this.fetchProvider.fetchData(node.attrs.resourceId);
23
+ }));
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @param nodes
29
+ * @param data
30
+ *
31
+ * @returns the resource ids of the nodes that were written
32
+ */
33
+ writeNodesData(nodes, data) {
34
+ const resourceIds = [];
35
+ nodes.forEach((node, index) => {
36
+ if (!data[index].content) {
37
+ resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
38
+ return;
39
+ }
40
+ const resourceId = this.writeProvider.writeData(data[index]);
41
+ resourceIds.push(resourceId);
42
+ });
43
+ return Promise.all(resourceIds);
44
+ }
45
+ getSourceId() {
46
+ return this.sourceId;
47
+ }
48
+ retrieveSyncBlockSourceUrl(node) {
49
+ const {
50
+ resourceId
51
+ } = node.attrs;
52
+ let pageARI;
53
+ if (resourceId && typeof resourceId === 'string') {
54
+ try {
55
+ pageARI = getPageARIFromResourceId(resourceId);
56
+ } catch (error) {
57
+ return Promise.reject(error);
58
+ }
59
+ }
60
+ return pageARI ? fetchURLfromARI(pageARI) : Promise.resolve(undefined);
61
+ }
42
62
  }
43
63
  export const useFetchDocNode = (editorView, node, defaultDocNode, provider) => {
44
64
  const [docNode, setDocNode] = useState(defaultDocNode);
@@ -90,4 +110,28 @@ export const useHandleContentChanges = (updatedDoc, isSource, node, provider) =>
90
110
  };
91
111
  provider === null || provider === void 0 ? void 0 : provider.writeNodesData([syncBlockNode], [data]);
92
112
  }, [isSource, node, provider, updatedDoc]);
113
+ };
114
+ const fetchURLfromARI = async ari => {
115
+ const response = await fetch('/gateway/api/object-resolver/resolve/ari', {
116
+ method: 'POST',
117
+ headers: {
118
+ 'Content-Type': 'application/json',
119
+ Accept: 'application/json'
120
+ },
121
+ body: JSON.stringify({
122
+ ari
123
+ })
124
+ });
125
+ if (response.ok) {
126
+ var _payload$data;
127
+ const payload = await response.json();
128
+ const url = payload === null || payload === void 0 ? void 0 : (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
129
+ if (typeof url === 'string') {
130
+ return url;
131
+ }
132
+ } else {
133
+ //eslint-disable-next-line no-console
134
+ console.error('Failed to fetch URL from ARI', response.statusText);
135
+ }
136
+ return undefined;
93
137
  };
@@ -15,6 +15,59 @@ export class SyncBlockStoreManager {
15
15
  this.syncBlocks = new Map();
16
16
  this.dataProvider = dataProvider;
17
17
  }
18
+
19
+ /**
20
+ * Add/update a sync block node to the store.
21
+ * @param node - The sync block node to add
22
+ * @returns True if the sync block node was added/updated
23
+ */
24
+ updateSyncBlockNode(node) {
25
+ const {
26
+ localId,
27
+ resourceId
28
+ } = node.attrs;
29
+ if (!localId || !resourceId) {
30
+ return false;
31
+ }
32
+ const existingSyncBlock = this.syncBlocks.get(resourceId);
33
+ const sourceURL = existingSyncBlock === null || existingSyncBlock === void 0 ? void 0 : existingSyncBlock.sourceURL; //avoid fetching the URL again
34
+
35
+ // if the sync block is a reference block, we need to fetch the URL to the source
36
+ // we could optimise this further by checking if the sync block is on the same page as the source
37
+ if (!sourceURL && !this.isSourceBlock(node) && this.dataProvider) {
38
+ this.syncBlocks.set(resourceId, {
39
+ resourceId,
40
+ sourceLocalId: localId,
41
+ sourceURL: undefined
42
+ });
43
+ this.dataProvider.retrieveSyncBlockSourceUrl({
44
+ attrs: {
45
+ localId,
46
+ resourceId
47
+ },
48
+ type: 'syncBlock'
49
+ }).then(url => {
50
+ if (this.syncBlocks.has(resourceId)) {
51
+ this.syncBlocks.set(resourceId, {
52
+ resourceId,
53
+ sourceLocalId: localId,
54
+ sourceURL: url
55
+ });
56
+ }
57
+ }); // prefetch the data for the sync block URL
58
+ }
59
+ return true;
60
+ }
61
+
62
+ /**
63
+ * Get the URL for a sync block.
64
+ * @param resourceId - The resource ID of the sync block to get the URL for
65
+ * @returns
66
+ */
67
+ getSyncBlockURL(resourceId) {
68
+ const syncBlock = this.syncBlocks.get(resourceId);
69
+ return syncBlock === null || syncBlock === void 0 ? void 0 : syncBlock.sourceURL;
70
+ }
18
71
  setEditorView(editorView) {
19
72
  this.editorView = editorView;
20
73
  }
@@ -52,7 +105,10 @@ export class SyncBlockStoreManager {
52
105
  var _this$dataProvider2;
53
106
  const localId = uuid();
54
107
  const sourceId = (_this$dataProvider2 = this.dataProvider) === null || _this$dataProvider2 === void 0 ? void 0 : _this$dataProvider2.getSourceId();
55
- const resourceId = sourceId ? resourceIdFromSourceAndLocalId(sourceId, localId) : localId;
108
+ if (!sourceId) {
109
+ throw new Error('Provider of sync block plugin is not set');
110
+ }
111
+ const resourceId = resourceIdFromSourceAndLocalId(sourceId, localId);
56
112
  const syncBlockNode = {
57
113
  attrs: {
58
114
  resourceId,
@@ -60,10 +116,6 @@ export class SyncBlockStoreManager {
60
116
  },
61
117
  type: 'syncBlock'
62
118
  };
63
- this.syncBlocks.set(syncBlockNode.attrs.resourceId, {
64
- resourceId: syncBlockNode.attrs.resourceId,
65
- sourceLocalId: syncBlockNode.attrs.localId
66
- });
67
119
  return syncBlockNode;
68
120
  }
69
121
  async deleteSyncBlocksWithConfirmation(tr, syncBlockIds) {
@@ -6,5 +6,5 @@ export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemo
6
6
  export { getDefaultSyncBlockSchema } from './common/schema';
7
7
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluenceContentAPI';
8
8
  export { getConfluencePageAri } from './utils/ari';
9
- export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
9
+ export { convertSyncBlockPMNodeToSyncBlockData } from './utils/utils';
10
10
  export { rebaseTransaction } from './common/rebase-transaction';
@@ -21,6 +21,14 @@ export const getLocalIdFromAri = ari => {
21
21
  }
22
22
  throw new Error(`Invalid page ARI: ${ari}`);
23
23
  };
24
+ export const getPageARIFromResourceId = resourceId => {
25
+ // eslint-disable-next-line require-unicode-regexp
26
+ const match = resourceId.match(/(ari:cloud:confluence:[^:]+:page\/\d+)\/([a-zA-Z0-9-]+)$/);
27
+ if (match !== null && match !== void 0 && match[1]) {
28
+ return match[1];
29
+ }
30
+ throw new Error(`Invalid resourceId: ${resourceId}`);
31
+ };
24
32
  export const getContentPropertyAri = (contentPropertyId, cloudId) => `ari:cloud:confluence:${cloudId}:content/${contentPropertyId}`;
25
33
  export const getContentPropertyIdFromAri = ari => {
26
34
  // eslint-disable-next-line require-unicode-regexp
@@ -10,16 +10,4 @@ export const convertSyncBlockPMNodeToSyncBlockData = (node, includeContent = fal
10
10
  },
11
11
  content: includeContent ? node.content.content.map(toJSON) : undefined
12
12
  };
13
- };
14
- export const generateSyncBlockSourceUrl = node => {
15
- const {
16
- localId,
17
- resourceId
18
- } = node.attrs;
19
- // TODO: EDITOR-1644 - To be implemented under EDITOR-1644
20
- // below is a temporary implementation for the url generation
21
- const url = new URL(location.origin + location.pathname);
22
- url.searchParams.set('localId', localId);
23
- url.searchParams.set('resourceId', resourceId);
24
- return url.toString();
25
13
  };
@@ -1,15 +1,18 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
1
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
+ import _createClass from "@babel/runtime/helpers/createClass";
4
5
  import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
5
6
  import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
6
7
  import _inherits from "@babel/runtime/helpers/inherits";
7
8
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
9
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
8
10
  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; }
9
11
  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; }
10
12
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
11
13
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
12
14
  import { useEffect, useState, useMemo } from 'react';
15
+ import { getPageARIFromResourceId } from '../utils/ari';
13
16
  import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
14
17
  import { SyncBlockDataProvider } from './types';
15
18
  export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
@@ -18,17 +21,31 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
18
21
  _classCallCheck(this, SyncBlockProvider);
19
22
  _this = _callSuper(this, SyncBlockProvider);
20
23
  _defineProperty(_this, "name", 'syncBlockProvider');
21
- _defineProperty(_this, "isNodeSupported", function (node) {
24
+ _this.fetchProvider = fetchProvider;
25
+ _this.writeProvider = writeProvider;
26
+ _this.sourceId = sourceId;
27
+ return _this;
28
+ }
29
+ _inherits(SyncBlockProvider, _SyncBlockDataProvide);
30
+ return _createClass(SyncBlockProvider, [{
31
+ key: "isNodeSupported",
32
+ value: function isNodeSupported(node) {
22
33
  return node.type === 'syncBlock';
23
- });
24
- _defineProperty(_this, "nodeDataKey", function (node) {
34
+ }
35
+ }, {
36
+ key: "nodeDataKey",
37
+ value: function nodeDataKey(node) {
25
38
  return node.attrs.localId;
26
- });
27
- _defineProperty(_this, "fetchNodesData", function (nodes) {
39
+ }
40
+ }, {
41
+ key: "fetchNodesData",
42
+ value: function fetchNodesData(nodes) {
43
+ var _this2 = this;
28
44
  return Promise.all(nodes.map(function (node) {
29
- return _this.fetchProvider.fetchData(node.attrs.resourceId);
45
+ return _this2.fetchProvider.fetchData(node.attrs.resourceId);
30
46
  }));
31
- });
47
+ }
48
+
32
49
  /**
33
50
  *
34
51
  * @param nodes
@@ -36,28 +53,41 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
36
53
  *
37
54
  * @returns the resource ids of the nodes that were written
38
55
  */
39
- _defineProperty(_this, "writeNodesData", function (nodes, data) {
56
+ }, {
57
+ key: "writeNodesData",
58
+ value: function writeNodesData(nodes, data) {
59
+ var _this3 = this;
40
60
  var resourceIds = [];
41
61
  nodes.forEach(function (node, index) {
42
62
  if (!data[index].content) {
43
63
  resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
44
64
  return;
45
65
  }
46
- var resourceId = _this.writeProvider.writeData(data[index]);
66
+ var resourceId = _this3.writeProvider.writeData(data[index]);
47
67
  resourceIds.push(resourceId);
48
68
  });
49
69
  return Promise.all(resourceIds);
50
- });
51
- _defineProperty(_this, "getSourceId", function () {
52
- return _this.sourceId;
53
- });
54
- _this.fetchProvider = fetchProvider;
55
- _this.writeProvider = writeProvider;
56
- _this.sourceId = sourceId;
57
- return _this;
58
- }
59
- _inherits(SyncBlockProvider, _SyncBlockDataProvide);
60
- return _createClass(SyncBlockProvider);
70
+ }
71
+ }, {
72
+ key: "getSourceId",
73
+ value: function getSourceId() {
74
+ return this.sourceId;
75
+ }
76
+ }, {
77
+ key: "retrieveSyncBlockSourceUrl",
78
+ value: function retrieveSyncBlockSourceUrl(node) {
79
+ var resourceId = node.attrs.resourceId;
80
+ var pageARI;
81
+ if (resourceId && typeof resourceId === 'string') {
82
+ try {
83
+ pageARI = getPageARIFromResourceId(resourceId);
84
+ } catch (error) {
85
+ return Promise.reject(error);
86
+ }
87
+ }
88
+ return pageARI ? fetchURLfromARI(pageARI) : Promise.resolve(undefined);
89
+ }
90
+ }]);
61
91
  }(SyncBlockDataProvider);
62
92
  export var useFetchDocNode = function useFetchDocNode(editorView, node, defaultDocNode, provider) {
63
93
  var _useState = useState(defaultDocNode),
@@ -111,4 +141,55 @@ export var useHandleContentChanges = function useHandleContentChanges(updatedDoc
111
141
  };
112
142
  provider === null || provider === void 0 || provider.writeNodesData([syncBlockNode], [data]);
113
143
  }, [isSource, node, provider, updatedDoc]);
114
- };
144
+ };
145
+ var fetchURLfromARI = /*#__PURE__*/function () {
146
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ari) {
147
+ var response, _payload$data, payload, url;
148
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
149
+ while (1) switch (_context.prev = _context.next) {
150
+ case 0:
151
+ _context.next = 2;
152
+ return fetch('/gateway/api/object-resolver/resolve/ari', {
153
+ method: 'POST',
154
+ headers: {
155
+ 'Content-Type': 'application/json',
156
+ Accept: 'application/json'
157
+ },
158
+ body: JSON.stringify({
159
+ ari: ari
160
+ })
161
+ });
162
+ case 2:
163
+ response = _context.sent;
164
+ if (!response.ok) {
165
+ _context.next = 12;
166
+ break;
167
+ }
168
+ _context.next = 6;
169
+ return response.json();
170
+ case 6:
171
+ payload = _context.sent;
172
+ url = payload === null || payload === void 0 || (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
173
+ if (!(typeof url === 'string')) {
174
+ _context.next = 10;
175
+ break;
176
+ }
177
+ return _context.abrupt("return", url);
178
+ case 10:
179
+ _context.next = 13;
180
+ break;
181
+ case 12:
182
+ //eslint-disable-next-line no-console
183
+ console.error('Failed to fetch URL from ARI', response.statusText);
184
+ case 13:
185
+ return _context.abrupt("return", undefined);
186
+ case 14:
187
+ case "end":
188
+ return _context.stop();
189
+ }
190
+ }, _callee);
191
+ }));
192
+ return function fetchURLfromARI(_x) {
193
+ return _ref.apply(this, arguments);
194
+ };
195
+ }();
@@ -20,7 +20,64 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
20
20
  this.syncBlocks = new Map();
21
21
  this.dataProvider = dataProvider;
22
22
  }
23
+
24
+ /**
25
+ * Add/update a sync block node to the store.
26
+ * @param node - The sync block node to add
27
+ * @returns True if the sync block node was added/updated
28
+ */
23
29
  return _createClass(SyncBlockStoreManager, [{
30
+ key: "updateSyncBlockNode",
31
+ value: function updateSyncBlockNode(node) {
32
+ var _this = this;
33
+ var _node$attrs = node.attrs,
34
+ localId = _node$attrs.localId,
35
+ resourceId = _node$attrs.resourceId;
36
+ if (!localId || !resourceId) {
37
+ return false;
38
+ }
39
+ var existingSyncBlock = this.syncBlocks.get(resourceId);
40
+ var sourceURL = existingSyncBlock === null || existingSyncBlock === void 0 ? void 0 : existingSyncBlock.sourceURL; //avoid fetching the URL again
41
+
42
+ // if the sync block is a reference block, we need to fetch the URL to the source
43
+ // we could optimise this further by checking if the sync block is on the same page as the source
44
+ if (!sourceURL && !this.isSourceBlock(node) && this.dataProvider) {
45
+ this.syncBlocks.set(resourceId, {
46
+ resourceId: resourceId,
47
+ sourceLocalId: localId,
48
+ sourceURL: undefined
49
+ });
50
+ this.dataProvider.retrieveSyncBlockSourceUrl({
51
+ attrs: {
52
+ localId: localId,
53
+ resourceId: resourceId
54
+ },
55
+ type: 'syncBlock'
56
+ }).then(function (url) {
57
+ if (_this.syncBlocks.has(resourceId)) {
58
+ _this.syncBlocks.set(resourceId, {
59
+ resourceId: resourceId,
60
+ sourceLocalId: localId,
61
+ sourceURL: url
62
+ });
63
+ }
64
+ }); // prefetch the data for the sync block URL
65
+ }
66
+ return true;
67
+ }
68
+
69
+ /**
70
+ * Get the URL for a sync block.
71
+ * @param resourceId - The resource ID of the sync block to get the URL for
72
+ * @returns
73
+ */
74
+ }, {
75
+ key: "getSyncBlockURL",
76
+ value: function getSyncBlockURL(resourceId) {
77
+ var syncBlock = this.syncBlocks.get(resourceId);
78
+ return syncBlock === null || syncBlock === void 0 ? void 0 : syncBlock.sourceURL;
79
+ }
80
+ }, {
24
81
  key: "setEditorView",
25
82
  value: function setEditorView(editorView) {
26
83
  this.editorView = editorView;
@@ -42,9 +99,9 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
42
99
  if (node.type.name !== 'syncBlock') {
43
100
  return false;
44
101
  }
45
- var _node$attrs = node.attrs,
46
- resourceId = _node$attrs.resourceId,
47
- localId = _node$attrs.localId;
102
+ var _node$attrs2 = node.attrs,
103
+ resourceId = _node$attrs2.resourceId,
104
+ localId = _node$attrs2.localId;
48
105
  var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
49
106
  if (!sourceId) {
50
107
  return false;
@@ -54,10 +111,10 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
54
111
  }, {
55
112
  key: "registerConfirmationCallback",
56
113
  value: function registerConfirmationCallback(callback) {
57
- var _this = this;
114
+ var _this2 = this;
58
115
  this.confirmationCallback = callback;
59
116
  return function () {
60
- _this.confirmationCallback = undefined;
117
+ _this2.confirmationCallback = undefined;
61
118
  };
62
119
  }
63
120
  }, {
@@ -71,7 +128,10 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
71
128
  var _this$dataProvider2;
72
129
  var localId = uuid();
73
130
  var sourceId = (_this$dataProvider2 = this.dataProvider) === null || _this$dataProvider2 === void 0 ? void 0 : _this$dataProvider2.getSourceId();
74
- var resourceId = sourceId ? resourceIdFromSourceAndLocalId(sourceId, localId) : localId;
131
+ if (!sourceId) {
132
+ throw new Error('Provider of sync block plugin is not set');
133
+ }
134
+ var resourceId = resourceIdFromSourceAndLocalId(sourceId, localId);
75
135
  var syncBlockNode = {
76
136
  attrs: {
77
137
  resourceId: resourceId,
@@ -79,17 +139,13 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
79
139
  },
80
140
  type: 'syncBlock'
81
141
  };
82
- this.syncBlocks.set(syncBlockNode.attrs.resourceId, {
83
- resourceId: syncBlockNode.attrs.resourceId,
84
- sourceLocalId: syncBlockNode.attrs.localId
85
- });
86
142
  return syncBlockNode;
87
143
  }
88
144
  }, {
89
145
  key: "deleteSyncBlocksWithConfirmation",
90
146
  value: function () {
91
147
  var _deleteSyncBlocksWithConfirmation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(tr, syncBlockIds) {
92
- var _this2 = this;
148
+ var _this3 = this;
93
149
  var confirmed, _this$editorView;
94
150
  return _regeneratorRuntime.wrap(function _callee$(_context) {
95
151
  while (1) switch (_context.prev = _context.next) {
@@ -108,7 +164,7 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
108
164
  // Need to update the BE on deletion
109
165
  syncBlockIds.forEach(function (_ref) {
110
166
  var resourceId = _ref.resourceId;
111
- return _this2.syncBlocks.delete(resourceId);
167
+ return _this3.syncBlocks.delete(resourceId);
112
168
  });
113
169
  }
114
170
  this.confirmationTransaction = undefined;
package/dist/esm/index.js CHANGED
@@ -6,5 +6,5 @@ export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemo
6
6
  export { getDefaultSyncBlockSchema } from './common/schema';
7
7
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluenceContentAPI';
8
8
  export { getConfluencePageAri } from './utils/ari';
9
- export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
9
+ export { convertSyncBlockPMNodeToSyncBlockData } from './utils/utils';
10
10
  export { rebaseTransaction } from './common/rebase-transaction';
@@ -23,6 +23,14 @@ export var getLocalIdFromAri = function getLocalIdFromAri(ari) {
23
23
  }
24
24
  throw new Error("Invalid page ARI: ".concat(ari));
25
25
  };
26
+ export var getPageARIFromResourceId = function getPageARIFromResourceId(resourceId) {
27
+ // eslint-disable-next-line require-unicode-regexp
28
+ var match = resourceId.match(/(ari:cloud:confluence:[^:]+:page\/\d+)\/([a-zA-Z0-9-]+)$/);
29
+ if (match !== null && match !== void 0 && match[1]) {
30
+ return match[1];
31
+ }
32
+ throw new Error("Invalid resourceId: ".concat(resourceId));
33
+ };
26
34
  export var getContentPropertyAri = function getContentPropertyAri(contentPropertyId, cloudId) {
27
35
  return "ari:cloud:confluence:".concat(cloudId, ":content/").concat(contentPropertyId);
28
36
  };
@@ -13,15 +13,4 @@ export var convertSyncBlockPMNodeToSyncBlockData = function convertSyncBlockPMNo
13
13
  },
14
14
  content: includeContent ? node.content.content.map(toJSON) : undefined
15
15
  };
16
- };
17
- export var generateSyncBlockSourceUrl = function generateSyncBlockSourceUrl(node) {
18
- var _node$attrs = node.attrs,
19
- localId = _node$attrs.localId,
20
- resourceId = _node$attrs.resourceId;
21
- // TODO: EDITOR-1644 - To be implemented under EDITOR-1644
22
- // below is a temporary implementation for the url generation
23
- var url = new URL(location.origin + location.pathname);
24
- url.searchParams.set('localId', localId);
25
- url.searchParams.set('resourceId', resourceId);
26
- return url.toString();
27
16
  };
@@ -9,9 +9,9 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
9
9
  private writeProvider;
10
10
  private sourceId;
11
11
  constructor(fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string);
12
- isNodeSupported: (node: JSONNode) => node is SyncBlockNode;
13
- nodeDataKey: (node: SyncBlockNode) => string;
14
- fetchNodesData: (nodes: SyncBlockNode[]) => Promise<SyncBlockData[]>;
12
+ isNodeSupported(node: JSONNode): node is SyncBlockNode;
13
+ nodeDataKey(node: SyncBlockNode): string;
14
+ fetchNodesData(nodes: SyncBlockNode[]): Promise<SyncBlockData[]>;
15
15
  /**
16
16
  *
17
17
  * @param nodes
@@ -19,8 +19,9 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
19
19
  *
20
20
  * @returns the resource ids of the nodes that were written
21
21
  */
22
- writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
23
- getSourceId: () => string;
22
+ writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<string | undefined>>;
23
+ getSourceId(): string;
24
+ retrieveSyncBlockSourceUrl(node: SyncBlockNode): Promise<string | undefined>;
24
25
  }
25
26
  export declare const useFetchDocNode: (editorView: EditorView, node: PMNode, defaultDocNode: DocNode, provider?: SyncBlockDataProvider) => DocNode;
26
27
  export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string) => SyncBlockProvider;
@@ -3,6 +3,7 @@ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { SyncBlockAttrs, SyncBlockDataProvider, SyncBlockNode } from './types';
6
+ type ResourceId = string;
6
7
  export interface SyncBlock {
7
8
  /**
8
9
  * The local content of the block,
@@ -11,6 +12,7 @@ export interface SyncBlock {
11
12
  content?: ADFEntity;
12
13
  resourceId: string;
13
14
  sourceLocalId: string;
15
+ sourceURL?: string;
14
16
  }
15
17
  type ConfirmationCallback = () => Promise<boolean>;
16
18
  export declare class SyncBlockStoreManager {
@@ -21,6 +23,18 @@ export declare class SyncBlockStoreManager {
21
23
  private confirmationTransaction?;
22
24
  private syncBlockNestedEditorView?;
23
25
  constructor(dataProvider?: SyncBlockDataProvider);
26
+ /**
27
+ * Add/update a sync block node to the store.
28
+ * @param node - The sync block node to add
29
+ * @returns True if the sync block node was added/updated
30
+ */
31
+ updateSyncBlockNode(node: PMNode): boolean;
32
+ /**
33
+ * Get the URL for a sync block.
34
+ * @param resourceId - The resource ID of the sync block to get the URL for
35
+ * @returns
36
+ */
37
+ getSyncBlockURL(resourceId: ResourceId): string | undefined;
24
38
  setEditorView(editorView: EditorView | undefined): void;
25
39
  setSyncBlockNestedEditorView(editorView: EditorView | undefined): void;
26
40
  getSyncBlockNestedEditorView(): EditorView | undefined;
@@ -28,6 +28,7 @@ export interface ADFWriteProvider {
28
28
  writeData: (data: SyncBlockData) => Promise<string>;
29
29
  }
30
30
  export declare abstract class SyncBlockDataProvider extends NodeDataProvider<SyncBlockNode, SyncBlockData> {
31
- abstract writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
32
- abstract getSourceId: () => string;
31
+ abstract writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<string | undefined>>;
32
+ abstract getSourceId(): string;
33
+ abstract retrieveSyncBlockSourceUrl(node: SyncBlockNode): Promise<string | undefined>;
33
34
  }
@@ -5,5 +5,5 @@ export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemo
5
5
  export { getDefaultSyncBlockSchema } from './common/schema';
6
6
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders, } from './providers/confluenceContentAPI';
7
7
  export { getConfluencePageAri } from './utils/ari';
8
- export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
8
+ export { convertSyncBlockPMNodeToSyncBlockData } from './utils/utils';
9
9
  export { rebaseTransaction } from './common/rebase-transaction';
@@ -6,6 +6,7 @@ export declare const getPageIdFromAri: (ari: string) => string;
6
6
  * @returns
7
7
  */
8
8
  export declare const getLocalIdFromAri: (ari: string) => string;
9
+ export declare const getPageARIFromResourceId: (resourceId: string) => string;
9
10
  export declare const getContentPropertyAri: (contentPropertyId: string, cloudId: string) => string;
10
11
  export declare const getContentPropertyIdFromAri: (ari: string) => string;
11
12
  export declare const resourceIdFromSourceAndLocalId: (sourceId: string, localId: string) => string;
@@ -1,4 +1,3 @@
1
1
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { SyncBlockNode } from '../common/types';
3
3
  export declare const convertSyncBlockPMNodeToSyncBlockData: (node: PMNode, includeContent?: boolean) => SyncBlockNode;
4
- export declare const generateSyncBlockSourceUrl: (node: PMNode) => string;
@@ -9,9 +9,9 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
9
9
  private writeProvider;
10
10
  private sourceId;
11
11
  constructor(fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string);
12
- isNodeSupported: (node: JSONNode) => node is SyncBlockNode;
13
- nodeDataKey: (node: SyncBlockNode) => string;
14
- fetchNodesData: (nodes: SyncBlockNode[]) => Promise<SyncBlockData[]>;
12
+ isNodeSupported(node: JSONNode): node is SyncBlockNode;
13
+ nodeDataKey(node: SyncBlockNode): string;
14
+ fetchNodesData(nodes: SyncBlockNode[]): Promise<SyncBlockData[]>;
15
15
  /**
16
16
  *
17
17
  * @param nodes
@@ -19,8 +19,9 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
19
19
  *
20
20
  * @returns the resource ids of the nodes that were written
21
21
  */
22
- writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
23
- getSourceId: () => string;
22
+ writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<string | undefined>>;
23
+ getSourceId(): string;
24
+ retrieveSyncBlockSourceUrl(node: SyncBlockNode): Promise<string | undefined>;
24
25
  }
25
26
  export declare const useFetchDocNode: (editorView: EditorView, node: PMNode, defaultDocNode: DocNode, provider?: SyncBlockDataProvider) => DocNode;
26
27
  export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string) => SyncBlockProvider;
@@ -3,6 +3,7 @@ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { SyncBlockAttrs, SyncBlockDataProvider, SyncBlockNode } from './types';
6
+ type ResourceId = string;
6
7
  export interface SyncBlock {
7
8
  /**
8
9
  * The local content of the block,
@@ -11,6 +12,7 @@ export interface SyncBlock {
11
12
  content?: ADFEntity;
12
13
  resourceId: string;
13
14
  sourceLocalId: string;
15
+ sourceURL?: string;
14
16
  }
15
17
  type ConfirmationCallback = () => Promise<boolean>;
16
18
  export declare class SyncBlockStoreManager {
@@ -21,6 +23,18 @@ export declare class SyncBlockStoreManager {
21
23
  private confirmationTransaction?;
22
24
  private syncBlockNestedEditorView?;
23
25
  constructor(dataProvider?: SyncBlockDataProvider);
26
+ /**
27
+ * Add/update a sync block node to the store.
28
+ * @param node - The sync block node to add
29
+ * @returns True if the sync block node was added/updated
30
+ */
31
+ updateSyncBlockNode(node: PMNode): boolean;
32
+ /**
33
+ * Get the URL for a sync block.
34
+ * @param resourceId - The resource ID of the sync block to get the URL for
35
+ * @returns
36
+ */
37
+ getSyncBlockURL(resourceId: ResourceId): string | undefined;
24
38
  setEditorView(editorView: EditorView | undefined): void;
25
39
  setSyncBlockNestedEditorView(editorView: EditorView | undefined): void;
26
40
  getSyncBlockNestedEditorView(): EditorView | undefined;
@@ -28,6 +28,7 @@ export interface ADFWriteProvider {
28
28
  writeData: (data: SyncBlockData) => Promise<string>;
29
29
  }
30
30
  export declare abstract class SyncBlockDataProvider extends NodeDataProvider<SyncBlockNode, SyncBlockData> {
31
- abstract writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
32
- abstract getSourceId: () => string;
31
+ abstract writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<string | undefined>>;
32
+ abstract getSourceId(): string;
33
+ abstract retrieveSyncBlockSourceUrl(node: SyncBlockNode): Promise<string | undefined>;
33
34
  }
@@ -5,5 +5,5 @@ export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemo
5
5
  export { getDefaultSyncBlockSchema } from './common/schema';
6
6
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders, } from './providers/confluenceContentAPI';
7
7
  export { getConfluencePageAri } from './utils/ari';
8
- export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
8
+ export { convertSyncBlockPMNodeToSyncBlockData } from './utils/utils';
9
9
  export { rebaseTransaction } from './common/rebase-transaction';
@@ -6,6 +6,7 @@ export declare const getPageIdFromAri: (ari: string) => string;
6
6
  * @returns
7
7
  */
8
8
  export declare const getLocalIdFromAri: (ari: string) => string;
9
+ export declare const getPageARIFromResourceId: (resourceId: string) => string;
9
10
  export declare const getContentPropertyAri: (contentPropertyId: string, cloudId: string) => string;
10
11
  export declare const getContentPropertyIdFromAri: (ari: string) => string;
11
12
  export declare const resourceIdFromSourceAndLocalId: (sourceId: string, localId: string) => string;
@@ -1,4 +1,3 @@
1
1
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { SyncBlockNode } from '../common/types';
3
3
  export declare const convertSyncBlockPMNodeToSyncBlockData: (node: PMNode, includeContent?: boolean) => SyncBlockNode;
4
- export declare const generateSyncBlockSourceUrl: (node: PMNode) => string;
package/package.json CHANGED
@@ -33,7 +33,7 @@
33
33
  "@atlaskit/primitives": "^15.0.0",
34
34
  "@atlaskit/tokens": "^6.5.0",
35
35
  "@babel/runtime": "^7.0.0",
36
- "@compiled/react": "^0.18.3",
36
+ "@compiled/react": "^0.18.6",
37
37
  "uuid": "^3.1.0"
38
38
  },
39
39
  "peerDependencies": {
@@ -82,7 +82,7 @@
82
82
  }
83
83
  },
84
84
  "name": "@atlaskit/editor-synced-block-provider",
85
- "version": "0.5.3",
85
+ "version": "0.6.0",
86
86
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
87
87
  "author": "Atlassian Pty Ltd",
88
88
  "license": "Apache-2.0",