@opendaw/lib-box 0.0.69 → 0.0.70

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/README.md CHANGED
@@ -42,4 +42,157 @@ Graph-based object modeling system with serialization, transactions, and pointer
42
42
  ## Editing & Transactions
43
43
 
44
44
  * **editing.ts** - Undo/redo system for graph modifications
45
- * **indexed-box.ts** - Indexed box implementation for efficient lookups
45
+ * **indexed-box.ts** - Indexed box implementation for efficient lookups
46
+
47
+ ## Transaction Mechanism
48
+
49
+ The box system uses transactions to batch changes and ensure consistency. Understanding the transaction lifecycle is crucial for working with the system.
50
+
51
+ ### Transaction Lifecycle
52
+
53
+ 1. **`beginTransaction()`** - Starts a transaction, sets `#inTransaction = true`
54
+ 2. **Changes are made** - Field values updated, pointers modified
55
+ 3. **`endTransaction()`** - Commits changes and fires deferred notifications
56
+
57
+ ### Pointer Updates and Deferred Notifications
58
+
59
+ When a pointer is changed via `refer()`, two things happen:
60
+
61
+ 1. **Immediate**: Graph edges are updated synchronously
62
+ - `graph.edges().connect(pointer, address)` is called
63
+ - The pointer hub's `incoming()` returns the new state immediately
64
+
65
+ 2. **Deferred**: Notifications are batched until `endTransaction()`
66
+ - Pointer changes are recorded in `#pointerTransactionState`
67
+ - At `endTransaction()`, notifications fire in the order changes were made:
68
+ ```typescript
69
+ initial.ifSome(address => vertex.pointerHub.onRemoved(pointer))
70
+ final.ifSome(address => vertex.pointerHub.onAdded(pointer))
71
+ ```
72
+
73
+ ### Implications for Adapters
74
+
75
+ When creating adapters during a transaction:
76
+
77
+ 1. **`catchupAndSubscribe()`** on a pointer hub will:
78
+ - Catch up with current edges (immediately available)
79
+ - Subscribe to future `onAdded`/`onRemoved` notifications (deferred)
80
+
81
+ 2. **Order of notifications** at `endTransaction()`:
82
+ - Determined by the `index` field in `#pointerTransactionState`
83
+ - Index is assigned when the pointer change is recorded
84
+ - Earlier changes fire before later changes
85
+
86
+ ### Example: Creating a Track and Moving a Region
87
+
88
+ ```typescript
89
+ editing.modify(() => {
90
+ // 1. Create new track (deferred: track added notification)
91
+ const newTrack = projectApi.createNoteTrack(audioUnit, index)
92
+
93
+ // 2. Get adapter - this creates TrackRegions which subscribes to pointer hub
94
+ // At this point, no regions are on this track yet
95
+ const adapter = boxAdapters.adapterFor(newTrack, TrackBoxAdapter)
96
+
97
+ // 3. Move region to new track (deferred: region added notification)
98
+ regionBox.regions.refer(adapter.box.regions)
99
+ })
100
+ // After modify() returns, endTransaction() has been called:
101
+ // - "track added" notification fires -> TracksManager.onAdd() -> UI created
102
+ // - "region added" notification fires -> TrackRegions.onAdded() -> dispatchChange()
103
+ ```
104
+
105
+ ### Box Construction During Transaction
106
+
107
+ When creating a box inside a transaction (`TrackBox.create()`):
108
+ - The `#constructingBox` flag is set
109
+ - Pointer updates during construction are added to `#deferredPointerUpdates`
110
+ - These are processed at the start of `endTransaction()` before other notifications
111
+
112
+ ### Key Points
113
+
114
+ - **Edges are synchronous**: `pointerHub.incoming()` reflects changes immediately
115
+ - **Notifications are deferred**: `onAdded`/`onRemoved` fire at `endTransaction()`
116
+ - **Order matters**: Notifications fire in the order changes were made
117
+ - **Adapter creation timing**: Creating an adapter during a transaction means its subscriptions won't receive notifications for changes made earlier in the same transaction (those are caught up via `catchupAndSubscribe`)
118
+
119
+ ## Resource Boxes
120
+
121
+ Boxes can be marked as resources using the `resource` property. Resources act as endpoints in dependency collection, useful for copy/paste operations.
122
+
123
+ ### Resource Types
124
+
125
+ | Type | Description | UUID on Copy |
126
+ |------|-------------|--------------|
127
+ | `"external"` | References something outside the project (files, etc.) | Keep original |
128
+ | `"internal"` | Project-level shared resource | Remap to target's existing |
129
+
130
+ ### Usage in BoxSchema
131
+
132
+ ```typescript
133
+ export const AudioFileBox: BoxSchema<Pointers> = {
134
+ type: "box",
135
+ class: {...},
136
+ pointerRules: {...},
137
+ resource: "external" // Marks as external resource
138
+ }
139
+ ```
140
+
141
+ ### Accessing Resource Type
142
+
143
+ ```typescript
144
+ const box = AudioFileBox.create(graph, uuid)
145
+ console.log(box.resource) // "external"
146
+ console.log(AudioFileBox.Resource) // "external" (static property)
147
+ ```
148
+
149
+ ## Dependency Collection
150
+
151
+ The `dependenciesOf` method collects boxes that depend on a given box. This is used for operations like delete and copy.
152
+
153
+ ### Options
154
+
155
+ ```typescript
156
+ dependenciesOf(box: Box, options: {
157
+ excludeBox?: Predicate<Box> // Filter out specific boxes
158
+ alwaysFollowMandatory?: boolean // Bypass incoming pointer check
159
+ stopAtResources?: boolean // Stop traversal at resource boxes
160
+ } = {}): Dependencies
161
+ ```
162
+
163
+ ### stopAtResources Behavior
164
+
165
+ When `stopAtResources: true`:
166
+
167
+ 1. **Resource boxes ARE added** to the dependency set (they need to be copied)
168
+ 2. **Children are included**: Incoming edges to FIELDS (`!address.isBox()`) are followed
169
+ 3. **Users are excluded**: Incoming edges to the BOX itself (`address.isBox()`) are NOT followed
170
+ 4. **Outgoing edges are skipped**: Resources don't have dependencies we need to follow
171
+
172
+ ### Example: AudioRegion → AudioFileBox ← TransientMarker
173
+
174
+ ```typescript
175
+ // Scenario:
176
+ // Region → AudioFileBox (external resource)
177
+ // TransientMarker → AudioFileBox.children (points to FIELD)
178
+ // OtherRegion → AudioFileBox (points to BOX)
179
+
180
+ const {boxes} = graph.dependenciesOf(region, {
181
+ stopAtResources: true,
182
+ alwaysFollowMandatory: true
183
+ })
184
+
185
+ // Result:
186
+ // - AudioFileBox: included (resource endpoint)
187
+ // - TransientMarker: included (child, points to field)
188
+ // - OtherRegion: excluded (user, points to box)
189
+ ```
190
+
191
+ ### Differentiating Children vs Users
192
+
193
+ The key distinction is the target address:
194
+
195
+ - **Child** (include): `pointer.targetAddress.isBox() === false` - points to a field within the resource
196
+ - **User** (exclude): `pointer.targetAddress.isBox() === true` - points to the resource box itself
197
+
198
+ This allows resource boxes to have "owned" children that are always included when copying, while preventing other boxes that merely reference the resource from being pulled in.
package/dist/box.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Address } from "./address";
2
- import { Class, DataInput, DataOutput, Func, int, JSONValue, Maybe, Option, Optional, Procedure, Subscription, UUID } from "@opendaw/lib-std";
2
+ import { Class, DataInput, DataOutput, Exec, Func, int, JSONValue, Maybe, Option, Optional, Procedure, Subscription, UUID } from "@opendaw/lib-std";
3
3
  import { PointerRules, Vertex, VertexVisitor } from "./vertex";
