@opendaw/lib-box 0.0.80 → 0.0.81
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/editing.d.ts.map +1 -1
- package/dist/editing.js +72 -29
- package/dist/graph-edges.d.ts +3 -0
- package/dist/graph-edges.d.ts.map +1 -1
- package/dist/graph-edges.js +48 -1
- package/dist/graph.d.ts +4 -3
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +118 -28
- package/dist/sync-source.d.ts.map +1 -1
- package/dist/sync-source.js +5 -1
- package/package.json +4 -4
package/dist/editing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editing.d.ts","sourceRoot":"","sources":["../src/editing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAA;AAChC,OAAO,EAGH,OAAO,EAEP,KAAK,EAEL,QAAQ,EACR,MAAM,
|
|
1
|
+
{"version":3,"file":"editing.d.ts","sourceRoot":"","sources":["../src/editing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAA;AAChC,OAAO,EAGH,OAAO,EAEP,KAAK,EAEL,QAAQ,EACR,MAAM,EAEN,YAAY,EACZ,YAAY,EAGf,MAAM,kBAAkB,CAAA;AAiDzB,MAAM,WAAW,mBAAmB;IAChC,OAAO,IAAI,IAAI,CAAA;IACf,MAAM,IAAI,IAAI,CAAA;CACjB;AAED,qBAAa,UAAW,YAAW,OAAO;;gBAY1B,KAAK,EAAE,QAAQ;IAM3B,IAAI,KAAK,IAAI,QAAQ,CAAqB;IAE1C,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY;IAIjD,SAAS,IAAI,IAAI;IAKjB,iBAAiB,IAAI,OAAO;IAM5B,YAAY,IAAI,OAAO;IAEvB,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,OAAO;IAsBf,IAAI,IAAI,OAAO;IAoBf,OAAO,IAAI,OAAO;IAKlB,OAAO,IAAI,OAAO;IAMlB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,OAAc,GAAG,MAAM,CAAC,CAAC,CAAC;IAiC5E,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAoDtD,iBAAiB,IAAI,mBAAmB;IAoCxC,IAAI,IAAI,IAAI;IAYZ,aAAa,IAAI,IAAI;IAOrB,OAAO,IAAI,IAAI;CAGlB"}
|
package/dist/editing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Arrays, assert, Notifier, Option, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { Arrays, assert, Notifier, Option, RuntimeNotifier, tryCatch, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { DeleteUpdate, NewUpdate, PointerUpdate, PrimitiveUpdate } from "./updates";
|
|
3
3
|
// Removes updates for boxes that were created AND deleted in the same transaction.
|
|
4
4
|
const optimizeUpdates = (updates) => {
|
|
@@ -96,8 +96,21 @@ export class BoxEditing {
|
|
|
96
96
|
}
|
|
97
97
|
console.debug("undo");
|
|
98
98
|
const modifications = this.#marked[--this.#historyIndex];
|
|
99
|
-
modifications.toReversed()
|
|
100
|
-
|
|
99
|
+
const reversed = modifications.toReversed();
|
|
100
|
+
const applied = [];
|
|
101
|
+
for (const step of reversed) {
|
|
102
|
+
const result = tryCatch(() => step.inverse(this.#graph));
|
|
103
|
+
if (result.status === "failure") {
|
|
104
|
+
if (this.#graph.inTransaction()) {
|
|
105
|
+
this.#graph.abortTransaction();
|
|
106
|
+
}
|
|
107
|
+
applied.toReversed().forEach(completed => completed.forward(this.#graph));
|
|
108
|
+
this.#historyIndex++;
|
|
109
|
+
RuntimeNotifier.info({ headline: "Undo Failed", message: "This history step is no longer valid due to changes from other participants." });
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
applied.push(step);
|
|
113
|
+
}
|
|
101
114
|
this.#notifier.notify();
|
|
102
115
|
return true;
|
|
103
116
|
}
|
|
@@ -106,8 +119,21 @@ export class BoxEditing {
|
|
|
106
119
|
return false;
|
|
107
120
|
}
|
|
108
121
|
console.debug("redo");
|
|
109
|
-
this.#marked[this.#historyIndex++]
|
|
110
|
-
|
|
122
|
+
const modifications = this.#marked[this.#historyIndex++];
|
|
123
|
+
const applied = [];
|
|
124
|
+
for (const step of modifications) {
|
|
125
|
+
const result = tryCatch(() => step.forward(this.#graph));
|
|
126
|
+
if (result.status === "failure") {
|
|
127
|
+
if (this.#graph.inTransaction()) {
|
|
128
|
+
this.#graph.abortTransaction();
|
|
129
|
+
}
|
|
130
|
+
applied.toReversed().forEach(completed => completed.inverse(this.#graph));
|
|
131
|
+
this.#historyIndex--;
|
|
132
|
+
RuntimeNotifier.info({ headline: "Redo Failed", message: "This history step is no longer valid due to changes from other participants." });
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
applied.push(step);
|
|
136
|
+
}
|
|
111
137
|
this.#notifier.notify();
|
|
112
138
|
return true;
|
|
113
139
|
}
|
|
@@ -129,7 +155,6 @@ export class BoxEditing {
|
|
|
129
155
|
modify(modifier, mark = true) {
|
|
130
156
|
assert(!this.#inProcess, "Cannot call modify while a modification process is running");
|
|
131
157
|
if (this.#modifying || this.#graph.inTransaction()) {
|
|
132
|
-
// Nested modify call or reactive call during undo/redo — just execute without separate recording
|
|
133
158
|
this.#notifier.notify();
|
|
134
159
|
return Option.wrap(modifier());
|
|
135
160
|
}
|
|
@@ -141,21 +166,29 @@ export class BoxEditing {
|
|
|
141
166
|
const subscription = this.#graph.subscribeToAllUpdates({
|
|
142
167
|
onUpdate: (update) => updates.push(update)
|
|
143
168
|
});
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
const result = tryCatch(() => {
|
|
170
|
+
this.#graph.beginTransaction();
|
|
171
|
+
const result = modifier();
|
|
172
|
+
this.#graph.endTransaction();
|
|
173
|
+
return result;
|
|
174
|
+
});
|
|
147
175
|
subscription.terminate();
|
|
176
|
+
this.#modifying = false;
|
|
177
|
+
if (result.status === "failure") {
|
|
178
|
+
if (this.#graph.inTransaction()) {
|
|
179
|
+
this.#graph.abortTransaction();
|
|
180
|
+
}
|
|
181
|
+
throw result.error;
|
|
182
|
+
}
|
|
148
183
|
const optimized = optimizeUpdates(updates);
|
|
149
184
|
if (optimized.length > 0) {
|
|
150
185
|
this.#pending.push(new Modification(optimized));
|
|
151
186
|
}
|
|
152
|
-
this.#modifying = false;
|
|
153
|
-
this.#graph.edges().validateRequirements();
|
|
154
187
|
if (mark) {
|
|
155
188
|
this.mark();
|
|
156
189
|
}
|
|
157
190
|
this.#notifier.notify();
|
|
158
|
-
return Option.wrap(result);
|
|
191
|
+
return Option.wrap(result.value);
|
|
159
192
|
}
|
|
160
193
|
append(modifier) {
|
|
161
194
|
assert(!this.#inProcess, "Cannot call append while a modification process is running");
|
|
@@ -177,10 +210,20 @@ export class BoxEditing {
|
|
|
177
210
|
const subscription = this.#graph.subscribeToAllUpdates({
|
|
178
211
|
onUpdate: (update) => updates.push(update)
|
|
179
212
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
213
|
+
const result = tryCatch(() => {
|
|
214
|
+
this.#graph.beginTransaction();
|
|
215
|
+
const result = modifier();
|
|
216
|
+
this.#graph.endTransaction();
|
|
217
|
+
return result;
|
|
218
|
+
});
|
|
183
219
|
subscription.terminate();
|
|
220
|
+
this.#modifying = false;
|
|
221
|
+
if (result.status === "failure") {
|
|
222
|
+
if (this.#graph.inTransaction()) {
|
|
223
|
+
this.#graph.abortTransaction();
|
|
224
|
+
}
|
|
225
|
+
throw result.error;
|
|
226
|
+
}
|
|
184
227
|
const optimized = optimizeUpdates(updates);
|
|
185
228
|
if (optimized.length > 0) {
|
|
186
229
|
const modification = new Modification(optimized);
|
|
@@ -199,10 +242,8 @@ export class BoxEditing {
|
|
|
199
242
|
this.#historyIndex = this.#marked.length;
|
|
200
243
|
}
|
|
201
244
|
}
|
|
202
|
-
this.#modifying = false;
|
|
203
|
-
this.#graph.edges().validateRequirements();
|
|
204
245
|
this.#notifier.notify();
|
|
205
|
-
return Option.wrap(result);
|
|
246
|
+
return Option.wrap(result.value);
|
|
206
247
|
}
|
|
207
248
|
beginModification() {
|
|
208
249
|
assert(!this.#modifying && !this.#inProcess, "Cannot begin modification while another is in progress");
|
|
@@ -213,27 +254,29 @@ export class BoxEditing {
|
|
|
213
254
|
onUpdate: (update) => updates.push(update)
|
|
214
255
|
});
|
|
215
256
|
this.#graph.beginTransaction();
|
|
257
|
+
const cleanup = () => {
|
|
258
|
+
subscription.terminate();
|
|
259
|
+
this.#modifying = false;
|
|
260
|
+
this.#inProcess = false;
|
|
261
|
+
};
|
|
216
262
|
return {
|
|
217
263
|
approve: () => {
|
|
218
|
-
this.#graph.endTransaction();
|
|
219
|
-
|
|
264
|
+
const result = tryCatch(() => this.#graph.endTransaction());
|
|
265
|
+
cleanup();
|
|
266
|
+
if (result.status === "failure") {
|
|
267
|
+
throw result.error;
|
|
268
|
+
}
|
|
220
269
|
const optimized = optimizeUpdates(updates);
|
|
221
270
|
if (optimized.length > 0) {
|
|
222
271
|
this.#pending.push(new Modification(optimized));
|
|
223
272
|
}
|
|
224
|
-
this.#modifying = false;
|
|
225
|
-
this.#inProcess = false;
|
|
226
|
-
this.#graph.edges().validateRequirements();
|
|
227
273
|
this.mark();
|
|
228
274
|
this.#notifier.notify();
|
|
229
275
|
},
|
|
230
276
|
revert: () => {
|
|
231
|
-
this.#graph.endTransaction();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
this.#inProcess = false;
|
|
235
|
-
this.#graph.edges().validateRequirements();
|
|
236
|
-
if (updates.length > 0) {
|
|
277
|
+
const result = tryCatch(() => this.#graph.endTransaction());
|
|
278
|
+
cleanup();
|
|
279
|
+
if (result.status === "success" && updates.length > 0) {
|
|
237
280
|
new Modification(updates).inverse(this.#graph);
|
|
238
281
|
}
|
|
239
282
|
}
|
package/dist/graph-edges.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Option } from "@opendaw/lib-std";
|
|
1
2
|
import { Address } from "./address";
|
|
2
3
|
import { PointerField } from "./pointer";
|
|
3
4
|
import { Vertex } from "./vertex";
|
|
@@ -12,6 +13,8 @@ export declare class GraphEdges {
|
|
|
12
13
|
isConnected(source: PointerField, target: Address): boolean;
|
|
13
14
|
outgoingEdgesOf(box: Box): ReadonlyArray<[PointerField, Address]>;
|
|
14
15
|
incomingEdgesOf(vertex: Box | Vertex): ReadonlyArray<PointerField>;
|
|
16
|
+
clearAffected(): void;
|
|
17
|
+
tryValidateAffected(): Option<Error>;
|
|
15
18
|
validateRequirements(): void;
|
|
16
19
|
}
|
|
17
20
|
//# sourceMappingURL=graph-edges.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-edges.d.ts","sourceRoot":"","sources":["../src/graph-edges.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph-edges.d.ts","sourceRoot":"","sources":["../src/graph-edges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,MAAM,EAAyB,MAAM,kBAAkB,CAAA;AACtG,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAEzB,qBAAa,UAAU;;;IAiBnB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAqBhD,iBAAiB,CAAC,GAAG,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;IAqBrD,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAUpD,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAStC,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO;IAI3D,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,aAAa,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAIjE,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC;IASlE,aAAa,IAAI,IAAI;IAErB,mBAAmB,IAAI,MAAM,CAAC,KAAK,CAAC;IAsCpC,oBAAoB,IAAI,IAAI;CAgD/B"}
|
package/dist/graph-edges.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Arrays, isDefined, isInstanceOf, panic } from "@opendaw/lib-std";
|
|
1
|
+
import { Arrays, isDefined, isInstanceOf, Option, panic, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { Address } from "./address";
|
|
3
3
|
import { PointerField } from "./pointer";
|
|
4
4
|
export class GraphEdges {
|
|
@@ -7,12 +7,14 @@ export class GraphEdges {
|
|
|
7
7
|
#requiresExclusive;
|
|
8
8
|
#incoming;
|
|
9
9
|
#outgoing;
|
|
10
|
+
#affected;
|
|
10
11
|
constructor() {
|
|
11
12
|
this.#requiresTarget = Address.newSet(source => source.address);
|
|
12
13
|
this.#requiresPointer = Address.newSet(vertex => vertex.address);
|
|
13
14
|
this.#requiresExclusive = Address.newSet(vertex => vertex.address);
|
|
14
15
|
this.#incoming = Address.newSet(([address]) => address);
|
|
15
16
|
this.#outgoing = Address.newSet(([source]) => source.address);
|
|
17
|
+
this.#affected = UUID.newSet(uuid => uuid);
|
|
16
18
|
}
|
|
17
19
|
watchVertex(vertex) {
|
|
18
20
|
if (isInstanceOf(vertex, PointerField)) {
|
|
@@ -33,6 +35,7 @@ export class GraphEdges {
|
|
|
33
35
|
this.#requiresExclusive.add(vertex);
|
|
34
36
|
}
|
|
35
37
|
}
|
|
38
|
+
this.#affected.add(vertex.address.uuid);
|
|
36
39
|
}
|
|
37
40
|
unwatchVerticesOf(...boxes) {
|
|
38
41
|
const map = ({ box: { address: { uuid } } }) => uuid;
|
|
@@ -58,6 +61,8 @@ export class GraphEdges {
|
|
|
58
61
|
none: () => this.#incoming.add([target, [source]]),
|
|
59
62
|
some: ([, sources]) => sources.push(source)
|
|
60
63
|
});
|
|
64
|
+
this.#affected.add(source.address.uuid);
|
|
65
|
+
this.#affected.add(target.uuid);
|
|
61
66
|
}
|
|
62
67
|
disconnect(source) {
|
|
63
68
|
const [, target] = this.#outgoing.removeByKey(source.address);
|
|
@@ -66,6 +71,8 @@ export class GraphEdges {
|
|
|
66
71
|
if (sources.length === 0) {
|
|
67
72
|
this.#incoming.removeByKey(target);
|
|
68
73
|
}
|
|
74
|
+
this.#affected.add(source.address.uuid);
|
|
75
|
+
this.#affected.add(target.uuid);
|
|
69
76
|
}
|
|
70
77
|
isConnected(source, target) {
|
|
71
78
|
return this.#outgoing.opt(source.address).mapOr(([, actualTarget]) => actualTarget.equals(target), false);
|
|
@@ -82,6 +89,46 @@ export class GraphEdges {
|
|
|
82
89
|
return this.#incoming.opt(vertex.address).mapOr(([_, pointers]) => pointers, Arrays.empty());
|
|
83
90
|
}
|
|
84
91
|
}
|
|
92
|
+
clearAffected() { this.#affected.clear(); }
|
|
93
|
+
tryValidateAffected() {
|
|
94
|
+
const map = ({ box: { address: { uuid } } }) => uuid;
|
|
95
|
+
for (const uuid of this.#affected.values()) {
|
|
96
|
+
const pointers = this.#collectSameBox(this.#requiresTarget, uuid, map);
|
|
97
|
+
for (const pointer of pointers) {
|
|
98
|
+
if (pointer.isEmpty()) {
|
|
99
|
+
this.#affected.clear();
|
|
100
|
+
if (pointer.mandatory) {
|
|
101
|
+
return Option.wrap(new Error(`Pointer ${pointer.toString()} requires an edge.`));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return Option.wrap(new Error(`Illegal state: ${pointer} has no edge requirements.`));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const targets = this.#collectSameBox(this.#requiresPointer, uuid, map);
|
|
109
|
+
for (const target of targets) {
|
|
110
|
+
if (target.pointerHub.isEmpty()) {
|
|
111
|
+
this.#affected.clear();
|
|
112
|
+
if (target.pointerRules.mandatory) {
|
|
113
|
+
return Option.wrap(new Error(`Target ${target.toString()} requires an edge.`));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return Option.wrap(new Error(`Illegal state: ${target} has no edge requirements.`));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const exclusives = this.#collectSameBox(this.#requiresExclusive, uuid, map);
|
|
121
|
+
for (const target of exclusives) {
|
|
122
|
+
const count = target.pointerHub.size();
|
|
123
|
+
if (count > 1) {
|
|
124
|
+
this.#affected.clear();
|
|
125
|
+
return Option.wrap(new Error(`Target ${target.toString()} is exclusive but has ${count} incoming pointers.`));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
this.#affected.clear();
|
|
130
|
+
return Option.None;
|
|
131
|
+
}
|
|
85
132
|
validateRequirements() {
|
|
86
133
|
// TODO I removed the assertions because they were too slow in busy graphs.
|
|
87
134
|
// I tried to use a Set<Box> in BoxGraph, but that wasn't faster than the SortedSet.
|
package/dist/graph.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { GraphEdges } from "./graph-edges";
|
|
|
10
10
|
export type BoxFactory<BoxMap> = (name: keyof BoxMap, graph: BoxGraph<BoxMap>, uuid: UUID.Bytes, constructor: Procedure<Box>) => Box;
|
|
11
11
|
export interface TransactionListener {
|
|
12
12
|
onBeginTransaction(): void;
|
|
13
|
-
onEndTransaction(): void;
|
|
13
|
+
onEndTransaction(rolledBack: boolean): void;
|
|
14
14
|
}
|
|
15
15
|
export interface UpdateListener {
|
|
16
16
|
onUpdate(update: Update): void;
|
|
@@ -23,6 +23,7 @@ export declare class BoxGraph<BoxMap = any> {
|
|
|
23
23
|
#private;
|
|
24
24
|
constructor(boxFactory?: Option<BoxFactory<BoxMap>>);
|
|
25
25
|
beginTransaction(): void;
|
|
26
|
+
abortTransaction(): void;
|
|
26
27
|
endTransaction(): void;
|
|
27
28
|
inTransaction(): boolean;
|
|
28
29
|
constructingBox(): boolean;
|
|
@@ -55,8 +56,8 @@ export declare class BoxGraph<BoxMap = any> {
|
|
|
55
56
|
debugDependencies(): void;
|
|
56
57
|
addressToDebugPath(address: Option<Address>): Option<string>;
|
|
57
58
|
toArrayBuffer(): ArrayBufferLike;
|
|
58
|
-
fromArrayBuffer(arrayBuffer: ArrayBufferLike): void;
|
|
59
|
+
fromArrayBuffer(arrayBuffer: ArrayBufferLike, validate?: boolean): void;
|
|
59
60
|
toJSON(): JSONValue;
|
|
60
|
-
fromJSON(value: JSONValue): void;
|
|
61
|
+
fromJSON(value: JSONValue, validate?: boolean): void;
|
|
61
62
|
}
|
|
62
63
|
//# sourceMappingURL=graph.d.ts.map
|
package/dist/graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAMH,IAAI,EACJ,GAAG,EAEH,SAAS,EAET,MAAM,EAEN,SAAS,EAET,SAAS,EAET,YAAY,
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { asDefined, assert, ByteArrayInput, ByteArrayOutput, Checksum, isDefined, Listeners, Option, panic, Predicates, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { asDefined, assert, ByteArrayInput, ByteArrayOutput, Checksum, isDefined, Listeners, Option, panic, Predicates, tryCatch, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { Address } from "./address";
|
|
3
3
|
import { DeleteUpdate, NewUpdate, PointerUpdate, PrimitiveUpdate } from "./updates";
|
|
4
4
|
import { Dispatchers } from "./dispatchers";
|
|
@@ -7,6 +7,8 @@ export class BoxGraph {
|
|
|
7
7
|
#boxFactory;
|
|
8
8
|
#boxes;
|
|
9
9
|
#deferredPointerUpdates;
|
|
10
|
+
#pendingDeferredNotifications;
|
|
11
|
+
#transactionUpdates;
|
|
10
12
|
#updateListeners;
|
|
11
13
|
#immediateUpdateListeners;
|
|
12
14
|
#transactionListeners;
|
|
@@ -17,10 +19,13 @@ export class BoxGraph {
|
|
|
17
19
|
#deletionListeners;
|
|
18
20
|
#inTransaction = false;
|
|
19
21
|
#constructingBox = false;
|
|
22
|
+
#rollingBack = false;
|
|
20
23
|
constructor(boxFactory = Option.None) {
|
|
21
24
|
this.#boxFactory = boxFactory;
|
|
22
25
|
this.#boxes = UUID.newSet(box => box.address.uuid);
|
|
23
26
|
this.#deferredPointerUpdates = [];
|
|
27
|
+
this.#pendingDeferredNotifications = [];
|
|
28
|
+
this.#transactionUpdates = [];
|
|
24
29
|
this.#dispatchers = Dispatchers.create();
|
|
25
30
|
this.#updateListeners = new Listeners();
|
|
26
31
|
this.#immediateUpdateListeners = new Listeners();
|
|
@@ -33,32 +38,33 @@ export class BoxGraph {
|
|
|
33
38
|
beginTransaction() {
|
|
34
39
|
assert(!this.#inTransaction, "Transaction already in progress");
|
|
35
40
|
this.#inTransaction = true;
|
|
41
|
+
this.#transactionUpdates.length = 0;
|
|
36
42
|
this.#transactionListeners.proxy.onBeginTransaction();
|
|
37
43
|
}
|
|
44
|
+
abortTransaction() {
|
|
45
|
+
assert(this.#inTransaction, "No transaction in progress");
|
|
46
|
+
this.#rollback();
|
|
47
|
+
this.#deferredPointerUpdates.length = 0;
|
|
48
|
+
this.#finalizeTransaction();
|
|
49
|
+
}
|
|
38
50
|
endTransaction() {
|
|
39
51
|
assert(this.#inTransaction, "No transaction in progress");
|
|
40
52
|
if (this.#deferredPointerUpdates.length > 0) {
|
|
41
|
-
this.#deferredPointerUpdates.forEach(({ pointerField, update }) =>
|
|
53
|
+
this.#deferredPointerUpdates.forEach(({ pointerField, update }) => {
|
|
54
|
+
this.#transactionUpdates.push(update);
|
|
55
|
+
this.#prepareDeferredPointerUpdate(pointerField, update);
|
|
56
|
+
});
|
|
42
57
|
this.#deferredPointerUpdates.length = 0;
|
|
43
58
|
}
|
|
44
|
-
this.#
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
this.#pointerTransactionState.clear();
|
|
53
|
-
this.#inTransaction = false;
|
|
54
|
-
// it is possible that new observers will be added while executing
|
|
55
|
-
while (this.#finalizeTransactionObservers.length > 0) {
|
|
56
|
-
this.#finalizeTransactionObservers.splice(0).forEach(observer => observer());
|
|
57
|
-
if (this.#finalizeTransactionObservers.length > 0) {
|
|
58
|
-
console.debug(`${this.#finalizeTransactionObservers.length} new observers while notifying`);
|
|
59
|
-
}
|
|
59
|
+
if (!this.#rollingBack && this.#boxFactory.nonEmpty()) {
|
|
60
|
+
this.#edges.tryValidateAffected().ifSome(error => {
|
|
61
|
+
this.#rollback();
|
|
62
|
+
this.#finalizeTransaction();
|
|
63
|
+
throw error;
|
|
64
|
+
});
|
|
60
65
|
}
|
|
61
|
-
this.#
|
|
66
|
+
this.#dispatchDeferredNotifications();
|
|
67
|
+
this.#finalizeTransaction();
|
|
62
68
|
}
|
|
63
69
|
inTransaction() { return this.#inTransaction; }
|
|
64
70
|
constructingBox() { return this.#constructingBox; }
|
|
@@ -76,6 +82,9 @@ export class BoxGraph {
|
|
|
76
82
|
const added = this.#boxes.add(box);
|
|
77
83
|
assert(added, () => `${box.name} ${box.address.toString()} already staged`);
|
|
78
84
|
const update = new NewUpdate(box.address.uuid, box.name, box.toArrayBuffer());
|
|
85
|
+
if (!this.#rollingBack) {
|
|
86
|
+
this.#transactionUpdates.push(update);
|
|
87
|
+
}
|
|
79
88
|
this.#updateListeners.proxy.onUpdate(update);
|
|
80
89
|
this.#immediateUpdateListeners.proxy.onUpdate(update);
|
|
81
90
|
return box;
|
|
@@ -111,6 +120,9 @@ export class BoxGraph {
|
|
|
111
120
|
assert(deleted === box, `${box} could not be found to unstage`);
|
|
112
121
|
this.#edges.unwatchVerticesOf(box);
|
|
113
122
|
const update = new DeleteUpdate(box.address.uuid, box.name, box.toArrayBuffer());
|
|
123
|
+
if (!this.#rollingBack) {
|
|
124
|
+
this.#transactionUpdates.push(update);
|
|
125
|
+
}
|
|
114
126
|
this.#deletionListeners.removeByKeyIfExist(box.address.uuid)?.listeners.forEach(listener => listener());
|
|
115
127
|
this.#updateListeners.proxy.onUpdate(update);
|
|
116
128
|
this.#immediateUpdateListeners.proxy.onUpdate(update);
|
|
@@ -132,6 +144,9 @@ export class BoxGraph {
|
|
|
132
144
|
this.#assertTransaction();
|
|
133
145
|
if (field.isAttached() && !this.#constructingBox) {
|
|
134
146
|
const update = new PrimitiveUpdate(field.address, field.serialization(), oldValue, newValue);
|
|
147
|
+
if (!this.#rollingBack) {
|
|
148
|
+
this.#transactionUpdates.push(update);
|
|
149
|
+
}
|
|
135
150
|
this.#dispatchers.dispatch(update);
|
|
136
151
|
this.#updateListeners.proxy.onUpdate(update);
|
|
137
152
|
this.#immediateUpdateListeners.proxy.onUpdate(update);
|
|
@@ -150,6 +165,9 @@ export class BoxGraph {
|
|
|
150
165
|
this.#deferredPointerUpdates.push({ pointerField, update });
|
|
151
166
|
}
|
|
152
167
|
else {
|
|
168
|
+
if (!this.#rollingBack) {
|
|
169
|
+
this.#transactionUpdates.push(update);
|
|
170
|
+
}
|
|
153
171
|
this.#processPointerVertexUpdate(pointerField, update);
|
|
154
172
|
this.#immediateUpdateListeners.proxy.onUpdate(update);
|
|
155
173
|
}
|
|
@@ -170,6 +188,60 @@ export class BoxGraph {
|
|
|
170
188
|
this.#dispatchers.dispatch(update);
|
|
171
189
|
this.#updateListeners.proxy.onUpdate(update);
|
|
172
190
|
}
|
|
191
|
+
#prepareDeferredPointerUpdate(pointerField, update) {
|
|
192
|
+
const { oldAddress, newAddress } = update;
|
|
193
|
+
pointerField.resolvedTo(newAddress.flatMap(address => this.findVertex(address)));
|
|
194
|
+
const optState = this.#pointerTransactionState.opt(pointerField.address);
|
|
195
|
+
optState.match({
|
|
196
|
+
none: () => this.#pointerTransactionState.add({
|
|
197
|
+
pointer: pointerField,
|
|
198
|
+
initial: oldAddress,
|
|
199
|
+
final: newAddress,
|
|
200
|
+
index: this.#pointerTransactionState.size()
|
|
201
|
+
}),
|
|
202
|
+
some: state => state.final = newAddress
|
|
203
|
+
});
|
|
204
|
+
this.#pendingDeferredNotifications.push({ pointerField, update });
|
|
205
|
+
}
|
|
206
|
+
#dispatchDeferredNotifications() {
|
|
207
|
+
for (const { update } of this.#pendingDeferredNotifications) {
|
|
208
|
+
this.#dispatchers.dispatch(update);
|
|
209
|
+
this.#updateListeners.proxy.onUpdate(update);
|
|
210
|
+
}
|
|
211
|
+
this.#pendingDeferredNotifications.length = 0;
|
|
212
|
+
}
|
|
213
|
+
#finalizeTransaction() {
|
|
214
|
+
this.#pointerTransactionState.values()
|
|
215
|
+
.toSorted((a, b) => a.index - b.index)
|
|
216
|
+
.forEach(({ pointer, initial, final }) => {
|
|
217
|
+
if (!initial.equals(final)) {
|
|
218
|
+
initial.ifSome(address => this.findVertex(address).unwrapOrUndefined()?.pointerHub.onRemoved(pointer));
|
|
219
|
+
final.ifSome(address => this.findVertex(address).unwrapOrUndefined()?.pointerHub.onAdded(pointer));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
this.#pointerTransactionState.clear();
|
|
223
|
+
this.#inTransaction = false;
|
|
224
|
+
while (this.#finalizeTransactionObservers.length > 0) {
|
|
225
|
+
this.#finalizeTransactionObservers.splice(0).forEach(observer => observer());
|
|
226
|
+
if (this.#finalizeTransactionObservers.length > 0) {
|
|
227
|
+
console.debug(`${this.#finalizeTransactionObservers.length} new observers while notifying`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
this.#transactionListeners.proxy.onEndTransaction(this.#rollingBack);
|
|
231
|
+
this.#rollingBack = false;
|
|
232
|
+
}
|
|
233
|
+
#rollback() {
|
|
234
|
+
this.#rollingBack = true;
|
|
235
|
+
const updates = this.#transactionUpdates.splice(0);
|
|
236
|
+
for (let i = updates.length - 1; i >= 0; i--) {
|
|
237
|
+
updates[i].inverse(this);
|
|
238
|
+
}
|
|
239
|
+
this.#deferredPointerUpdates.length = 0;
|
|
240
|
+
this.#pendingDeferredNotifications.length = 0;
|
|
241
|
+
this.#edges.clearAffected();
|
|
242
|
+
this.#pointerTransactionState.clear();
|
|
243
|
+
this.#transactionUpdates.length = 0;
|
|
244
|
+
}
|
|
173
245
|
findOrphans(rootBox) {
|
|
174
246
|
const connectedBoxes = this.#collectAllConnectedBoxes(rootBox);
|
|
175
247
|
return this.boxes().filter(box => !connectedBoxes.has(box));
|
|
@@ -331,7 +403,7 @@ export class BoxGraph {
|
|
|
331
403
|
});
|
|
332
404
|
return output.toArrayBuffer();
|
|
333
405
|
}
|
|
334
|
-
fromArrayBuffer(arrayBuffer) {
|
|
406
|
+
fromArrayBuffer(arrayBuffer, validate = true) {
|
|
335
407
|
assert(this.#boxes.isEmpty(), "Cannot call fromArrayBuffer if boxes is not empty");
|
|
336
408
|
const input = new ByteArrayInput(arrayBuffer);
|
|
337
409
|
const numBoxes = input.readInt();
|
|
@@ -350,7 +422,17 @@ export class BoxGraph {
|
|
|
350
422
|
boxes
|
|
351
423
|
.sort((a, b) => a.creationIndex - b.creationIndex)
|
|
352
424
|
.forEach(({ name, uuid, boxStream }) => this.createBox(name, uuid, box => box.read(boxStream)));
|
|
353
|
-
|
|
425
|
+
if (validate) {
|
|
426
|
+
this.endTransaction();
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
if (this.#deferredPointerUpdates.length > 0) {
|
|
430
|
+
this.#deferredPointerUpdates.forEach(({ pointerField, update }) => this.#processPointerVertexUpdate(pointerField, update));
|
|
431
|
+
this.#deferredPointerUpdates.length = 0;
|
|
432
|
+
}
|
|
433
|
+
this.#edges.clearAffected();
|
|
434
|
+
this.#finalizeTransaction();
|
|
435
|
+
}
|
|
354
436
|
}
|
|
355
437
|
toJSON() {
|
|
356
438
|
const result = {};
|
|
@@ -362,7 +444,7 @@ export class BoxGraph {
|
|
|
362
444
|
}
|
|
363
445
|
return result;
|
|
364
446
|
}
|
|
365
|
-
fromJSON(value) {
|
|
447
|
+
fromJSON(value, validate = true) {
|
|
366
448
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
367
449
|
return panic("Expected object");
|
|
368
450
|
}
|
|
@@ -370,15 +452,23 @@ export class BoxGraph {
|
|
|
370
452
|
const entries = Object.entries(value);
|
|
371
453
|
for (const [uuid, { name, fields }] of entries) {
|
|
372
454
|
this.createBox(name, UUID.parse(uuid), box => {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
catch (reason) {
|
|
377
|
-
console.warn(reason);
|
|
455
|
+
const result = tryCatch(() => box.fromJSON(fields));
|
|
456
|
+
if (result.status === "failure") {
|
|
457
|
+
console.warn(result.error);
|
|
378
458
|
}
|
|
379
459
|
});
|
|
380
460
|
}
|
|
381
|
-
|
|
461
|
+
if (validate) {
|
|
462
|
+
this.endTransaction();
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
if (this.#deferredPointerUpdates.length > 0) {
|
|
466
|
+
this.#deferredPointerUpdates.forEach(({ pointerField, update }) => this.#processPointerVertexUpdate(pointerField, update));
|
|
467
|
+
this.#deferredPointerUpdates.length = 0;
|
|
468
|
+
}
|
|
469
|
+
this.#edges.clearAffected();
|
|
470
|
+
this.#finalizeTransaction();
|
|
471
|
+
}
|
|
382
472
|
}
|
|
383
473
|
#assertTransaction() {
|
|
384
474
|
assert(this.#inTransaction, () => "Modification only prohibited in transaction mode.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-source.d.ts","sourceRoot":"","sources":["../src/sync-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,UAAU,EAAa,MAAM,kBAAkB,CAAA;AACjF,OAAO,EAAe,SAAS,EAAC,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAA;AAIhC,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,UAAU;;IAC5C,MAAM,CAAC,QAAQ,CAAC,cAAc,SAAQ;gBAK1B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"sync-source.d.ts","sourceRoot":"","sources":["../src/sync-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,UAAU,EAAa,MAAM,kBAAkB,CAAA;AACjF,OAAO,EAAe,SAAS,EAAC,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAA;AAIhC,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,UAAU;;IAC5C,MAAM,CAAC,QAAQ,CAAC,cAAc,SAAQ;gBAK1B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,OAAO;IAsE1E,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IACzC,SAAS;CACZ"}
|
package/dist/sync-source.js
CHANGED
|
@@ -23,7 +23,11 @@ export class SyncSource {
|
|
|
23
23
|
const updates = [];
|
|
24
24
|
this.#terminator.own(graph.subscribeTransaction({
|
|
25
25
|
onBeginTransaction: EmptyExec,
|
|
26
|
-
onEndTransaction: () => {
|
|
26
|
+
onEndTransaction: (rolledBack) => {
|
|
27
|
+
if (rolledBack) {
|
|
28
|
+
Arrays.clear(updates);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
27
31
|
this.#caller.sendUpdates(updates);
|
|
28
32
|
if (SyncSource.DEBUG_CHECKSUM) {
|
|
29
33
|
this.#caller.checksum(graph.checksum()).then(EmptyExec, (reason) => panic(reason));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opendaw/lib-box",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.81",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"test": "vitest run"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@opendaw/lib-runtime": "^0.0.
|
|
27
|
-
"@opendaw/lib-std": "^0.0.
|
|
26
|
+
"@opendaw/lib-runtime": "^0.0.76",
|
|
27
|
+
"@opendaw/lib-std": "^0.0.75"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@opendaw/eslint-config": "^0.0.27",
|
|
31
31
|
"@opendaw/typescript-config": "^0.0.29"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "ff6efcb5332559bb0ba064be829ab0d18a6ba226"
|
|
34
34
|
}
|