@knotx/plugins-history 0.2.6 → 0.2.8

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/dist/index.cjs CHANGED
@@ -82,6 +82,9 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
82
82
  __publicField(this, "currentIndex", -1);
83
83
  __publicField(this, "isUndoRedo", false);
84
84
  __publicField(this, "maxHistory");
85
+ __publicField(this, "tagMap", /* @__PURE__ */ new Map());
86
+ __publicField(this, "operationBuffer", {});
87
+ __publicField(this, "operations$", new rxjs.Subject());
85
88
  __publicField(this, "canUndo", __runInitializers(_init, 8, this, false)), __runInitializers(_init, 11, this);
86
89
  __publicField(this, "canRedo", __runInitializers(_init, 12, this, false)), __runInitializers(_init, 15, this);
87
90
  __publicField(this, "ref", __runInitializers(_init, 16, this, this)), __runInitializers(_init, 19, this);
@@ -98,17 +101,32 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
98
101
  __publicField(this, "edgesManager", __runInitializers(_init, 28, this)), __runInitializers(_init, 31, this);
99
102
  __publicField(this, "dataManagers", /* @__PURE__ */ new Map());
100
103
  }
101
- init(config) {
102
- var _a2;
104
+ init(config = {}) {
105
+ var _a2, _b;
103
106
  this.maxHistory = (_a2 = config.maxHistory) != null ? _a2 : 50;
107
+ const debounceTimeConfig = (_b = config.debounceTime) != null ? _b : 20;
104
108
  this.dataManagers.set(this.nodesManager.tag, this.nodesManager);
105
109
  this.dataManagers.set(this.edgesManager.tag, this.edgesManager);
106
110
  this.dataManagers.forEach((dataManager) => {
107
111
  this.addOperationPipe(dataManager);
108
112
  });
113
+ this.subscriptions.push(
114
+ this.operations$.pipe(
115
+ rxjs.tap(([tag, operation]) => {
116
+ if (!this.operationBuffer[tag]) {
117
+ this.operationBuffer[tag] = [];
118
+ }
119
+ this.operationBuffer[tag].push(operation);
120
+ }),
121
+ rxjs.debounceTime(debounceTimeConfig)
122
+ ).subscribe(() => {
123
+ this.flushOperationBuffer();
124
+ })
125
+ );
109
126
  }
110
127
  destroy() {
111
128
  this.dataManagers.clear();
129
+ this.tagMap.clear();
112
130
  }
113
131
  addOperationPipe(dataManager) {
114
132
  dataManager.addDataOperationPipe({
@@ -119,17 +137,22 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
119
137
  }
120
138
  if (!this.isUndoRedo) {
121
139
  const enrichedOperation = this.enrichOperation(dataManager, operation);
122
- this.pushHistory({
123
- value: {
124
- [dataManager.tag]: [enrichedOperation]
125
- },
126
- timestamp: Date.now()
127
- });
140
+ this.operations$.next([dataManager.tag, enrichedOperation]);
128
141
  }
129
142
  })
130
143
  )
131
144
  });
132
145
  }