4
4
  import { Field, FieldKey, FieldKeys, Fields } from "./field";
5
5
  import { PointerField, PointerTypes } from "./pointer";
@@ -7,30 +7,37 @@ import { PointerHub } from "./pointer-hub";
7
7
  import { BoxGraph } from "./graph";
8
8
  import { Update } from "./updates";
9
9
  import { Propagation } from "./dispatchers";
10
+ export type ResourceType = "external" | "internal";
10
11
  export type BoxConstruct<T extends PointerTypes> = {
11
12
  uuid: UUID.Bytes;
12
13
  graph: BoxGraph;
13
14
  name: string;
14
15
  pointerRules: PointerRules<T>;
16
+ resource?: ResourceType;
17
+ ephemeral?: boolean;
15
18
  };
16
19
  export declare abstract class Box<P extends PointerTypes = PointerTypes, F extends Fields = any> implements Vertex<P, F> {
17
20
  #private;
18
21
  static readonly DEBUG_DELETION = false;
19
22
  static Index: int;
20
- protected constructor({ uuid, graph, name, pointerRules }: BoxConstruct<P>);
23
+ protected constructor({ uuid, graph, name, pointerRules, resource, ephemeral }: BoxConstruct<P>);
21
24
  protected abstract initializeFields(): F;
25
+ abstract get tags(): Readonly<Record<string, string | number | boolean>>;
22
26
  abstract accept<VISITOR extends VertexVisitor<any>>(visitor: VISITOR): VISITOR extends VertexVisitor<infer R> ? Maybe<R> : void;
23
27
  fields(): ReadonlyArray<Field>;
24
28
  record(): Readonly<Record<string, Field>>;
25
29
  getField<K extends keyof F>(key: K): F[K];
26
30
  optField<K extends keyof F>(key: K): Option<F[K]>;
27
31
  subscribe(propagation: Propagation, procedure: Procedure<Update>): Subscription;
32
+ subscribeDeletion(listener: Exec): Subscription;
28
33
  get box(): Box;
29
34
  get name(): string;
30
35
  get graph(): BoxGraph;
31
36
  get parent(): Vertex;
32
37
  get address(): Address;
33
38
  get pointerRules(): PointerRules<P>;
39
+ get resource(): ResourceType | undefined;
40
+ get ephemeral(): boolean;
34
41
  get creationIndex(): number;
35
42
  get pointerHub(): PointerHub;
36
43
  estimateMemory(): int;
package/dist/box.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../src/box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAMH,KAAK,EACL,SAAS,EACT,UAAU,EACV,IAAI,EACJ,GAAG,EAGH,SAAS,EAET,KAAK,EACL,MAAM,EACN,QAAQ,EAER,SAAS,EACT,YAAY,EACZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,UAAU,CAAA;AAC5D,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAC,MAAM,SAAS,CAAA;AAC1D,OAAO,EAAC,YAAY,EAAE,YAAY,EAAC,MAAM,WAAW,CAAA;AACpD,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAA;AAExC,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAA;AAChC,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAA;AAChC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAA;AAKzC,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,YAAY,IAAI;IAC/C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAA;IAChB,KAAK,EAAE,QAAQ,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;CAChC,CAAA;AAED,8BAAsB,GAAG,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,CAAC,SAAS,MAAM,GAAG,GAAG,CAAE,YAAW,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;;IAC5G,MAAM,CAAC,QAAQ,CAAC,cAAc,SAAQ;IAEtC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAQ;IAUzB,SAAS,aAAa,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAWxE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,IAAI,CAAC;IAExC,QAAQ,CAAC,MAAM,CAAC,OAAO,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;IAE/H,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC;IAC9B,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACzC,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAIzC,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,YAAY;IAI/E,IAAI,GAAG,IAAI,GAAG,CAAc;IAC5B,IAAI,IAAI,IAAI,MAAM,CAAoB;IACtC,IAAI,KAAK,IAAI,QAAQ,CAAqB;IAC1C,IAAI,MAAM,IAAI,MAAM,CAAc;IAClC,IAAI,OAAO,IAAI,OAAO,CAAuB;IAC7C,IAAI,YAAY,IAAI,YAAY,CAAC,CAAC,CAAC,CAA4B;IAC/D,IAAI,aAAa,IAAI,MAAM,CAA6B;IAExD,IACI,UAAU,IAAI,UAAU,CAA8B;IAE1D,cAAc,IAAI,GAAG;IAMrB,KAAK,IAAI,IAAI,IAAI,GAAG;IACpB,KAAK,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IACvC,OAAO,IAAI,IAAI,IAAI,KAAK;IACxB,UAAU,IAAI,OAAO;IACrB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAC5B,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAC/B,SAAS,IAAI,eAAe;IAQ5B,aAAa,IAAI,eAAe;IAKhC,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC;IAS7B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAajC,aAAa,IAAI,aAAa,CAAC,YAAY,CAAC;IAC5C,aAAa,IAAI,aAAa,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEvD,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAWrF,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;IAW7C,MAAM,IAAI,IAAI;IAad,OAAO,IAAI,IAAI;IAEf,OAAO,IAAI,OAAO;IAelB,QAAQ,IAAI,MAAM;CACrB"}
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../src/box.ts"],"names":[],"mappings":"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"}
package/dist/box.js CHANGED
@@ -18,13 +18,17 @@ export class Box {
18
18
  #graph;
19
19
  #name;
20
20
  #pointerRules;
21
+ #resource;
22
+ #ephemeral;
21
23
  #fields;
22
24
  #creationIndex = Box.Index++;
23
- constructor({ uuid, graph, name, pointerRules }) {
25
+ constructor({ uuid, graph, name, pointerRules, resource, ephemeral }) {
24
26
  this.#address = Address.compose(uuid);
25
27
  this.#graph = graph;
26
28
  this.#name = name;
27
29
  this.#pointerRules = pointerRules;
30
+ this.#resource = resource;
31
+ this.#ephemeral = ephemeral === true;
28
32
  this.#fields = this.initializeFields();
29
33
  if (pointerRules.mandatory || pointerRules.exclusive) {
30
34
  this.graph.edges().watchVertex(this);
@@ -39,12 +43,17 @@ export class Box {
39
43
  subscribe(propagation, procedure) {
40
44
  return this.graph.subscribeVertexUpdates(propagation, this.address, procedure);
41
45
  }
46
+ subscribeDeletion(listener) {
47
+ return this.graph.subscribeDeletion(this.address.uuid, listener);
48
+ }
42
49
  get box() { return this; }
43
50
  get name() { return this.#name; }
44
51
  get graph() { return this.#graph; }
45
52
  get parent() { return this; }
46
53
  get address() { return this.#address; }
47
54
  get pointerRules() { return this.#pointerRules; }
55
+ get resource() { return this.#resource; }
56
+ get ephemeral() { return this.#ephemeral; }
48
57
  get creationIndex() { return this.#creationIndex; }
49
58
  get pointerHub() { return new PointerHub(this); }
50
59
  estimateMemory() {
@@ -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,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"}
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,EAEf,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,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;IA4B5E,iBAAiB,IAAI,mBAAmB;IAoCxC,IAAI,IAAI,IAAI;IAYZ,YAAY,IAAI,IAAI;IAOpB,OAAO,IAAI,IAAI;CAGlB"}
package/dist/editing.js CHANGED
@@ -1,4 +1,36 @@
1
- import { Arrays, assert, Notifier, Option } from "@opendaw/lib-std";
1
+ import { Arrays, assert, Notifier, Option, UUID } from "@opendaw/lib-std";
2
+ import { DeleteUpdate, NewUpdate, PointerUpdate, PrimitiveUpdate } from "./updates";
3
+ // Removes updates for boxes that were created AND deleted in the same transaction.
4
+ const optimizeUpdates = (updates) => {
5
+ const createdUuids = UUID.newSet(uuid => uuid);
6
+ const deletedUuids = UUID.newSet(uuid => uuid);
7
+ for (const update of updates) {
8
+ if (update instanceof NewUpdate) {
9
+ createdUuids.add(update.uuid);
10
+ }
11
+ else if (update instanceof DeleteUpdate) {
12
+ deletedUuids.add(update.uuid);
13
+ }
14
+ }
15
+ const phantomUuids = UUID.newSet(uuid => uuid);
16
+ for (const uuid of createdUuids.values()) {
17
+ if (deletedUuids.hasKey(uuid)) {
18
+ phantomUuids.add(uuid);
19
+ }
20
+ }
21
+ if (phantomUuids.isEmpty()) {
22
+ return updates;
23
+ }
24
+ return updates.filter(update => {
25
+ if (update instanceof NewUpdate || update instanceof DeleteUpdate) {
26
+ return !phantomUuids.hasKey(update.uuid);
27
+ }
28
+ else if (update instanceof PointerUpdate || update instanceof PrimitiveUpdate) {
29
+ return !phantomUuids.hasKey(update.address.uuid);
30
+ }
31
+ return true;
32
+ });
33
+ };
2
34
  class Modification {
3
35
  #updates;
4
36
  constructor(updates) { this.#updates = updates; }
@@ -126,8 +158,9 @@ export class BoxEditing {
126
158
  const result = modifier();
127
159
  this.#graph.endTransaction();
128
160
  subscription.terminate();
129
- if (updates.length > 0) {
130
- this.#pending.push(new Modification(updates));
161
+ const optimized = optimizeUpdates(updates);
162
+ if (optimized.length > 0) {
163
+ this.#pending.push(new Modification(optimized));
131
164
  }
132
165
  this.#modifying = false;
133
166
  this.#graph.edges().validateRequirements();
@@ -150,8 +183,9 @@ export class BoxEditing {
150
183
  approve: () => {
151
184
  this.#graph.endTransaction();
152
185
  subscription.terminate();
153
- if (updates.length > 0) {
154
- this.#pending.push(new Modification(updates));
186
+ const optimized = optimizeUpdates(updates);
187
+ if (optimized.length > 0) {
188
+ this.#pending.push(new Modification(optimized));
155
189
  }
156
190
  this.#modifying = false;
157
191
  this.#inProcess = false;
package/dist/graph.d.ts CHANGED
@@ -33,6 +33,7 @@ export declare class BoxGraph<BoxMap = any> {
33
33
  subscribeToAllUpdatesImmediate(listener: UpdateListener): Subscription;
34
34
  subscribeVertexUpdates(propagation: Propagation, address: Address, procedure: Procedure<Update>): Subscription;
35
35
  subscribeEndTransaction(observer: Exec): void;
36
+ subscribeDeletion(uuid: UUID.Bytes, listener: Exec): Subscription;
36
37
  unstageBox(box: Box): void;
37
38
  findBox<B extends Box = Box>(uuid: UUID.Bytes): Option<B>;
38
39
  findVertex(address: Address): Option<Vertex>;
@@ -45,6 +46,7 @@ export declare class BoxGraph<BoxMap = any> {
45
46
  dependenciesOf(box: Box, options?: {
46
47
  excludeBox?: Predicate<Box>;
47
48
  alwaysFollowMandatory?: boolean;
49
+ stopAtResources?: boolean;
48
50
  }): Dependencies;
49
51
  verifyPointers(): {
50
52
  count: int;
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
package/dist/graph.js CHANGED
@@ -14,6 +14,7 @@ export class BoxGraph {
14
14
  #edges;
15
15
  #pointerTransactionState;
16
16
  #finalizeTransactionObservers;
17
+ #deletionListeners;
17
18
  #inTransaction = false;
18
19
  #constructingBox = false;
19
20
  constructor(boxFactory = Option.None) {
@@ -27,6 +28,7 @@ export class BoxGraph {
27
28
  this.#edges = new GraphEdges();
28
29
  this.#pointerTransactionState = Address.newSet(({ pointer }) => pointer.address);
29
30
  this.#finalizeTransactionObservers = [];
31
+ this.#deletionListeners = UUID.newSet(entry => entry.uuid);
30
32
  }
31
33
  beginTransaction() {
32
34
  assert(!this.#inTransaction, "Transaction already in progress");
@@ -91,12 +93,25 @@ export class BoxGraph {
91
93
  return this.#dispatchers.subscribe(propagation, address, procedure);
92
94
  }
93
95
  subscribeEndTransaction(observer) { this.#finalizeTransactionObservers.push(observer); }
96
+ subscribeDeletion(uuid, listener) {
97
+ const entry = this.#deletionListeners.getOrCreate(uuid, () => ({ uuid, listeners: new Set() }));
98
+ entry.listeners.add(listener);
99
+ return {
100
+ terminate: () => {
101
+ entry.listeners.delete(listener);
102
+ if (entry.listeners.size === 0) {
103
+ this.#deletionListeners.removeByKeyIfExist(uuid);
104
+ }
105
+ }
106
+ };
107
+ }
94
108
  unstageBox(box) {
95
109
  this.#assertTransaction();
96
110
  const deleted = this.#boxes.removeByKey(box.address.uuid);
97
111
  assert(deleted === box, `${box} could not be found to unstage`);
98
112
  this.#edges.unwatchVerticesOf(box);
99
113
  const update = new DeleteUpdate(box.address.uuid, box.name, box.toArrayBuffer());
114
+ this.#deletionListeners.removeByKeyIfExist(box.address.uuid)?.listeners.forEach(listener => listener());
100
115
  this.#updateListeners.proxy.onUpdate(update);
101
116
  this.#immediateUpdateListeners.proxy.onUpdate(update);
102
117
  }
@@ -202,6 +217,7 @@ export class BoxGraph {
202
217
  dependenciesOf(box, options = {}) {
203
218
  const excludeBox = isDefined(options.excludeBox) ? options.excludeBox : Predicates.alwaysFalse;
204
219
  const alwaysFollowMandatory = isDefined(options.alwaysFollowMandatory) ? options.alwaysFollowMandatory : false;
220
+ const stopAtResources = isDefined(options.stopAtResources) ? options.stopAtResources : false;
205
221
  const boxes = new Set();
206
222
  const pointers = new Set();
207
223
  const trace = (box) => {
@@ -209,6 +225,23 @@ export class BoxGraph {
209
225
  return;
210
226
  }
211
227
  boxes.add(box);
228
+ // Handle resource boxes specially when stopAtResources is enabled
229
+ if (stopAtResources && isDefined(box.resource)) {
230
+ // Resource boxes are endpoints, but we still need their "children"
231
+ // Children = boxes that point to FIELDS within this box (not the box itself)
232
+ box.incomingEdges()
233
+ .forEach(pointer => {
234
+ pointers.add(pointer);
235
+ // Only follow if pointer targets a FIELD (child), not the BOX (user)
236
+ const targetsField = pointer.targetAddress.mapOr(address => !address.isBox(), false);
237
+ if (pointer.mandatory && targetsField) {
238
+ trace(pointer.box);
239
+ }
240
+ });
241
+ // Don't trace outgoing edges - resources are endpoints
242
+ return;
243
+ }
244
+ // Normal box traversal
212
245
  box.outgoingEdges()
213
246
  .filter(([pointer]) => !pointers.has(pointer))
214
247
  .forEach(([source, targetAddress]) => {
package/package.json CHANGED
@@ -1,34 +1,34 @@
1
1
  {
2
- "name": "@opendaw/lib-box",
3
- "version": "0.0.69",
4
- "sideEffects": false,
5
- "main": "./dist/index.js",
6
- "types": "./dist/index.d.ts",
7
- "license": "LGPL-3.0-or-later",
8
- "publishConfig": {
9
- "access": "public"
10
- },
11
- "exports": {
12
- ".": {
13
- "types": "./dist/index.d.ts",
14
- "default": "./dist/index.js"
15
- }
16
- },
17
- "files": [
18
- "dist/**/*"
19
- ],
20
- "scripts": {
21
- "build": "tsc",
22
- "lint": "eslint \"**/*.ts\"",
23
- "test": "vitest run"
24
- },
25
- "dependencies": {
26
- "@opendaw/lib-runtime": "^0.0.66",
27
- "@opendaw/lib-std": "^0.0.65"
28
- },
29
- "devDependencies": {
30
- "@opendaw/eslint-config": "^0.0.27",
31
- "@opendaw/typescript-config": "^0.0.28"
32
- },
33
- "gitHead": "182679bcfec5f187c52b2cb1e867098cf6d0f766"
2
+ "name": "@opendaw/lib-box",
3
+ "version": "0.0.70",
4
+ "sideEffects": false,
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "license": "LGPL-3.0-or-later",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/**/*"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "lint": "eslint \"**/*.ts\"",
23
+ "test": "vitest run"
24
+ },
25
+ "dependencies": {
26
+ "@opendaw/lib-runtime": "^0.0.67",
27
+ "@opendaw/lib-std": "^0.0.66"
28
+ },
29
+ "devDependencies": {
30
+ "@opendaw/eslint-config": "^0.0.27",
31
+ "@opendaw/typescript-config": "^0.0.28"
32
+ },
33
+ "gitHead": "a23a423a60a8b0cebfb973224ffb6eddd6fb6943"
34
34
  }