@opendaw/lib-box 0.0.62 → 0.0.64
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 +4 -1
- package/dist/editing.d.ts.map +1 -1
- package/dist/editing.js +85 -45
- package/dist/graph.d.ts +1 -0
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +46 -0
- package/package.json +5 -5
package/dist/editing.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BoxGraph } from "./graph";
|
|
2
|
-
import { Editing, Maybe, Option, SyncProvider } from "@opendaw/lib-std";
|
|
2
|
+
import { Editing, Maybe, Observer, Option, Subscription, SyncProvider } from "@opendaw/lib-std";
|
|
3
3
|
export interface ModificationProcess {
|
|
4
4
|
approve(): void;
|
|
5
5
|
revert(): void;
|
|
@@ -8,12 +8,15 @@ export declare class BoxEditing implements Editing {
|
|
|
8
8
|
#private;
|
|
9
9
|
constructor(graph: BoxGraph);
|
|
10
10
|
get graph(): BoxGraph;
|
|
11
|
+
subscribe(observer: Observer<void>): Subscription;
|
|
11
12
|
markSaved(): void;
|
|
12
13
|
hasUnsavedChanges(): boolean;
|
|
13
14
|
isEmpty(): boolean;
|
|
14
15
|
clear(): void;
|
|
15
16
|
undo(): boolean;
|
|
16
17
|
redo(): boolean;
|
|
18
|
+
canUndo(): boolean;
|
|
19
|
+
canRedo(): boolean;
|
|
17
20
|
mustModify(): boolean;
|
|
18
21
|
modify<R>(modifier: SyncProvider<Maybe<R>>, mark?: boolean): Option<R>;
|
|
19
22
|
beginModification(): ModificationProcess;
|
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,
|
|
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,EACN,YAAY,EACZ,YAAY,EACf,MAAM,kBAAkB,CAAA;AAqBzB,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,OAAO,IAAI,OAAO;IAElB,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,OAAO;IAWf,IAAI,IAAI,OAAO;IASf,OAAO,IAAI,OAAO;IAKlB,OAAO,IAAI,OAAO;IAkBlB,UAAU,IAAI,OAAO;IAErB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,OAAc,GAAG,MAAM,CAAC,CAAC,CAAC;IA2B5E,iBAAiB,IAAI,mBAAmB;IAmCxC,IAAI,IAAI,IAAI;IAYZ,YAAY,IAAI,IAAI;IAOpB,OAAO,IAAI,IAAI;CAGlB"}
|
package/dist/editing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Arrays, assert, Option } from "@opendaw/lib-std";
|
|
1
|
+
import { Arrays, assert, Notifier, Option } from "@opendaw/lib-std";
|
|
2
2
|
class Modification {
|
|
3
3
|
#updates;
|
|
4
4
|
constructor(updates) { this.#updates = updates; }
|
|
@@ -17,14 +17,20 @@ export class BoxEditing {
|
|
|
17
17
|
#graph;
|
|
18
18
|
#pending = [];
|
|
19
19
|
#marked = [];
|
|
20
|
+
#notifier;
|
|
20
21
|
#modifying = false;
|
|
22
|
+
#inProcess = false;
|
|
21
23
|
#disabled = false;
|
|
22
24
|
#historyIndex = 0;
|
|
23
25
|
#savedHistoryIndex = 0; // -1 = saved state was spliced away, >= 0 = valid saved position
|
|
24
26
|
constructor(graph) {
|
|
25
27
|
this.#graph = graph;
|
|
28
|
+
this.#notifier = new Notifier();
|
|
26
29
|
}
|
|
27
30
|
get graph() { return this.#graph; }
|
|
31
|
+
subscribe(observer) {
|
|
32
|
+
return this.#notifier.subscribe(observer);
|
|
33
|
+
}
|
|
28
34
|
markSaved() {
|
|
29
35
|
if (this.#pending.length > 0) {
|
|
30
36
|
this.mark();
|
|
@@ -47,91 +53,124 @@ export class BoxEditing {
|
|
|
47
53
|
Arrays.clear(this.#marked);
|
|
48
54
|
this.#historyIndex = 0;
|
|
49
55
|
this.#savedHistoryIndex = 0;
|
|
56
|
+
this.#notifier.notify();
|
|
50
57
|
}
|
|
51
58
|
undo() {
|
|
52
|
-
if (this
|
|
59
|
+
if (!this.canUndo()) {
|
|
53
60
|
return false;
|
|
54
61
|
}
|
|
55
62
|
if (this.#pending.length > 0) {
|
|
56
63
|
this.mark();
|
|
57
64
|
}
|
|
58
|
-
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
65
|
+
console.debug("undo");
|
|
61
66
|
const modifications = this.#marked[--this.#historyIndex];
|
|
62
67
|
modifications.toReversed().forEach(step => step.inverse(this.#graph));
|
|
63
68
|
this.#graph.edges().validateRequirements();
|
|
69
|
+
this.#notifier.notify();
|
|
64
70
|
return true;
|
|
65
71
|
}
|
|
66
72
|
redo() {
|
|
73
|
+
if (!this.canRedo()) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
console.debug("redo");
|
|
77
|
+
this.#marked[this.#historyIndex++].forEach(step => step.forward(this.#graph));
|
|
78
|
+
this.#graph.edges().validateRequirements();
|
|
79
|
+
this.#notifier.notify();
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
canUndo() {
|
|
67
83
|
if (this.#disabled) {
|
|
68
84
|
return false;
|
|
69
85
|
}
|
|
70
|
-
|
|
86
|
+
return this.#historyIndex !== 0 || this.#pending.length > 0;
|
|
87
|
+
}
|
|
88
|
+
canRedo() {
|
|
89
|
+
if (this.#disabled) {
|
|
71
90
|
return false;
|
|
72
91
|
}
|
|
73
|
-
if (this.#
|
|
74
|
-
console.warn("redo while having pending updates?");
|
|
92
|
+
if (this.#historyIndex === this.#marked.length) {
|
|
75
93
|
return false;
|
|
76
94
|
}
|
|
77
|
-
this.#
|
|
78
|
-
this.#graph.edges().validateRequirements();
|
|
79
|
-
return true;
|
|
95
|
+
return this.#pending.length <= 0;
|
|
80
96
|
}
|
|
81
|
-
// TODO This
|
|
82
|
-
//
|
|
97
|
+
// TODO This method exists to handle bidirectional sync between UI state and Box state.
|
|
98
|
+
// Problem: When a Box field changes (e.g., during undo/redo), reactive subscriptions may fire
|
|
99
|
+
// and attempt to call modify() to sync the UI state back to the Box. But since undo/redo
|
|
100
|
+
// already has a transaction open (via Modification.inverse/forward calling beginTransaction
|
|
101
|
+
// directly), calling modify() would fail with "Transaction already in progress".
|
|
102
|
+
// Current workaround: Callers check mustModify() before calling modify(). If false (transaction
|
|
103
|
+
// already open), they either skip the call or call setValue directly without recording history.
|
|
104
|
+
// See: EditWrapper.forValue, EditWrapper.forAutomatableParameter, TransportGroup loop sync.
|
|
105
|
+
// Better solution: Consider having Modification.inverse/forward use the same #modifying flag
|
|
106
|
+
// as modify(), or introduce a unified "modification context" that both undo/redo and user
|
|
107
|
+
// actions share. This would allow modify() to detect it's being called reactively during
|
|
108
|
+
// undo/redo and handle it internally, rather than requiring all callers to guard with mustModify().
|
|
83
109
|
mustModify() { return !this.#graph.inTransaction(); }
|
|
84
110
|
modify(modifier, mark = true) {
|
|
111
|
+
assert(!this.#inProcess, "Cannot call modify while a modification process is running");
|
|
85
112
|
if (this.#modifying) {
|
|
86
|
-
//
|
|
113
|
+
// Nested modify call - just execute without separate recording
|
|
114
|
+
this.#notifier.notify();
|
|
87
115
|
return Option.wrap(modifier());
|
|
88
116
|
}
|
|
89
117
|
if (mark && this.#pending.length > 0) {
|
|
90
118
|
this.mark();
|
|
91
119
|
}
|
|
92
|
-
|
|
120
|
+
this.#modifying = true;
|
|
121
|
+
const updates = [];
|
|
122
|
+
const subscription = this.#graph.subscribeToAllUpdates({
|
|
123
|
+
onUpdate: (update) => updates.push(update)
|
|
124
|
+
});
|
|
125
|
+
this.#graph.beginTransaction();
|
|
126
|
+
const result = modifier();
|
|
127
|
+
this.#graph.endTransaction();
|
|
128
|
+
subscription.terminate();
|
|
129
|
+
if (updates.length > 0) {
|
|
130
|
+
this.#pending.push(new Modification(updates));
|
|
131
|
+
}
|
|
132
|
+
this.#modifying = false;
|
|
133
|
+
this.#graph.edges().validateRequirements();
|
|
93
134
|
if (mark) {
|
|
94
135
|
this.mark();
|
|
95
136
|
}
|
|
96
|
-
|
|
137
|
+
this.#notifier.notify();
|
|
138
|
+
return Option.wrap(result);
|
|
97
139
|
}
|
|
98
140
|
beginModification() {
|
|
99
|
-
|
|
100
|
-
if (!alreadyIntransaction) {
|
|
101
|
-
this.#graph.beginTransaction();
|
|
102
|
-
}
|
|
141
|
+
assert(!this.#modifying && !this.#inProcess, "Cannot begin modification while another is in progress");
|
|
103
142
|
this.#modifying = true;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
143
|
+
this.#inProcess = true;
|
|
144
|
+
const updates = [];
|
|
145
|
+
const subscription = this.#graph.subscribeToAllUpdates({
|
|
146
|
+
onUpdate: (update) => updates.push(update)
|
|
147
|
+
});
|
|
148
|
+
this.#graph.beginTransaction();
|
|
149
|
+
return {
|
|
150
|
+
approve: () => {
|
|
107
151
|
this.#graph.endTransaction();
|
|
152
|
+
subscription.terminate();
|
|
153
|
+
if (updates.length > 0) {
|
|
154
|
+
this.#pending.push(new Modification(updates));
|
|
155
|
+
}
|
|
156
|
+
this.#modifying = false;
|
|
157
|
+
this.#inProcess = false;
|
|
108
158
|
this.#graph.edges().validateRequirements();
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
approve: complete,
|
|
159
|
+
this.mark();
|
|
160
|
+
this.#notifier.notify();
|
|
161
|
+
},
|
|
113
162
|
revert: () => {
|
|
114
|
-
this.
|
|
115
|
-
|
|
163
|
+
this.#graph.endTransaction();
|
|
164
|
+
subscription.terminate();
|
|
165
|
+
this.#modifying = false;
|
|
166
|
+
this.#inProcess = false;
|
|
167
|
+
this.#graph.edges().validateRequirements();
|
|
168
|
+
if (updates.length > 0) {
|
|
169
|
+
new Modification(updates).inverse(this.#graph);
|
|
170
|
+
}
|
|
116
171
|
}
|
|
117
172
|
};
|
|
118
173
|
}
|
|
119
|
-
#modify(modifier) {
|
|
120
|
-
assert(!this.#modifying, "Already modifying");
|
|
121
|
-
this.#modifying = true;
|
|
122
|
-
const updates = [];
|
|
123
|
-
const subscription = this.#graph.subscribeToAllUpdates({ onUpdate: (update) => { updates.push(update); } });
|
|
124
|
-
this.#graph.beginTransaction();
|
|
125
|
-
const result = modifier();
|
|
126
|
-
this.#graph.endTransaction();
|
|
127
|
-
if (updates.length > 0) {
|
|
128
|
-
this.#pending.push(new Modification(updates));
|
|
129
|
-
}
|
|
130
|
-
subscription.terminate();
|
|
131
|
-
this.#modifying = false;
|
|
132
|
-
this.#graph.edges().validateRequirements();
|
|
133
|
-
return result;
|
|
134
|
-
}
|
|
135
174
|
mark() {
|
|
136
175
|
if (this.#pending.length === 0) {
|
|
137
176
|
return;
|
|
@@ -151,6 +190,7 @@ export class BoxEditing {
|
|
|
151
190
|
}
|
|
152
191
|
this.#pending.reverse().forEach(modification => modification.inverse(this.#graph));
|
|
153
192
|
this.#pending.length = 0;
|
|
193
|
+
this.#notifier.notify();
|
|
154
194
|
}
|
|
155
195
|
disable() {
|
|
156
196
|
this.#disabled = true;
|
package/dist/graph.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare class BoxGraph<BoxMap = any> {
|
|
|
41
41
|
checksum(): Int8Array;
|
|
42
42
|
onPrimitiveValueUpdate<V extends PrimitiveValues>(field: PrimitiveField<V, any>, oldValue: V, newValue: V): void;
|
|
43
43
|
onPointerAddressUpdated(pointerField: PointerField, oldValue: Option<Address>, newValue: Option<Address>): void;
|
|
44
|
+
findOrphans(rootBox: Box): ReadonlyArray<Box>;
|
|
44
45
|
dependenciesOf(box: Box, options?: {
|
|
45
46
|
excludeBox?: Predicate<Box>;
|
|
46
47
|
alwaysFollowMandatory?: boolean;
|
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,EACN,QAAQ,EAER,SAAS,EAET,SAAS,EAET,YAAY,EACZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAMH,IAAI,EACJ,GAAG,EAEH,SAAS,EAET,MAAM,EACN,QAAQ,EAER,SAAS,EAET,SAAS,EAET,YAAY,EACZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAuE,MAAM,EAAC,MAAM,WAAW,CAAA;AACtG,OAAO,EAAc,WAAW,EAAC,MAAM,eAAe,CAAA;AACtD,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAA;AAExC,MAAM,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,MAAM,EAClB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,IAAI,EAAE,IAAI,CAAC,KAAK,EAChB,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,KAAK,GAAG,CAAA;AAErE,MAAM,WAAW,mBAAmB;IAChC,kBAAkB,IAAI,IAAI,CAAA;IAC1B,gBAAgB,IAAI,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAA;CAAE,CAAA;AAErF,qBAAa,QAAQ,CAAC,MAAM,GAAG,GAAG;;gBAoBlB,UAAU,GAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAe;IAahE,gBAAgB,IAAI,IAAI;IAMxB,cAAc,IAAI,IAAI;IA2BtB,aAAa,IAAI,OAAO;IACxB,eAAe,IAAI,OAAO;IAE1B,SAAS,CAAC,IAAI,EAAE,MAAM,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG;IAIjF,QAAQ,CAAC,CAAC,SAAS,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IAgB9D,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,YAAY;IAIjE,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY;IAI7D,8BAA8B,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY;IAItE,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,YAAY;IAI9G,uBAAuB,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IAE7C,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAU1B,OAAO,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;IAIzD,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;IAI5C,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC;IAE3B,KAAK,IAAI,UAAU;IAEnB,QAAQ,IAAI,SAAS;IAMrB,sBAAsB,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;IAUhH,uBAAuB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI;IA8B/G,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;IA6C7C,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE;QAC9B,UAAU,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAC7B,GAAG,YAAY;IAmCrB,cAAc,IAAI;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE;IAwBhC,UAAU,IAAI,IAAI;IAYlB,iBAAiB,IAAI,IAAI;IAUzB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IAS5D,aAAa,IAAI,eAAe;IAYhC,eAAe,CAAC,WAAW,EAAE,eAAe,GAAG,IAAI;IA2BnD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC;CAWhC"}
|
package/dist/graph.js
CHANGED
|
@@ -155,6 +155,50 @@ export class BoxGraph {
|
|
|
155
155
|
this.#dispatchers.dispatch(update);
|
|
156
156
|
this.#updateListeners.proxy.onUpdate(update);
|
|
157
157
|
}
|
|
158
|
+
findOrphans(rootBox) {
|
|
159
|
+
const connectedBoxes = this.#collectAllConnectedBoxes(rootBox);
|
|
160
|
+
return this.boxes().filter(box => !connectedBoxes.has(box));
|
|
161
|
+
}
|
|
162
|
+
#collectAllConnectedBoxes(rootBox) {
|
|
163
|
+
const visited = new Set();
|
|
164
|
+
const queue = [rootBox];
|
|
165
|
+
while (queue.length > 0) {
|
|
166
|
+
const box = queue.pop();
|
|
167
|
+
if (visited.has(box)) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
visited.add(box);
|
|
171
|
+
this.#collectPointersFromBox(box).forEach(pointer => {
|
|
172
|
+
pointer.targetAddress.ifSome(address => {
|
|
173
|
+
this.findBox(address.uuid).ifSome(targetBox => {
|
|
174
|
+
if (!visited.has(targetBox)) {
|
|
175
|
+
queue.push(targetBox);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
for (const pointer of box.incomingEdges()) {
|
|
181
|
+
if (!visited.has(pointer.box)) {
|
|
182
|
+
queue.push(pointer.box);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return visited;
|
|
187
|
+
}
|
|
188
|
+
#collectPointersFromBox(box) {
|
|
189
|
+
const pointers = [];
|
|
190
|
+
const collectFromFields = (fields) => {
|
|
191
|
+
for (const field of fields) {
|
|
192
|
+
field.accept({
|
|
193
|
+
visitPointerField: (p) => pointers.push(p),
|
|
194
|
+
visitObjectField: (o) => collectFromFields(o.fields()),
|
|
195
|
+
visitArrayField: (a) => collectFromFields(a.fields())
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
collectFromFields(box.fields());
|
|
200
|
+
return pointers;
|
|
201
|
+
}
|
|
158
202
|
dependenciesOf(box, options = {}) {
|
|
159
203
|
const excludeBox = isDefined(options.excludeBox) ? options.excludeBox : Predicates.alwaysFalse;
|
|
160
204
|
const alwaysFollowMandatory = isDefined(options.alwaysFollowMandatory) ? options.alwaysFollowMandatory : false;
|
|
@@ -173,6 +217,8 @@ export class BoxGraph {
|
|
|
173
217
|
pointers.add(source);
|
|
174
218
|
if (targetVertex.pointerRules.mandatory &&
|
|
175
219
|
(alwaysFollowMandatory || targetVertex.pointerHub.incoming()
|
|
220
|
+
// Only check pointers to this specific address, not to other fields in the box
|
|
221
|
+
.filter(p => p.targetAddress.mapOr(address => address.equals(targetAddress), false))
|
|
176
222
|
.every(pointer => pointers.has(pointer)))) {
|
|
177
223
|
return trace(targetVertex.box);
|
|
178
224
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opendaw/lib-box",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.64",
|
|
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.63",
|
|
27
|
+
"@opendaw/lib-std": "^0.0.63"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@opendaw/eslint-config": "^0.0.27",
|
|
31
|
-
"@opendaw/typescript-config": "^0.0.
|
|
31
|
+
"@opendaw/typescript-config": "^0.0.28"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "db2b1bd172607177fef63077c2eed9b7cbec167f"
|
|
34
34
|
}
|