146
+ flushOperationBuffer() {
147
+ if (Object.keys(this.operationBuffer).length === 0) {
148
+ return;
149
+ }
150
+ this.pushHistory({
151
+ value: __spreadValues({}, this.operationBuffer),
152
+ timestamp: Date.now()
153
+ });
154
+ this.operationBuffer = {};
155
+ }
133
156
  enrichOperation(dataManager, operation) {
134
157
  switch (operation.type) {
135
158
  case "update": {
@@ -175,6 +198,7 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
175
198
  undo() {
176
199
  if (!this.canUndo)
177
200
  return;
201
+ this.flushOperationBufferImmediately();
178
202
  const state = this.history[this.currentIndex];
179
203
  this.isUndoRedo = true;
180
204
  try {
@@ -196,6 +220,7 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
196
220
  redo() {
197
221
  if (!this.canRedo)
198
222
  return;
223
+ this.flushOperationBufferImmediately();
199
224
  this.currentIndex++;
200
225
  const state = this.history[this.currentIndex];
201
226
  this.isUndoRedo = true;
@@ -214,6 +239,51 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
214
239
  this.isUndoRedo = false;
215
240
  }
216
241
  }
242
+ addTag(tag) {
243
+ this.flushOperationBufferImmediately();
244
+ this.tagMap.set(tag, this.history[this.currentIndex]);
245
+ }
246
+ removeTag(tag) {
247
+ this.tagMap.delete(tag);
248
+ }
249
+ toTag(tag) {
250
+ this.flushOperationBufferImmediately();
251
+ const tagIndex = this.ensureTagIndex(tag);
252
+ if (tagIndex === false) {
253
+ return;
254
+ }
255
+ if (this.currentIndex > tagIndex) {
256
+ let offset = this.currentIndex - tagIndex;
257
+ while (offset > 0) {
258
+ this.undo();
259
+ offset--;
260
+ }
261
+ } else if (this.currentIndex < tagIndex) {
262
+ let offset = tagIndex - this.currentIndex;
263
+ while (offset > 0) {
264
+ this.redo();
265
+ offset--;
266
+ }
267
+ }
268
+ }
269
+ clearTags() {
270
+ this.tagMap.clear();
271
+ }
272
+ ensureTagIndex(tag) {
273
+ if (!this.tagMap.has(tag)) {
274
+ return false;
275
+ }
276
+ const state = this.tagMap.get(tag);
277
+ if (typeof state === "undefined") {
278
+ return -1;
279
+ }
280
+ const stateIndex = this.history.indexOf(state);
281
+ if (stateIndex === -1) {
282
+ this.removeTag(tag);
283
+ return false;
284
+ }
285
+ return stateIndex;
286
+ }
217
287
  reverseOperation(dataManager, operation) {
218
288
  switch (operation.type) {
219
289
  case "add":
@@ -238,6 +308,12 @@ class History extends (_a = core.BasePlugin, _canUndo_dec = [decorators.register
238
308
  break;
239
309
  }
240
310
  }
311
+ /**
312
+ * 立即处理操作缓冲区,不等待 debounce
313
+ */
314
+ flushOperationBufferImmediately() {
315
+ this.flushOperationBuffer();
316
+ }
241
317
  }
242
318
  _init = __decoratorStart(_a);
243
319
  __decorateElement(_init, 1, "init", _init_dec, History);
package/dist/index.d.cts CHANGED
@@ -13,17 +13,23 @@ declare module '@knotx/core' {
13
13
  interface IHistory {
14
14
  undo: () => void;
15
15
  redo: () => void;
16
+ addTag: (tag: string) => void;
17
+ removeTag: (tag: string) => void;
18
+ toTag: (tag: string) => void;
19
+ clearTags: () => void;
16
20
  }
21
+ type HistoryOperation<T extends Record<string, IData>> = DataOperation<T[keyof T]> & {
22
+ originalData?: Partial<T[keyof T]>;
23
+ };
17
24
  interface HistoryState<T extends Record<string, IData> = Record<string, any>> {
18
25
  value: {
19
- [key: string]: Array<DataOperation<T[keyof T]> & {
20
- originalData?: Partial<T[keyof T]>;
21
- }>;
26
+ [key: string]: HistoryOperation<T>[];
22
27
  };
23
28
  timestamp: number;
24
29
  }
25
30
  interface HistoryConfig {
26
31
  maxHistory?: number;
32
+ debounceTime?: number;
27
33
  }
28
34
  declare class History<T extends Record<string, IData> = Record<string, any>> extends BasePlugin<'history', HistoryConfig> {
29
35
  name: "history";
@@ -31,6 +37,9 @@ declare class History<T extends Record<string, IData> = Record<string, any>> ext
31
37
  private currentIndex;
32
38
  private isUndoRedo;
33
39
  private maxHistory;
40
+ private tagMap;
41
+ private operationBuffer;
42
+ private operations$;
34
43
  canUndo: boolean;
35
44
  canRedo: boolean;
36
45
  ref: this;
@@ -38,15 +47,25 @@ declare class History<T extends Record<string, IData> = Record<string, any>> ext
38
47
  private nodesManager;
39
48
  private edgesManager;
40
49
  private dataManagers;
41
- init(config: HistoryConfig): void;
50
+ init(config?: HistoryConfig): void;
42
51
  destroy(): void;
43
52
  private addOperationPipe;
53
+ private flushOperationBuffer;
44
54
  private enrichOperation;
45
55
  private pushHistory;
46
56
  private updateCanUndoRedo;
47
57
  undo(): void;
48
58
  redo(): void;
59
+ addTag(tag: string): void;
60
+ removeTag(tag: string): void;
61
+ toTag(tag: string): void;
62
+ clearTags(): void;
63
+ private ensureTagIndex;
49
64
  private reverseOperation;
65
+ /**
66
+ * 立即处理操作缓冲区,不等待 debounce
67
+ */
68
+ private flushOperationBufferImmediately;
50
69
  }
51
70
 
52
- export { History, type HistoryConfig, type HistoryState, type IHistory };
71
+ export { History, type HistoryConfig, type HistoryOperation, type HistoryState, type IHistory };
package/dist/index.d.mts CHANGED
@@ -13,17 +13,23 @@ declare module '@knotx/core' {
13
13
  interface IHistory {
14
14
  undo: () => void;
15
15
  redo: () => void;
16
+ addTag: (tag: string) => void;
17
+ removeTag: (tag: string) => void;
18
+ toTag: (tag: string) => void;
19
+ clearTags: () => void;
16
20
  }
21
+ type HistoryOperation<T extends Record<string, IData>> = DataOperation<T[keyof T]> & {
22
+ originalData?: Partial<T[keyof T]>;
23
+ };
17
24
  interface HistoryState<T extends Record<string, IData> = Record<string, any>> {
18
25
  value: {
19
- [key: string]: Array<DataOperation<T[keyof T]> & {
20
- originalData?: Partial<T[keyof T]>;
21
- }>;
26
+ [key: string]: HistoryOperation<T>[];
22
27
  };
23
28
  timestamp: number;
24
29
  }
25
30
  interface HistoryConfig {
26
31
  maxHistory?: number;
32
+ debounceTime?: number;
27
33
  }
28
34
  declare class History<T extends Record<string, IData> = Record<string, any>> extends BasePlugin<'history', HistoryConfig> {
29
35
  name: "history";
@@ -31,6 +37,9 @@ declare class History<T extends Record<string, IData> = Record<string, any>> ext
31
37
  private currentIndex;
32
38
  private isUndoRedo;
33
39
  private maxHistory;
40
+ private tagMap;
41
+ private operationBuffer;
42
+ private operations$;
34
43
  canUndo: boolean;
35
44
  canRedo: boolean;
36
45
  ref: this;
@@ -38,15 +47,25 @@ declare class History<T extends Record<string, IData> = Record<string, any>> ext
38
47
  private nodesManager;
39
48
  private edgesManager;
40
49
  private dataManagers;
41
- init(config: HistoryConfig): void;
50
+ init(config?: HistoryConfig): void;
42
51
  destroy(): void;
43
52
  private addOperationPipe;
53
+ private flushOperationBuffer;
44
54
  private enrichOperation;
45
55
  private pushHistory;
46
56
  private updateCanUndoRedo;
47
57
  undo(): void;
48
58
  redo(): void;
59
+ addTag(tag: string): void;
60
+ removeTag(tag: string): void;
61
+ toTag(tag: string): void;
62
+ clearTags(): void;
63
+ private ensureTagIndex;
49
64
  private reverseOperation;
65
+ /**
66
+ * 立即处理操作缓冲区,不等待 debounce
67
+ */
68
+ private flushOperationBufferImmediately;
50
69
  }
51
70
 
52
- export { History, type HistoryConfig, type HistoryState, type IHistory };
71
+ export { History, type HistoryConfig, type HistoryOperation, type HistoryState, type IHistory };
package/dist/index.d.ts CHANGED
@@ -13,17 +13,23 @@ declare module '@knotx/core' {
13
13
  interface IHistory {
14
14
  undo: () => void;
15
15
  redo: () => void;
16
+ addTag: (tag: string) => void;
17
+ removeTag: (tag: string) => void;
18
+ toTag: (tag: string) => void;
19
+ clearTags: () => void;
16
20
  }
21
+ type HistoryOperation<T extends Record<string, IData>> = DataOperation<T[keyof T]> & {
22
+ originalData?: Partial<T[keyof T]>;
23
+ };
17
24
  interface HistoryState<T extends Record<string, IData> = Record<string, any>> {
18
25
  value: {
19
- [key: string]: Array<DataOperation<T[keyof T]> & {
20
- originalData?: Partial<T[keyof T]>;
21
- }>;
26
+ [key: string]: HistoryOperation<T>[];
22
27
  };
23
28
  timestamp: number;
24
29
  }
25
30
  interface HistoryConfig {
26
31
  maxHistory?: number;
32
+ debounceTime?: number;
27
33
  }
28
34
  declare class History<T extends Record<string, IData> = Record<string, any>> extends BasePlugin<'history', HistoryConfig> {
29
35
  name: "history";
@@ -31,6 +37,9 @@ declare class History<T extends Record<string, IData> = Record<string, any>> ext
31
37
  private currentIndex;
32
38
  private isUndoRedo;
33
39
  private maxHistory;
40
+ private tagMap;
41
+ private operationBuffer;
42
+ private operations$;
34
43
  canUndo: boolean;
35
44
  canRedo: boolean;
36
45
  ref: this;
@@ -38,15 +47,25 @@ declare class History<T extends Record<string, IData> = Record<string, any>> ext
38
47
  private nodesManager;
39
48
  private edgesManager;
40
49
  private dataManagers;
41
- init(config: HistoryConfig): void;
50
+ init(config?: HistoryConfig): void;
42
51
  destroy(): void;
43
52
  private addOperationPipe;
53
+ private flushOperationBuffer;
44
54
  private enrichOperation;
45
55
  private pushHistory;
46
56
  private updateCanUndoRedo;
47
57
  undo(): void;
48
58
  redo(): void;
59
+ addTag(tag: string): void;
60
+ removeTag(tag: string): void;
61
+ toTag(tag: string): void;
62
+ clearTags(): void;
63
+ private ensureTagIndex;
49
64
  private reverseOperation;
65
+ /**
66
+ * 立即处理操作缓冲区,不等待 debounce
67
+ */
68
+ private flushOperationBufferImmediately;
50
69
  }
51
70
 
52
- export { History, type HistoryConfig, type HistoryState, type IHistory };
71
+ export { History, type HistoryConfig, type HistoryOperation, type HistoryState, type IHistory };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isDraftOperation, isInitOperation, flattenOperations, BasePlugin } from '@knotx/core';
2
2
  import { register, inject, OnInit, OnDestroy } from '@knotx/decorators';
3
- import { pipe, tap } from 'rxjs';
3
+ import { Subject, tap, debounceTime, pipe } from 'rxjs';
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -80,6 +80,9 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
80
80
  __publicField(this, "currentIndex", -1);
81
81
  __publicField(this, "isUndoRedo", false);
82
82
  __publicField(this, "maxHistory");
83
+ __publicField(this, "tagMap", /* @__PURE__ */ new Map());
84
+ __publicField(this, "operationBuffer", {});
85
+ __publicField(this, "operations$", new Subject());
83
86
  __publicField(this, "canUndo", __runInitializers(_init, 8, this, false)), __runInitializers(_init, 11, this);
84
87
  __publicField(this, "canRedo", __runInitializers(_init, 12, this, false)), __runInitializers(_init, 15, this);
85
88
  __publicField(this, "ref", __runInitializers(_init, 16, this, this)), __runInitializers(_init, 19, this);
@@ -96,17 +99,32 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
96
99
  __publicField(this, "edgesManager", __runInitializers(_init, 28, this)), __runInitializers(_init, 31, this);
97
100
  __publicField(this, "dataManagers", /* @__PURE__ */ new Map());
98
101
  }
99
- init(config) {
100
- var _a2;
102
+ init(config = {}) {
103
+ var _a2, _b;
101
104
  this.maxHistory = (_a2 = config.maxHistory) != null ? _a2 : 50;
105
+ const debounceTimeConfig = (_b = config.debounceTime) != null ? _b : 20;
102
106
  this.dataManagers.set(this.nodesManager.tag, this.nodesManager);
103
107
  this.dataManagers.set(this.edgesManager.tag, this.edgesManager);
104
108
  this.dataManagers.forEach((dataManager) => {
105
109
  this.addOperationPipe(dataManager);
106
110
  });
111
+ this.subscriptions.push(
112
+ this.operations$.pipe(
113
+ tap(([tag, operation]) => {
114
+ if (!this.operationBuffer[tag]) {
115
+ this.operationBuffer[tag] = [];
116
+ }
117
+ this.operationBuffer[tag].push(operation);
118
+ }),
119
+ debounceTime(debounceTimeConfig)
120
+ ).subscribe(() => {
121
+ this.flushOperationBuffer();
122
+ })
123
+ );
107
124
  }
108
125
  destroy() {
109
126
  this.dataManagers.clear();
127
+ this.tagMap.clear();
110
128
  }
111
129
  addOperationPipe(dataManager) {
112
130
  dataManager.addDataOperationPipe({
@@ -117,17 +135,22 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
117
135
  }
118
136
  if (!this.isUndoRedo) {
119
137
  const enrichedOperation = this.enrichOperation(dataManager, operation);
120
- this.pushHistory({
121
- value: {
122
- [dataManager.tag]: [enrichedOperation]
123
- },
124
- timestamp: Date.now()
125
- });
138
+ this.operations$.next([dataManager.tag, enrichedOperation]);
126
139
  }
127
140
  })
128
141
  )
129
142
  });
130
143
  }
144
+ flushOperationBuffer() {
145
+ if (Object.keys(this.operationBuffer).length === 0) {
146
+ return;
147
+ }
148
+ this.pushHistory({
149
+ value: __spreadValues({}, this.operationBuffer),
150
+ timestamp: Date.now()
151
+ });
152
+ this.operationBuffer = {};
153
+ }
131
154
  enrichOperation(dataManager, operation) {
132
155
  switch (operation.type) {
133
156
  case "update": {
@@ -173,6 +196,7 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
173
196
  undo() {
174
197
  if (!this.canUndo)
175
198
  return;
199
+ this.flushOperationBufferImmediately();
176
200
  const state = this.history[this.currentIndex];
177
201
  this.isUndoRedo = true;
178
202
  try {
@@ -194,6 +218,7 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
194
218
  redo() {
195
219
  if (!this.canRedo)
196
220
  return;
221
+ this.flushOperationBufferImmediately();
197
222
  this.currentIndex++;
198
223
  const state = this.history[this.currentIndex];
199
224
  this.isUndoRedo = true;
@@ -212,6 +237,51 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
212
237
  this.isUndoRedo = false;
213
238
  }
214
239
  }
240
+ addTag(tag) {
241
+ this.flushOperationBufferImmediately();
242
+ this.tagMap.set(tag, this.history[this.currentIndex]);
243
+ }
244
+ removeTag(tag) {
245
+ this.tagMap.delete(tag);
246
+ }
247
+ toTag(tag) {
248
+ this.flushOperationBufferImmediately();
249
+ const tagIndex = this.ensureTagIndex(tag);
250
+ if (tagIndex === false) {
251
+ return;
252
+ }
253
+ if (this.currentIndex > tagIndex) {
254
+ let offset = this.currentIndex - tagIndex;
255
+ while (offset > 0) {
256
+ this.undo();
257
+ offset--;
258
+ }
259
+ } else if (this.currentIndex < tagIndex) {
260
+ let offset = tagIndex - this.currentIndex;
261
+ while (offset > 0) {
262
+ this.redo();
263
+ offset--;
264
+ }
265
+ }
266
+ }
267
+ clearTags() {
268
+ this.tagMap.clear();
269
+ }
270
+ ensureTagIndex(tag) {
271
+ if (!this.tagMap.has(tag)) {
272
+ return false;
273
+ }
274
+ const state = this.tagMap.get(tag);
275
+ if (typeof state === "undefined") {
276
+ return -1;
277
+ }
278
+ const stateIndex = this.history.indexOf(state);
279
+ if (stateIndex === -1) {
280
+ this.removeTag(tag);
281
+ return false;
282
+ }
283
+ return stateIndex;
284
+ }
215
285
  reverseOperation(dataManager, operation) {
216
286
  switch (operation.type) {
217
287
  case "add":
@@ -236,6 +306,12 @@ class History extends (_a = BasePlugin, _canUndo_dec = [register("canUndo")], _c
236
306
  break;
237
307
  }
238
308
  }
309
+ /**
310
+ * 立即处理操作缓冲区,不等待 debounce
311
+ */
312
+ flushOperationBufferImmediately() {
313
+ this.flushOperationBuffer();
314
+ }
239
315
  }
240
316
  _init = __decoratorStart(_a);
241
317
  __decorateElement(_init, 1, "init", _init_dec, History);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knotx/plugins-history",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "History Plugin for Knotx",
5
5
  "author": "boenfu",
6
6
  "license": "MIT",
@@ -29,13 +29,13 @@
29
29
  ],
30
30
  "dependencies": {
31
31
  "rxjs": "^7.8.1",
32
- "@knotx/core": "0.2.6",
33
- "@knotx/decorators": "0.2.6"
32
+ "@knotx/core": "0.2.7",
33
+ "@knotx/decorators": "0.2.7"
34
34
  },
35
35
  "devDependencies": {
36
- "@knotx/build-config": "0.2.6",
37
- "@knotx/eslint-config": "0.2.6",
38
- "@knotx/typescript-config": "0.2.6"
36
+ "@knotx/build-config": "0.2.7",
37
+ "@knotx/eslint-config": "0.2.7",
38
+ "@knotx/typescript-config": "0.2.7"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "unbuild",