@atlaskit/editor-synced-block-provider 0.1.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 +1 -0
- package/LICENSE.md +11 -0
- package/README.md +9 -0
- package/dist/cjs/common/syncBlockProvider.js +92 -0
- package/dist/cjs/common/syncBlockStoreManager.js +94 -0
- package/dist/cjs/common/types.js +23 -0
- package/dist/cjs/index.js +45 -0
- package/dist/cjs/providers/inMemory.js +26 -0
- package/dist/cjs/utils/utils.js +22 -0
- package/dist/es2019/common/syncBlockProvider.js +64 -0
- package/dist/es2019/common/syncBlockStoreManager.js +51 -0
- package/dist/es2019/common/types.js +2 -0
- package/dist/es2019/index.js +6 -0
- package/dist/es2019/providers/inMemory.js +20 -0
- package/dist/es2019/utils/utils.js +13 -0
- package/dist/esm/common/syncBlockProvider.js +85 -0
- package/dist/esm/common/syncBlockStoreManager.js +88 -0
- package/dist/esm/common/types.js +16 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/providers/inMemory.js +20 -0
- package/dist/esm/utils/utils.js +16 -0
- package/dist/types/common/syncBlockProvider.d.ts +24 -0
- package/dist/types/common/syncBlockStoreManager.d.ts +33 -0
- package/dist/types/common/types.d.ts +23 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/providers/inMemory.d.ts +3 -0
- package/dist/types/utils/utils.d.ts +3 -0
- package/dist/types-ts4.5/common/syncBlockProvider.d.ts +24 -0
- package/dist/types-ts4.5/common/syncBlockStoreManager.d.ts +33 -0
- package/dist/types-ts4.5/common/types.d.ts +23 -0
- package/dist/types-ts4.5/index.d.ts +5 -0
- package/dist/types-ts4.5/providers/inMemory.d.ts +3 -0
- package/dist/types-ts4.5/utils/utils.d.ts +3 -0
- package/package.json +91 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @atlaskit/editor-synced-block-provider
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright 2023 Atlassian Pty Ltd
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
|
4
|
+
compliance with the License. You may obtain a copy of the License at
|
|
5
|
+
|
|
6
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
|
|
8
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is
|
|
9
|
+
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
10
|
+
implied. See the License for the specific language governing permissions and limitations under the
|
|
11
|
+
License.
|
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# EditorSyncedBlockProvider
|
|
2
|
+
|
|
3
|
+
Synced Block Provider for @atlaskit/editor-plugin-synced-block
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
`import EditorSyncedBlockProvider from '@atlaskit/editor-synced-block-provider';`
|
|
8
|
+
|
|
9
|
+
Detailed docs and example usage can be found [here](https://atlaskit.atlassian.com/packages/editor/editor-synced-block-provider).
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useFetchDocNode = exports.SyncBlockProvider = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
12
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
13
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
14
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
15
|
+
var _react = require("react");
|
|
16
|
+
var _utils = require("../utils/utils");
|
|
17
|
+
var _types = require("./types");
|
|
18
|
+
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; }
|
|
19
|
+
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) { (0, _defineProperty2.default)(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; }
|
|
20
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
21
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
22
|
+
var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
|
|
23
|
+
function SyncBlockProvider(fetchProvider, writeProvider, sourceId) {
|
|
24
|
+
var _this;
|
|
25
|
+
(0, _classCallCheck2.default)(this, SyncBlockProvider);
|
|
26
|
+
_this = _callSuper(this, SyncBlockProvider);
|
|
27
|
+
(0, _defineProperty2.default)(_this, "name", 'syncBlockProvider');
|
|
28
|
+
(0, _defineProperty2.default)(_this, "isNodeSupported", function (node) {
|
|
29
|
+
return node.type === 'syncBlock';
|
|
30
|
+
});
|
|
31
|
+
(0, _defineProperty2.default)(_this, "nodeDataKey", function (node) {
|
|
32
|
+
return node.attrs.localId;
|
|
33
|
+
});
|
|
34
|
+
(0, _defineProperty2.default)(_this, "fetchNodesData", function (nodes) {
|
|
35
|
+
return Promise.all(nodes.map(function (node) {
|
|
36
|
+
return _this.fetchProvider.fetchData(node.attrs.resourceId);
|
|
37
|
+
}));
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param nodes
|
|
42
|
+
* @param data
|
|
43
|
+
*
|
|
44
|
+
* @returns the resource ids of the nodes that were written
|
|
45
|
+
*/
|
|
46
|
+
(0, _defineProperty2.default)(_this, "writeNodesData", function (nodes, data) {
|
|
47
|
+
var resourceIds = [];
|
|
48
|
+
nodes.forEach(function (node, index) {
|
|
49
|
+
if (!data[index].content) {
|
|
50
|
+
resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var resourceId = _this.writeProvider.writeData(_this.sourceId, node.attrs.localId, data[index].content, node.attrs.resourceId);
|
|
54
|
+
resourceIds.push(resourceId);
|
|
55
|
+
});
|
|
56
|
+
return Promise.all(resourceIds);
|
|
57
|
+
});
|
|
58
|
+
_this.fetchProvider = fetchProvider;
|
|
59
|
+
_this.writeProvider = writeProvider;
|
|
60
|
+
_this.sourceId = sourceId;
|
|
61
|
+
return _this;
|
|
62
|
+
}
|
|
63
|
+
(0, _inherits2.default)(SyncBlockProvider, _SyncBlockDataProvide);
|
|
64
|
+
return (0, _createClass2.default)(SyncBlockProvider);
|
|
65
|
+
}(_types.SyncBlockDataProvider);
|
|
66
|
+
var useFetchDocNode = exports.useFetchDocNode = function useFetchDocNode(editorView, node, defaultDocNode, provider) {
|
|
67
|
+
var _useState = (0, _react.useState)(defaultDocNode),
|
|
68
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
69
|
+
docNode = _useState2[0],
|
|
70
|
+
setDocNode = _useState2[1];
|
|
71
|
+
(0, _react.useEffect)(function () {
|
|
72
|
+
if (!provider) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
var interval = window.setInterval(function () {
|
|
76
|
+
var nodes = [(0, _utils.createSyncBlockNode)(node, false)];
|
|
77
|
+
provider === null || provider === void 0 || provider.fetchNodesData(nodes).then(function (data) {
|
|
78
|
+
var _data$;
|
|
79
|
+
if (data && (_data$ = data[0]) !== null && _data$ !== void 0 && _data$.content) {
|
|
80
|
+
var newNode = editorView.state.schema.nodeFromJSON(data[0].content);
|
|
81
|
+
setDocNode(_objectSpread(_objectSpread({}, newNode.toJSON()), {}, {
|
|
82
|
+
version: 1
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}, 1000);
|
|
87
|
+
return function () {
|
|
88
|
+
window.clearInterval(interval);
|
|
89
|
+
};
|
|
90
|
+
}, [editorView, node, provider]);
|
|
91
|
+
return docNode;
|
|
92
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.SyncBlockStoreManager = void 0;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
|
+
// Do this typedef to make it clear that
|
|
13
|
+
// this is a local identifier for a resource for local use
|
|
14
|
+
// A store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
15
|
+
// Supports create, read, update, and delete operations for sync blocks.
|
|
16
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
17
|
+
// Handles caching, debouncing updates, and publish/subscribe for local changes.
|
|
18
|
+
// Ensures consistency between local and remote state, and can be used in both editor and renderer contexts.
|
|
19
|
+
var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/function () {
|
|
20
|
+
function SyncBlockStoreManager(dataProvider) {
|
|
21
|
+
(0, _classCallCheck2.default)(this, SyncBlockStoreManager);
|
|
22
|
+
this.syncBlocks = new Map();
|
|
23
|
+
this.dataProvider = dataProvider;
|
|
24
|
+
}
|
|
25
|
+
return (0, _createClass2.default)(SyncBlockStoreManager, [{
|
|
26
|
+
key: "setEditorView",
|
|
27
|
+
value: function setEditorView(editorView) {
|
|
28
|
+
this.editorView = editorView;
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
key: "isSourceBlock",
|
|
32
|
+
value: function isSourceBlock(node) {
|
|
33
|
+
var _this$syncBlocks$get;
|
|
34
|
+
if (!this.dataProvider || node.type.name !== 'syncBlock') {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
var _node$attrs = node.attrs,
|
|
38
|
+
resourceId = _node$attrs.resourceId,
|
|
39
|
+
localId = _node$attrs.localId;
|
|
40
|
+
return this.syncBlocks.has(resourceId) && ((_this$syncBlocks$get = this.syncBlocks.get(resourceId)) === null || _this$syncBlocks$get === void 0 ? void 0 : _this$syncBlocks$get.sourceLocalId) === localId;
|
|
41
|
+
}
|
|
42
|
+
}, {
|
|
43
|
+
key: "registerConfirmationCallback",
|
|
44
|
+
value: function registerConfirmationCallback(callback) {
|
|
45
|
+
var _this = this;
|
|
46
|
+
this.confirmationCallback = callback;
|
|
47
|
+
return function () {
|
|
48
|
+
_this.confirmationCallback = undefined;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}, {
|
|
52
|
+
key: "requireConfirmationBeforeDelete",
|
|
53
|
+
value: function requireConfirmationBeforeDelete() {
|
|
54
|
+
return !!this.confirmationCallback;
|
|
55
|
+
}
|
|
56
|
+
}, {
|
|
57
|
+
key: "deleteSyncBlocksWithConfirmation",
|
|
58
|
+
value: function () {
|
|
59
|
+
var _deleteSyncBlocksWithConfirmation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(tr, syncBlockIds) {
|
|
60
|
+
var _this2 = this;
|
|
61
|
+
var confirmed, _this$editorView;
|
|
62
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
63
|
+
while (1) switch (_context.prev = _context.next) {
|
|
64
|
+
case 0:
|
|
65
|
+
if (!this.confirmationCallback) {
|
|
66
|
+
_context.next = 5;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
_context.next = 3;
|
|
70
|
+
return this.confirmationCallback();
|
|
71
|
+
case 3:
|
|
72
|
+
confirmed = _context.sent;
|
|
73
|
+
if (confirmed) {
|
|
74
|
+
// TODO: EDITOR-1779 - "rebase" the transaction to reflect the latest document state
|
|
75
|
+
(_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(tr.setMeta('isConfirmedSyncBlockDeletion', true));
|
|
76
|
+
// Need to update the BE on deletion
|
|
77
|
+
syncBlockIds.forEach(function (_ref) {
|
|
78
|
+
var resourceId = _ref.resourceId;
|
|
79
|
+
return _this2.syncBlocks.delete(resourceId);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
case 5:
|
|
83
|
+
case "end":
|
|
84
|
+
return _context.stop();
|
|
85
|
+
}
|
|
86
|
+
}, _callee, this);
|
|
87
|
+
}));
|
|
88
|
+
function deleteSyncBlocksWithConfirmation(_x, _x2) {
|
|
89
|
+
return _deleteSyncBlocksWithConfirmation.apply(this, arguments);
|
|
90
|
+
}
|
|
91
|
+
return deleteSyncBlocksWithConfirmation;
|
|
92
|
+
}()
|
|
93
|
+
}]);
|
|
94
|
+
}();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.SyncBlockDataProvider = void 0;
|
|
8
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
+
var _nodeDataProvider = require("@atlaskit/node-data-provider");
|
|
14
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
15
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
16
|
+
var SyncBlockDataProvider = exports.SyncBlockDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
17
|
+
function SyncBlockDataProvider() {
|
|
18
|
+
(0, _classCallCheck2.default)(this, SyncBlockDataProvider);
|
|
19
|
+
return _callSuper(this, SyncBlockDataProvider, arguments);
|
|
20
|
+
}
|
|
21
|
+
(0, _inherits2.default)(SyncBlockDataProvider, _NodeDataProvider);
|
|
22
|
+
return (0, _createClass2.default)(SyncBlockDataProvider);
|
|
23
|
+
}(_nodeDataProvider.NodeDataProvider);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "SyncBlockStoreManager", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _syncBlockStoreManager.SyncBlockStoreManager;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "SyncedBlockProvider", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _syncBlockProvider.SyncBlockProvider;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "createSyncBlockNode", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _utils.createSyncBlockNode;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "inMemoryFetchProvider", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function get() {
|
|
27
|
+
return _inMemory.inMemoryFetchProvider;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "inMemoryWriteProvider", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function get() {
|
|
33
|
+
return _inMemory.inMemoryWriteProvider;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "useFetchDocNode", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function get() {
|
|
39
|
+
return _syncBlockProvider.useFetchDocNode;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
var _syncBlockProvider = require("./common/syncBlockProvider");
|
|
43
|
+
var _syncBlockStoreManager = require("./common/syncBlockStoreManager");
|
|
44
|
+
var _inMemory = require("./providers/inMemory");
|
|
45
|
+
var _utils = require("./utils/utils");
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.inMemoryWriteProvider = exports.inMemoryFetchProvider = void 0;
|
|
7
|
+
var inMemStore = new Map();
|
|
8
|
+
var inMemoryFetchProvider = exports.inMemoryFetchProvider = {
|
|
9
|
+
fetchData: function fetchData(resourceId) {
|
|
10
|
+
return Promise.resolve({
|
|
11
|
+
content: inMemStore.get(resourceId)
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var inMemoryWriteProvider = exports.inMemoryWriteProvider = {
|
|
16
|
+
writeData: function writeData(_sourceId, _localId, data, resourceId) {
|
|
17
|
+
if (resourceId) {
|
|
18
|
+
inMemStore.set(resourceId, data);
|
|
19
|
+
return Promise.resolve(resourceId);
|
|
20
|
+
} else {
|
|
21
|
+
var uuid = crypto.randomUUID();
|
|
22
|
+
inMemStore.set(uuid, data);
|
|
23
|
+
return Promise.resolve(uuid);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createSyncBlockNode = void 0;
|
|
7
|
+
var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
|
|
8
|
+
var createSyncBlockNode = exports.createSyncBlockNode = function createSyncBlockNode(node) {
|
|
9
|
+
var includeContent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
10
|
+
var transformer = new _editorJsonTransformer.JSONTransformer();
|
|
11
|
+
var toJSON = function toJSON(node) {
|
|
12
|
+
return transformer.encodeNode(node);
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
type: 'syncBlock',
|
|
16
|
+
attrs: {
|
|
17
|
+
localId: node.attrs.localId,
|
|
18
|
+
resourceId: node.attrs.resourceId
|
|
19
|
+
},
|
|
20
|
+
content: includeContent ? node.content.content.map(toJSON) : undefined
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { createSyncBlockNode } from '../utils/utils';
|
|
4
|
+
import { SyncBlockDataProvider } from './types';
|
|
5
|
+
export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
6
|
+
constructor(fetchProvider, writeProvider, sourceId) {
|
|
7
|
+
super();
|
|
8
|
+
_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(this.sourceId, node.attrs.localId, data[index].content, node.attrs.resourceId);
|
|
31
|
+
resourceIds.push(resourceId);
|
|
32
|
+
});
|
|
33
|
+
return Promise.all(resourceIds);
|
|
34
|
+
});
|
|
35
|
+
this.fetchProvider = fetchProvider;
|
|
36
|
+
this.writeProvider = writeProvider;
|
|
37
|
+
this.sourceId = sourceId;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const useFetchDocNode = (editorView, node, defaultDocNode, provider) => {
|
|
41
|
+
const [docNode, setDocNode] = useState(defaultDocNode);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!provider) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const interval = window.setInterval(() => {
|
|
47
|
+
const nodes = [createSyncBlockNode(node, false)];
|
|
48
|
+
provider === null || provider === void 0 ? void 0 : provider.fetchNodesData(nodes).then(data => {
|
|
49
|
+
var _data$;
|
|
50
|
+
if (data && (_data$ = data[0]) !== null && _data$ !== void 0 && _data$.content) {
|
|
51
|
+
const newNode = editorView.state.schema.nodeFromJSON(data[0].content);
|
|
52
|
+
setDocNode({
|
|
53
|
+
...newNode.toJSON(),
|
|
54
|
+
version: 1
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}, 1000);
|
|
59
|
+
return () => {
|
|
60
|
+
window.clearInterval(interval);
|
|
61
|
+
};
|
|
62
|
+
}, [editorView, node, provider]);
|
|
63
|
+
return docNode;
|
|
64
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Do this typedef to make it clear that
|
|
2
|
+
// this is a local identifier for a resource for local use
|
|
3
|
+
|
|
4
|
+
// A store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
5
|
+
// Supports create, read, update, and delete operations for sync blocks.
|
|
6
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
7
|
+
// Handles caching, debouncing updates, and publish/subscribe for local changes.
|
|
8
|
+
// Ensures consistency between local and remote state, and can be used in both editor and renderer contexts.
|
|
9
|
+
export class SyncBlockStoreManager {
|
|
10
|
+
constructor(dataProvider) {
|
|
11
|
+
this.syncBlocks = new Map();
|
|
12
|
+
this.dataProvider = dataProvider;
|
|
13
|
+
}
|
|
14
|
+
setEditorView(editorView) {
|
|
15
|
+
this.editorView = editorView;
|
|
16
|
+
}
|
|
17
|
+
isSourceBlock(node) {
|
|
18
|
+
var _this$syncBlocks$get;
|
|
19
|
+
if (!this.dataProvider || node.type.name !== 'syncBlock') {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const {
|
|
23
|
+
resourceId,
|
|
24
|
+
localId
|
|
25
|
+
} = node.attrs;
|
|
26
|
+
return this.syncBlocks.has(resourceId) && ((_this$syncBlocks$get = this.syncBlocks.get(resourceId)) === null || _this$syncBlocks$get === void 0 ? void 0 : _this$syncBlocks$get.sourceLocalId) === localId;
|
|
27
|
+
}
|
|
28
|
+
registerConfirmationCallback(callback) {
|
|
29
|
+
this.confirmationCallback = callback;
|
|
30
|
+
return () => {
|
|
31
|
+
this.confirmationCallback = undefined;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
requireConfirmationBeforeDelete() {
|
|
35
|
+
return !!this.confirmationCallback;
|
|
36
|
+
}
|
|
37
|
+
async deleteSyncBlocksWithConfirmation(tr, syncBlockIds) {
|
|
38
|
+
if (this.confirmationCallback) {
|
|
39
|
+
const confirmed = await this.confirmationCallback();
|
|
40
|
+
if (confirmed) {
|
|
41
|
+
var _this$editorView;
|
|
42
|
+
// TODO: EDITOR-1779 - "rebase" the transaction to reflect the latest document state
|
|
43
|
+
(_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.dispatch(tr.setMeta('isConfirmedSyncBlockDeletion', true));
|
|
44
|
+
// Need to update the BE on deletion
|
|
45
|
+
syncBlockIds.forEach(({
|
|
46
|
+
resourceId
|
|
47
|
+
}) => this.syncBlocks.delete(resourceId));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/* eslint-disable @atlaskit/editor/no-re-export */
|
|
2
|
+
|
|
3
|
+
export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode } from './common/syncBlockProvider';
|
|
4
|
+
export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
|
|
5
|
+
export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
|
|
6
|
+
export { createSyncBlockNode } from './utils/utils';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const inMemStore = new Map();
|
|
2
|
+
export const inMemoryFetchProvider = {
|
|
3
|
+
fetchData: resourceId => {
|
|
4
|
+
return Promise.resolve({
|
|
5
|
+
content: inMemStore.get(resourceId)
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
export const inMemoryWriteProvider = {
|
|
10
|
+
writeData: (_sourceId, _localId, data, resourceId) => {
|
|
11
|
+
if (resourceId) {
|
|
12
|
+
inMemStore.set(resourceId, data);
|
|
13
|
+
return Promise.resolve(resourceId);
|
|
14
|
+
} else {
|
|
15
|
+
const uuid = crypto.randomUUID();
|
|
16
|
+
inMemStore.set(uuid, data);
|
|
17
|
+
return Promise.resolve(uuid);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { JSONTransformer } from "@atlaskit/editor-json-transformer";
|
|
2
|
+
export const createSyncBlockNode = (node, includeContent = false) => {
|
|
3
|
+
const transformer = new JSONTransformer();
|
|
4
|
+
const toJSON = node => transformer.encodeNode(node);
|
|
5
|
+
return {
|
|
6
|
+
type: 'syncBlock',
|
|
7
|
+
attrs: {
|
|
8
|
+
localId: node.attrs.localId,
|
|
9
|
+
resourceId: node.attrs.resourceId
|
|
10
|
+
},
|
|
11
|
+
content: includeContent ? node.content.content.map(toJSON) : undefined
|
|
12
|
+
};
|
|
13
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
4
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
5
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
6
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
7
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
8
|
+
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
|
+
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
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
11
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
12
|
+
import { useEffect, useState } from 'react';
|
|
13
|
+
import { createSyncBlockNode } from '../utils/utils';
|
|
14
|
+
import { SyncBlockDataProvider } from './types';
|
|
15
|
+
export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
|
|
16
|
+
function SyncBlockProvider(fetchProvider, writeProvider, sourceId) {
|
|
17
|
+
var _this;
|
|
18
|
+
_classCallCheck(this, SyncBlockProvider);
|
|
19
|
+
_this = _callSuper(this, SyncBlockProvider);
|
|
20
|
+
_defineProperty(_this, "name", 'syncBlockProvider');
|
|
21
|
+
_defineProperty(_this, "isNodeSupported", function (node) {
|
|
22
|
+
return node.type === 'syncBlock';
|
|
23
|
+
});
|
|
24
|
+
_defineProperty(_this, "nodeDataKey", function (node) {
|
|
25
|
+
return node.attrs.localId;
|
|
26
|
+
});
|
|
27
|
+
_defineProperty(_this, "fetchNodesData", function (nodes) {
|
|
28
|
+
return Promise.all(nodes.map(function (node) {
|
|
29
|
+
return _this.fetchProvider.fetchData(node.attrs.resourceId);
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param nodes
|
|
35
|
+
* @param data
|
|
36
|
+
*
|
|
37
|
+
* @returns the resource ids of the nodes that were written
|
|
38
|
+
*/
|
|
39
|
+
_defineProperty(_this, "writeNodesData", function (nodes, data) {
|
|
40
|
+
var resourceIds = [];
|
|
41
|
+
nodes.forEach(function (node, index) {
|
|
42
|
+
if (!data[index].content) {
|
|
43
|
+
resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
var resourceId = _this.writeProvider.writeData(_this.sourceId, node.attrs.localId, data[index].content, node.attrs.resourceId);
|
|
47
|
+
resourceIds.push(resourceId);
|
|
48
|
+
});
|
|
49
|
+
return Promise.all(resourceIds);
|
|
50
|
+
});
|
|
51
|
+
_this.fetchProvider = fetchProvider;
|
|
52
|
+
_this.writeProvider = writeProvider;
|
|
53
|
+
_this.sourceId = sourceId;
|
|
54
|
+
return _this;
|
|
55
|
+
}
|
|
56
|
+
_inherits(SyncBlockProvider, _SyncBlockDataProvide);
|
|
57
|
+
return _createClass(SyncBlockProvider);
|
|
58
|
+
}(SyncBlockDataProvider);
|
|
59
|
+
export var useFetchDocNode = function useFetchDocNode(editorView, node, defaultDocNode, provider) {
|
|
60
|
+
var _useState = useState(defaultDocNode),
|
|
61
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
62
|
+
docNode = _useState2[0],
|
|
63
|
+
setDocNode = _useState2[1];
|
|
64
|
+
useEffect(function () {
|
|
65
|
+
if (!provider) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
var interval = window.setInterval(function () {
|
|
69
|
+
var nodes = [createSyncBlockNode(node, false)];
|
|
70
|
+
provider === null || provider === void 0 || provider.fetchNodesData(nodes).then(function (data) {
|
|
71
|
+
var _data$;
|
|
72
|
+
if (data && (_data$ = data[0]) !== null && _data$ !== void 0 && _data$.content) {
|
|
73
|
+
var newNode = editorView.state.schema.nodeFromJSON(data[0].content);
|
|
74
|
+
setDocNode(_objectSpread(_objectSpread({}, newNode.toJSON()), {}, {
|
|
75
|
+
version: 1
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}, 1000);
|
|
80
|
+
return function () {
|
|
81
|
+
window.clearInterval(interval);
|
|
82
|
+
};
|
|
83
|
+
}, [editorView, node, provider]);
|
|
84
|
+
return docNode;
|
|
85
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
4
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
5
|
+
// Do this typedef to make it clear that
|
|
6
|
+
// this is a local identifier for a resource for local use
|
|
7
|
+
|
|
8
|
+
// A store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
9
|
+
// Supports create, read, update, and delete operations for sync blocks.
|
|
10
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
11
|
+
// Handles caching, debouncing updates, and publish/subscribe for local changes.
|
|
12
|
+
// Ensures consistency between local and remote state, and can be used in both editor and renderer contexts.
|
|
13
|
+
export var SyncBlockStoreManager = /*#__PURE__*/function () {
|
|
14
|
+
function SyncBlockStoreManager(dataProvider) {
|
|
15
|
+
_classCallCheck(this, SyncBlockStoreManager);
|
|
16
|
+
this.syncBlocks = new Map();
|
|
17
|
+
this.dataProvider = dataProvider;
|
|
18
|
+
}
|
|
19
|
+
return _createClass(SyncBlockStoreManager, [{
|
|
20
|
+
key: "setEditorView",
|
|
21
|
+
value: function setEditorView(editorView) {
|
|
22
|
+
this.editorView = editorView;
|
|
23
|
+
}
|
|
24
|
+
}, {
|
|
25
|
+
key: "isSourceBlock",
|
|
26
|
+
value: function isSourceBlock(node) {
|
|
27
|
+
var _this$syncBlocks$get;
|
|
28
|
+
if (!this.dataProvider || node.type.name !== 'syncBlock') {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
var _node$attrs = node.attrs,
|
|
32
|
+
resourceId = _node$attrs.resourceId,
|
|
33
|
+
localId = _node$attrs.localId;
|
|
34
|
+
return this.syncBlocks.has(resourceId) && ((_this$syncBlocks$get = this.syncBlocks.get(resourceId)) === null || _this$syncBlocks$get === void 0 ? void 0 : _this$syncBlocks$get.sourceLocalId) === localId;
|
|
35
|
+
}
|
|
36
|
+
}, {
|
|
37
|
+
key: "registerConfirmationCallback",
|
|
38
|
+
value: function registerConfirmationCallback(callback) {
|
|
39
|
+
var _this = this;
|
|
40
|
+
this.confirmationCallback = callback;
|
|
41
|
+
return function () {
|
|
42
|
+
_this.confirmationCallback = undefined;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}, {
|
|
46
|
+
key: "requireConfirmationBeforeDelete",
|
|
47
|
+
value: function requireConfirmationBeforeDelete() {
|
|
48
|
+
return !!this.confirmationCallback;
|
|
49
|
+
}
|
|
50
|
+
}, {
|
|
51
|
+
key: "deleteSyncBlocksWithConfirmation",
|
|
52
|
+
value: function () {
|
|
53
|
+
var _deleteSyncBlocksWithConfirmation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(tr, syncBlockIds) {
|
|
54
|
+
var _this2 = this;
|
|
55
|
+
var confirmed, _this$editorView;
|
|
56
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
57
|
+
while (1) switch (_context.prev = _context.next) {
|
|
58
|
+
case 0:
|
|
59
|
+
if (!this.confirmationCallback) {
|
|
60
|
+
_context.next = 5;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
_context.next = 3;
|
|
64
|
+
return this.confirmationCallback();
|
|
65
|
+
case 3:
|
|
66
|
+
confirmed = _context.sent;
|
|
67
|
+
if (confirmed) {
|
|
68
|
+
// TODO: EDITOR-1779 - "rebase" the transaction to reflect the latest document state
|
|
69
|
+
(_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(tr.setMeta('isConfirmedSyncBlockDeletion', true));
|
|
70
|
+
// Need to update the BE on deletion
|
|
71
|
+
syncBlockIds.forEach(function (_ref) {
|
|
72
|
+
var resourceId = _ref.resourceId;
|
|
73
|
+
return _this2.syncBlocks.delete(resourceId);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
case 5:
|
|
77
|
+
case "end":
|
|
78
|
+
return _context.stop();
|
|
79
|
+
}
|
|
80
|
+
}, _callee, this);
|
|
81
|
+
}));
|
|
82
|
+
function deleteSyncBlocksWithConfirmation(_x, _x2) {
|
|
83
|
+
return _deleteSyncBlocksWithConfirmation.apply(this, arguments);
|
|
84
|
+
}
|
|
85
|
+
return deleteSyncBlocksWithConfirmation;
|
|
86
|
+
}()
|
|
87
|
+
}]);
|
|
88
|
+
}();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
4
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
5
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
6
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
7
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
8
|
+
import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
9
|
+
export var SyncBlockDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
10
|
+
function SyncBlockDataProvider() {
|
|
11
|
+
_classCallCheck(this, SyncBlockDataProvider);
|
|
12
|
+
return _callSuper(this, SyncBlockDataProvider, arguments);
|
|
13
|
+
}
|
|
14
|
+
_inherits(SyncBlockDataProvider, _NodeDataProvider);
|
|
15
|
+
return _createClass(SyncBlockDataProvider);
|
|
16
|
+
}(NodeDataProvider);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/* eslint-disable @atlaskit/editor/no-re-export */
|
|
2
|
+
|
|
3
|
+
export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode } from './common/syncBlockProvider';
|
|
4
|
+
export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
|
|
5
|
+
export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
|
|
6
|
+
export { createSyncBlockNode } from './utils/utils';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
var inMemStore = new Map();
|
|
2
|
+
export var inMemoryFetchProvider = {
|
|
3
|
+
fetchData: function fetchData(resourceId) {
|
|
4
|
+
return Promise.resolve({
|
|
5
|
+
content: inMemStore.get(resourceId)
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
export var inMemoryWriteProvider = {
|
|
10
|
+
writeData: function writeData(_sourceId, _localId, data, resourceId) {
|
|
11
|
+
if (resourceId) {
|
|
12
|
+
inMemStore.set(resourceId, data);
|
|
13
|
+
return Promise.resolve(resourceId);
|
|
14
|
+
} else {
|
|
15
|
+
var uuid = crypto.randomUUID();
|
|
16
|
+
inMemStore.set(uuid, data);
|
|
17
|
+
return Promise.resolve(uuid);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { JSONTransformer } from "@atlaskit/editor-json-transformer";
|
|
2
|
+
export var createSyncBlockNode = function createSyncBlockNode(node) {
|
|
3
|
+
var includeContent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
4
|
+
var transformer = new JSONTransformer();
|
|
5
|
+
var toJSON = function toJSON(node) {
|
|
6
|
+
return transformer.encodeNode(node);
|
|
7
|
+
};
|
|
8
|
+
return {
|
|
9
|
+
type: 'syncBlock',
|
|
10
|
+
attrs: {
|
|
11
|
+
localId: node.attrs.localId,
|
|
12
|
+
resourceId: node.attrs.resourceId
|
|
13
|
+
},
|
|
14
|
+
content: includeContent ? node.content.content.map(toJSON) : undefined
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DocNode } from '@atlaskit/adf-schema';
|
|
2
|
+
import type { JSONNode } from '@atlaskit/editor-json-transformer/types';
|
|
3
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import { SyncBlockDataProvider, type ADFFetchProvider, type ADFWriteProvider, type SyncBlockData, type SyncBlockNode } from './types';
|
|
6
|
+
export declare class SyncBlockProvider extends SyncBlockDataProvider {
|
|
7
|
+
name: string;
|
|
8
|
+
private fetchProvider;
|
|
9
|
+
private writeProvider;
|
|
10
|
+
private sourceId;
|
|
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[]>;
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param nodes
|
|
18
|
+
* @param data
|
|
19
|
+
*
|
|
20
|
+
* @returns the resource ids of the nodes that were written
|
|
21
|
+
*/
|
|
22
|
+
writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
|
|
23
|
+
}
|
|
24
|
+
export declare const useFetchDocNode: (editorView: EditorView, node: PMNode, defaultDocNode: DocNode, provider?: SyncBlockProvider) => DocNode;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ADFEntity } from '@atlaskit/adf-utils/types';
|
|
2
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { SyncBlockDataProvider } from './types';
|
|
6
|
+
type ResourceId = string;
|
|
7
|
+
export interface SyncBlock {
|
|
8
|
+
/**
|
|
9
|
+
* The local content of the block,
|
|
10
|
+
* this might or might not be synced with the server
|
|
11
|
+
*/
|
|
12
|
+
content?: ADFEntity;
|
|
13
|
+
resourceId: string;
|
|
14
|
+
sourceLocalId: string;
|
|
15
|
+
}
|
|
16
|
+
type SyncBlockAttrs = {
|
|
17
|
+
localId: string;
|
|
18
|
+
resourceId: ResourceId;
|
|
19
|
+
};
|
|
20
|
+
type ConfirmationCallback = () => Promise<boolean>;
|
|
21
|
+
export declare class SyncBlockStoreManager {
|
|
22
|
+
private syncBlocks;
|
|
23
|
+
private dataProvider?;
|
|
24
|
+
private confirmationCallback?;
|
|
25
|
+
private editorView?;
|
|
26
|
+
constructor(dataProvider?: SyncBlockDataProvider);
|
|
27
|
+
setEditorView(editorView: EditorView | undefined): void;
|
|
28
|
+
isSourceBlock(node: PMNode): boolean;
|
|
29
|
+
registerConfirmationCallback(callback: ConfirmationCallback): () => void;
|
|
30
|
+
requireConfirmationBeforeDelete(): boolean;
|
|
31
|
+
deleteSyncBlocksWithConfirmation(tr: Transaction, syncBlockIds: SyncBlockAttrs[]): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ADFEntity } from '@atlaskit/adf-utils/types';
|
|
2
|
+
import type { JSONNode } from '@atlaskit/editor-json-transformer/types';
|
|
3
|
+
import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
4
|
+
export type SyncBlockNode = {
|
|
5
|
+
attrs: {
|
|
6
|
+
localId: string;
|
|
7
|
+
resourceId: string;
|
|
8
|
+
};
|
|
9
|
+
content?: Array<JSONNode>;
|
|
10
|
+
type: 'syncBlock';
|
|
11
|
+
};
|
|
12
|
+
export type SyncBlockData = {
|
|
13
|
+
content: ADFEntity | undefined;
|
|
14
|
+
};
|
|
15
|
+
export interface ADFFetchProvider {
|
|
16
|
+
fetchData: (resourceId: string) => Promise<SyncBlockData>;
|
|
17
|
+
}
|
|
18
|
+
export interface ADFWriteProvider {
|
|
19
|
+
writeData: (sourceId: string, localId: string, data: ADFEntity, resourceId?: string) => Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
export declare abstract class SyncBlockDataProvider extends NodeDataProvider<SyncBlockNode, SyncBlockData> {
|
|
22
|
+
abstract writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode } from './common/syncBlockProvider';
|
|
2
|
+
export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
|
|
3
|
+
export type { SyncBlockDataProvider, ADFFetchProvider, ADFWriteProvider, SyncBlockData, SyncBlockNode } from './common/types';
|
|
4
|
+
export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
|
|
5
|
+
export { createSyncBlockNode } from './utils/utils';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DocNode } from '@atlaskit/adf-schema';
|
|
2
|
+
import type { JSONNode } from '@atlaskit/editor-json-transformer/types';
|
|
3
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import { SyncBlockDataProvider, type ADFFetchProvider, type ADFWriteProvider, type SyncBlockData, type SyncBlockNode } from './types';
|
|
6
|
+
export declare class SyncBlockProvider extends SyncBlockDataProvider {
|
|
7
|
+
name: string;
|
|
8
|
+
private fetchProvider;
|
|
9
|
+
private writeProvider;
|
|
10
|
+
private sourceId;
|
|
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[]>;
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param nodes
|
|
18
|
+
* @param data
|
|
19
|
+
*
|
|
20
|
+
* @returns the resource ids of the nodes that were written
|
|
21
|
+
*/
|
|
22
|
+
writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
|
|
23
|
+
}
|
|
24
|
+
export declare const useFetchDocNode: (editorView: EditorView, node: PMNode, defaultDocNode: DocNode, provider?: SyncBlockProvider) => DocNode;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ADFEntity } from '@atlaskit/adf-utils/types';
|
|
2
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { SyncBlockDataProvider } from './types';
|
|
6
|
+
type ResourceId = string;
|
|
7
|
+
export interface SyncBlock {
|
|
8
|
+
/**
|
|
9
|
+
* The local content of the block,
|
|
10
|
+
* this might or might not be synced with the server
|
|
11
|
+
*/
|
|
12
|
+
content?: ADFEntity;
|
|
13
|
+
resourceId: string;
|
|
14
|
+
sourceLocalId: string;
|
|
15
|
+
}
|
|
16
|
+
type SyncBlockAttrs = {
|
|
17
|
+
localId: string;
|
|
18
|
+
resourceId: ResourceId;
|
|
19
|
+
};
|
|
20
|
+
type ConfirmationCallback = () => Promise<boolean>;
|
|
21
|
+
export declare class SyncBlockStoreManager {
|
|
22
|
+
private syncBlocks;
|
|
23
|
+
private dataProvider?;
|
|
24
|
+
private confirmationCallback?;
|
|
25
|
+
private editorView?;
|
|
26
|
+
constructor(dataProvider?: SyncBlockDataProvider);
|
|
27
|
+
setEditorView(editorView: EditorView | undefined): void;
|
|
28
|
+
isSourceBlock(node: PMNode): boolean;
|
|
29
|
+
registerConfirmationCallback(callback: ConfirmationCallback): () => void;
|
|
30
|
+
requireConfirmationBeforeDelete(): boolean;
|
|
31
|
+
deleteSyncBlocksWithConfirmation(tr: Transaction, syncBlockIds: SyncBlockAttrs[]): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ADFEntity } from '@atlaskit/adf-utils/types';
|
|
2
|
+
import type { JSONNode } from '@atlaskit/editor-json-transformer/types';
|
|
3
|
+
import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
4
|
+
export type SyncBlockNode = {
|
|
5
|
+
attrs: {
|
|
6
|
+
localId: string;
|
|
7
|
+
resourceId: string;
|
|
8
|
+
};
|
|
9
|
+
content?: Array<JSONNode>;
|
|
10
|
+
type: 'syncBlock';
|
|
11
|
+
};
|
|
12
|
+
export type SyncBlockData = {
|
|
13
|
+
content: ADFEntity | undefined;
|
|
14
|
+
};
|
|
15
|
+
export interface ADFFetchProvider {
|
|
16
|
+
fetchData: (resourceId: string) => Promise<SyncBlockData>;
|
|
17
|
+
}
|
|
18
|
+
export interface ADFWriteProvider {
|
|
19
|
+
writeData: (sourceId: string, localId: string, data: ADFEntity, resourceId?: string) => Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
export declare abstract class SyncBlockDataProvider extends NodeDataProvider<SyncBlockNode, SyncBlockData> {
|
|
22
|
+
abstract writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode } from './common/syncBlockProvider';
|
|
2
|
+
export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
|
|
3
|
+
export type { SyncBlockDataProvider, ADFFetchProvider, ADFWriteProvider, SyncBlockData, SyncBlockNode } from './common/types';
|
|
4
|
+
export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
|
|
5
|
+
export { createSyncBlockNode } from './utils/utils';
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"atlassian": {
|
|
3
|
+
"team": "Editor: Jenga",
|
|
4
|
+
"website": {
|
|
5
|
+
"name": "EditorSyncedBlockProvider",
|
|
6
|
+
"category": "Layout and structure"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"repository": "https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo",
|
|
10
|
+
"main": "dist/cjs/index.js",
|
|
11
|
+
"module": "dist/esm/index.js",
|
|
12
|
+
"module:es2019": "dist/es2019/index.js",
|
|
13
|
+
"types": "dist/types/index.d.ts",
|
|
14
|
+
"typesVersions": {
|
|
15
|
+
">=4.5 <5.9": {
|
|
16
|
+
"*": [
|
|
17
|
+
"dist/types-ts4.5/*",
|
|
18
|
+
"dist/types-ts4.5/index.d.ts"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": [
|
|
23
|
+
"*.compiled.css"
|
|
24
|
+
],
|
|
25
|
+
"atlaskit:src": "src/index.ts",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@atlaskit/adf-schema": "^51.2.0",
|
|
28
|
+
"@atlaskit/adf-utils": "^19.24.0",
|
|
29
|
+
"@atlaskit/css": "^0.14.0",
|
|
30
|
+
"@atlaskit/editor-json-transformer": "^8.30.0",
|
|
31
|
+
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
32
|
+
"@atlaskit/node-data-provider": "^6.4.0",
|
|
33
|
+
"@atlaskit/primitives": "^14.15.0",
|
|
34
|
+
"@atlaskit/tokens": "^6.3.0",
|
|
35
|
+
"@babel/runtime": "^7.0.0",
|
|
36
|
+
"@compiled/react": "^0.18.3"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^18.2.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@af/integration-testing": "workspace:^",
|
|
43
|
+
"@af/visual-regression": "workspace:^",
|
|
44
|
+
"@atlaskit/ssr": "workspace:^",
|
|
45
|
+
"@testing-library/react": "^13.4.0",
|
|
46
|
+
"react-dom": "^18.2.0"
|
|
47
|
+
},
|
|
48
|
+
"techstack": {
|
|
49
|
+
"@atlassian/frontend": {
|
|
50
|
+
"import-structure": [
|
|
51
|
+
"atlassian-conventions"
|
|
52
|
+
],
|
|
53
|
+
"circular-dependencies": [
|
|
54
|
+
"file-and-folder-level"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"@repo/internal": {
|
|
58
|
+
"dom-events": "use-bind-event-listener",
|
|
59
|
+
"analytics": [
|
|
60
|
+
"analytics-next"
|
|
61
|
+
],
|
|
62
|
+
"design-tokens": [
|
|
63
|
+
"color"
|
|
64
|
+
],
|
|
65
|
+
"theming": [
|
|
66
|
+
"react-context"
|
|
67
|
+
],
|
|
68
|
+
"ui-components": [
|
|
69
|
+
"lite-mode"
|
|
70
|
+
],
|
|
71
|
+
"deprecation": [
|
|
72
|
+
"no-deprecated-imports"
|
|
73
|
+
],
|
|
74
|
+
"styling": [
|
|
75
|
+
"static",
|
|
76
|
+
"compiled"
|
|
77
|
+
],
|
|
78
|
+
"imports": [
|
|
79
|
+
"import-no-extraneous-disable-for-examples-and-docs"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"name": "@atlaskit/editor-synced-block-provider",
|
|
84
|
+
"version": "0.1.0",
|
|
85
|
+
"description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
|
|
86
|
+
"author": "Atlassian Pty Ltd",
|
|
87
|
+
"license": "Apache-2.0",
|
|
88
|
+
"publishConfig": {
|
|
89
|
+
"registry": "https://registry.npmjs.org/"
|
|
90
|
+
}
|
|
91
|
+
}
|