@opendaw/lib-box 0.0.6

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.
Files changed (59) hide show
  1. package/README.md +1 -0
  2. package/dist/address.d.ts +47 -0
  3. package/dist/address.d.ts.map +1 -0
  4. package/dist/address.js +133 -0
  5. package/dist/array.d.ts +19 -0
  6. package/dist/array.d.ts.map +1 -0
  7. package/dist/array.js +32 -0
  8. package/dist/box.d.ts +51 -0
  9. package/dist/box.d.ts.map +1 -0
  10. package/dist/box.js +122 -0
  11. package/dist/dispatchers.d.ts +16 -0
  12. package/dist/dispatchers.d.ts.map +1 -0
  13. package/dist/dispatchers.js +127 -0
  14. package/dist/editing.d.ts +21 -0
  15. package/dist/editing.d.ts.map +1 -0
  16. package/dist/editing.js +131 -0
  17. package/dist/field.d.ts +42 -0
  18. package/dist/field.d.ts.map +1 -0
  19. package/dist/field.js +80 -0
  20. package/dist/graph-edges.d.ts +16 -0
  21. package/dist/graph-edges.d.ts.map +1 -0
  22. package/dist/graph-edges.js +109 -0
  23. package/dist/graph.d.ts +55 -0
  24. package/dist/graph.d.ts.map +1 -0
  25. package/dist/graph.js +262 -0
  26. package/dist/index.d.ts +18 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +25 -0
  29. package/dist/object.d.ts +17 -0
  30. package/dist/object.d.ts.map +1 -0
  31. package/dist/object.js +19 -0
  32. package/dist/pointer-hub.d.ts +26 -0
  33. package/dist/pointer-hub.d.ts.map +1 -0
  34. package/dist/pointer-hub.js +110 -0
  35. package/dist/pointer.d.ts +32 -0
  36. package/dist/pointer.d.ts.map +1 -0
  37. package/dist/pointer.js +82 -0
  38. package/dist/primitive.d.ts +110 -0
  39. package/dist/primitive.d.ts.map +1 -0
  40. package/dist/primitive.js +152 -0
  41. package/dist/serializer.d.ts +7 -0
  42. package/dist/serializer.d.ts.map +1 -0
  43. package/dist/serializer.js +29 -0
  44. package/dist/sync-source.d.ts +11 -0
  45. package/dist/sync-source.d.ts.map +1 -0
  46. package/dist/sync-source.js +72 -0
  47. package/dist/sync-target.d.ts +5 -0
  48. package/dist/sync-target.d.ts.map +1 -0
  49. package/dist/sync-target.js +40 -0
  50. package/dist/sync.d.ts +24 -0
  51. package/dist/sync.d.ts.map +1 -0
  52. package/dist/sync.js +1 -0
  53. package/dist/updates.d.ts +70 -0
  54. package/dist/updates.d.ts.map +1 -0
  55. package/dist/updates.js +178 -0
  56. package/dist/vertex.d.ts +41 -0
  57. package/dist/vertex.d.ts.map +1 -0
  58. package/dist/vertex.js +1 -0
  59. package/package.json +33 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ This package is part of the openDAW SDK
@@ -0,0 +1,47 @@
1
+ import { Comparable, Comparator, DataInput, DataOutput, Func, int, Nullable, SortedSet, UUID } from "@opendaw/lib-std";
2
+ import { FieldKey, FieldKeys } from "./field";
3
+ export type AddressLayout = [UUID.Format, FieldKeys];
4
+ export type AddressJSON = {
5
+ uuid: Array<int>;
6
+ fields: Array<int>;
7
+ };
8
+ export declare class Address implements Comparable<Address> {
9
+ #private;
10
+ static newSet<T>(keyExtractor: Func<T, Address>): SortedSet<Address, T>;
11
+ static readonly compose: (uuid: UUID.Format, ...fieldKeys: FieldKey[]) => Address;
12
+ static decode(str: string): Address;
13
+ static reconstruct(layout: AddressLayout): Address;
14
+ static boxRange<T>(set: SortedSet<Address, T>, id: UUID.Format, map: Func<T, UUID.Format>): Nullable<[int, int]>;
15
+ static readonly Comparator: Comparator<Address>;
16
+ static readonly MinimalComparator: Comparator<Address>;
17
+ static readonly LengthComparator: Comparator<Address>;
18
+ constructor(uuid: UUID.Format, fieldKeys: FieldKeys);
19
+ get uuid(): UUID.Format;
20
+ get fieldKeys(): FieldKeys;
21
+ isBox(): boolean;
22
+ isContent(): boolean;
23
+ equals(other: Address): boolean;
24
+ compareTo(other: Address): int;
25
+ append(key: FieldKey): Address;
26
+ startsWith(other: Address): boolean;
27
+ write(output: DataOutput): void;
28
+ decompose(): AddressLayout;
29
+ toJSON(): {
30
+ uuid: number[];
31
+ fields: number[];
32
+ };
33
+ toArrayBuffer(): ArrayBufferLike;
34
+ toString(): string;
35
+ static read(input: DataInput): Address;
36
+ }
37
+ export interface Addressable {
38
+ get address(): Address;
39
+ }
40
+ export declare namespace Addressable {
41
+ const AddressReader: (addressable: Addressable) => Address;
42
+ const Comparator: Comparator<Addressable>;
43
+ const equals: <A extends Addressable>(address: Address, sorted: ReadonlyArray<A>) => Array<A>;
44
+ const startsWith: <A extends Addressable>(address: Address, sorted: ReadonlyArray<A>) => Array<A>;
45
+ const endsWith: <A extends Addressable>(address: Address, sorted: ReadonlyArray<A>) => Array<A>;
46
+ }
47
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ import { Arrays, assert, BinarySearch, SortedSet, UUID } from "@opendaw/lib-std";
2
+ export class Address {
3
+ static newSet(keyExtractor) {
4
+ return new SortedSet(keyExtractor, Address.Comparator);
5
+ }
6
+ static compose = (uuid, ...fieldKeys) => {
7
+ const keys = fieldKeys.length === 0 ? this.#EMPTY_FIELD_KEYS : new Int16Array(fieldKeys);
8
+ assert(keys.every((value, index) => value === fieldKeys[index]), `fieldKeys (${keys.join(",")}) only allows i16`);
9
+ return new Address(uuid, keys);
10
+ };
11
+ static decode(str) {
12
+ const parts = str.split("/");
13
+ assert(parts.length > 0, "Unable to parse Address");
14
+ return Address.compose(UUID.parse(parts[0]), ...parts.slice(1).map(x => parseInt(x)));
15
+ }
16
+ static reconstruct(layout) { return this.compose(layout[0], ...layout[1]); }
17
+ static boxRange(set, id, map) {
18
+ const sorted = set.values();
19
+ const startIndex = BinarySearch.leftMostMapped(sorted, id, UUID.Comparator, map);
20
+ const length = sorted.length;
21
+ if (startIndex < 0 || startIndex >= length) {
22
+ return null;
23
+ }
24
+ for (let endIndex = startIndex; endIndex < length; endIndex++) {
25
+ if (UUID.Comparator(map(sorted[endIndex]), id) !== 0) {
26
+ if (startIndex < endIndex) {
27
+ return [startIndex, endIndex];
28
+ }
29
+ else {
30
+ return null;
31
+ }
32
+ }
33
+ }
34
+ return [startIndex, length];
35
+ }
36
+ static Comparator = (a, b) => {
37
+ const compareId = UUID.Comparator(a.#uuid, b.#uuid);
38
+ if (compareId !== 0) {
39
+ return compareId;
40
+ }
41
+ const n = Math.min(a.#fieldKeys.length, b.#fieldKeys.length);
42
+ for (let i = 0; i < n; i++) {
43
+ const comparison = (a.#fieldKeys)[i] - (b.#fieldKeys)[i];
44
+ if (comparison !== 0) {
45
+ return comparison;
46
+ }
47
+ }
48
+ return a.#fieldKeys.length - b.#fieldKeys.length;
49
+ };
50
+ static MinimalComparator = (a, b) => {
51
+ const compareId = UUID.Comparator(a.#uuid, b.#uuid);
52
+ if (compareId !== 0) {
53
+ return compareId;
54
+ }
55
+ const n = Math.min(a.#fieldKeys.length, b.#fieldKeys.length);
56
+ for (let i = 0; i < n; i++) {
57
+ const comparison = (a.#fieldKeys)[i] - (b.#fieldKeys)[i];
58
+ if (comparison !== 0) {
59
+ return comparison;
60
+ }
61
+ }
62
+ return 0;
63
+ };
64
+ static LengthComparator = (a, b) => {
65
+ const compareId = UUID.Comparator(a.#uuid, b.#uuid);
66
+ if (compareId !== 0) {
67
+ return compareId;
68
+ }
69
+ return b.#fieldKeys.length - a.#fieldKeys.length;
70
+ };
71
+ static #EMPTY_FIELD_KEYS = new Int16Array(0);
72
+ #uuid;
73
+ #fieldKeys;
74
+ constructor(uuid, fieldKeys) {
75
+ this.#uuid = uuid;
76
+ this.#fieldKeys = fieldKeys;
77
+ }
78
+ get uuid() { return this.#uuid; }
79
+ get fieldKeys() { return this.#fieldKeys; }
80
+ isBox() { return this.#fieldKeys.length === 0; }
81
+ isContent() { return !this.isBox(); }
82
+ equals(other) { return Address.Comparator(this, other) === 0; }
83
+ compareTo(other) { return Address.Comparator(this, other); }
84
+ append(key) {
85
+ return new Address(this.#uuid, new Int16Array([...this.#fieldKeys, key]));
86
+ }
87
+ startsWith(other) {
88
+ return UUID.Comparator(other.#uuid, this.#uuid) === 0
89
+ && other.#fieldKeys.length <= this.#fieldKeys.length
90
+ && other.#fieldKeys.every((value, index) => this.#fieldKeys[index] === value);
91
+ }
92
+ write(output) {
93
+ output.writeBytes(new Int8Array(this.#uuid.buffer));
94
+ output.writeByte(this.#fieldKeys.length);
95
+ this.#fieldKeys.forEach(key => output.writeShort(key));
96
+ }
97
+ decompose() { return [this.#uuid, this.#fieldKeys]; }
98
+ toJSON() { return { uuid: Array.from(this.#uuid.values()), fields: Array.from(this.#fieldKeys.values()) }; }
99
+ toArrayBuffer() {
100
+ const array = new Uint8Array(UUID.length + this.#fieldKeys.length);
101
+ array.set(this.#uuid, 0);
102
+ array.set(this.#fieldKeys, UUID.length);
103
+ return array.buffer;
104
+ }
105
+ toString() { return [UUID.toString(this.#uuid), ...this.#fieldKeys].join("/"); }
106
+ static read(input) {
107
+ const uuidBytes = UUID.fromDataInput(input);
108
+ const numFields = input.readByte();
109
+ return Address.compose(uuidBytes, ...Arrays.create(() => input.readShort(), numFields));
110
+ }
111
+ }
112
+ export var Addressable;
113
+ (function (Addressable) {
114
+ Addressable.AddressReader = (addressable) => addressable.address;
115
+ Addressable.Comparator = ({ address: a }, { address: b }) => Address.Comparator(a, b);
116
+ Addressable.equals = (address, sorted) => {
117
+ const [l, r] = BinarySearch.rangeMapped(sorted, address, Address.Comparator, Addressable.AddressReader);
118
+ return sorted.slice(l, r + 1);
119
+ };
120
+ Addressable.startsWith = (address, sorted) => {
121
+ const [l, r] = BinarySearch.rangeMapped(sorted, address, Address.MinimalComparator, Addressable.AddressReader);
122
+ return sorted
123
+ .slice(l, r + 1)
124
+ .filter((addressable) => addressable.address.startsWith(address));
125
+ };
126
+ Addressable.endsWith = (address, sorted) => {
127
+ const l = BinarySearch.leftMostMapped(sorted, address, Address.LengthComparator, Addressable.AddressReader);
128
+ const r = BinarySearch.rightMostMapped(sorted, address, Address.MinimalComparator, Addressable.AddressReader);
129
+ return sorted
130
+ .slice(l, r + 1)
131
+ .filter((addressable) => address.startsWith(addressable.address));
132
+ };
133
+ })(Addressable || (Addressable = {}));
@@ -0,0 +1,19 @@
1
+ import { Field, FieldConstruct } from "./field";
2
+ import { UnreferenceableType } from "./pointer";
3
+ import { DataInput, DataOutput, int, Nullish, Option } from "@opendaw/lib-std";
4
+ import { VertexVisitor } from "./vertex";
5
+ export type ArrayFieldFactory<FIELD extends Field> = (construct: FieldConstruct<UnreferenceableType>) => FIELD;
6
+ export declare class ArrayField<FIELD extends Field = Field> extends Field<UnreferenceableType, Record<int, FIELD>> {
7
+ #private;
8
+ static create<FIELD extends Field>(construct: FieldConstruct<UnreferenceableType>, factory: ArrayFieldFactory<FIELD>, length: int): ArrayField<FIELD>;
9
+ private constructor();
10
+ accept<RETURN>(visitor: VertexVisitor<RETURN>): Nullish<RETURN>;
11
+ fields(): Iterable<FIELD>;
12
+ getField(key: keyof Record<int, FIELD>): Record<int, FIELD>[keyof Record<int, FIELD>];
13
+ optField(key: keyof Record<int, FIELD>): Option<Record<int, FIELD>[keyof Record<int, FIELD>]>;
14
+ read(input: DataInput): void;
15
+ write(output: DataOutput): void;
16
+ size(): int;
17
+ toJSON(): readonly FIELD[];
18
+ }
19
+ //# sourceMappingURL=array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,cAAc,EAAC,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAC,mBAAmB,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAoB,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAA;AAC5G,OAAO,EAAa,aAAa,EAAC,MAAM,UAAU,CAAA;AAElD,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,mBAAmB,CAAC,KAAK,KAAK,CAAA;AAE9G,qBAAa,UAAU,CAAC,KAAK,SAAS,KAAK,GAAG,KAAK,CAC/C,SAAQ,KAAK,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;;IACtD,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,KAAK,EAC7B,SAAS,EAAE,cAAc,CAAC,mBAAmB,CAAC,EAC9C,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,EACjC,MAAM,EAAE,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC;IAKnC,OAAO;IAWP,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC;IAEzB,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAIrF,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAI7F,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAC5B,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAE/B,IAAI,IAAI,GAAG;IAEX,MAAM;CACT"}
package/dist/array.js ADDED
@@ -0,0 +1,32 @@
1
+ import { Field } from "./field";
2
+ import { Arrays, asDefined, Option, safeExecute } from "@opendaw/lib-std";
3
+ import { NoPointers } from "./vertex";
4
+ export class ArrayField extends Field {
5
+ static create(construct, factory, length) {
6
+ return new ArrayField(construct, factory, length);
7
+ }
8
+ #fields;
9
+ constructor(construct, factory, length) {
10
+ super(construct);
11
+ this.#fields = Arrays.create((index) => factory({
12
+ parent: this,
13
+ fieldKey: index,
14
+ fieldName: String(index),
15
+ pointerRules: NoPointers
16
+ }), length);
17
+ }
18
+ accept(visitor) {
19
+ return safeExecute(visitor.visitArrayField, this);
20
+ }
21
+ fields() { return this.#fields; }
22
+ getField(key) {
23
+ return asDefined(this.#fields[key]);
24
+ }
25
+ optField(key) {
26
+ return Option.wrap(this.#fields[key]);
27
+ }
28
+ read(input) { this.#fields.forEach(field => field.read(input)); }
29
+ write(output) { this.#fields.forEach(field => field.write(output)); }
30
+ size() { return this.#fields.length; }
31
+ toJSON() { return this.#fields; }
32
+ }
package/dist/box.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { Address } from "./address";
2
+ import { DataInput, DataOutput, Func, int, Nullish, Option, Procedure, Subscription, UUID } from "@opendaw/lib-std";
3
+ import { PointerRules, Vertex, VertexVisitor } from "./vertex";
4
+ import { Field, FieldKey, FieldKeys, Fields } from "./field";
5
+ import { PointerField, PointerTypes } from "./pointer";
6
+ import { PointerHub } from "./pointer-hub";
7
+ import { BoxGraph } from "./graph";
8
+ import { Update } from "./updates";
9
+ import { Propagation } from "./dispatchers";
10
+ export type BoxConstruct<T extends PointerTypes> = {
11
+ uuid: UUID.Format;
12
+ graph: BoxGraph;
13
+ name: string;
14
+ pointerRules: PointerRules<T>;
15
+ };
16
+ export declare abstract class Box<P extends PointerTypes = PointerTypes, F extends Fields = any> implements Vertex<P, F> {
17
+ #private;
18
+ static readonly DEBUG_DELETION = false;
19
+ static Index: int;
20
+ protected constructor({ uuid, graph, name, pointerRules }: BoxConstruct<P>);
21
+ protected abstract initializeFields(): F;
22
+ abstract accept<VISITOR extends VertexVisitor<any>>(visitor: VISITOR): VISITOR extends VertexVisitor<infer R> ? Nullish<R> : void;
23
+ fields(): Iterable<Field>;
24
+ getField<K extends keyof F>(key: K): F[K];
25
+ optField<K extends keyof F>(key: K): Option<F[K]>;
26
+ subscribe(propagation: Propagation, procedure: Procedure<Update>): Subscription;
27
+ get box(): Box;
28
+ get name(): string;
29
+ get graph(): BoxGraph;
30
+ get parent(): Vertex;
31
+ get address(): Address;
32
+ get pointerRules(): PointerRules<P>;
33
+ get creationIndex(): number;
34
+ get pointerHub(): PointerHub;
35
+ estimateMemory(): int;
36
+ isBox(): this is Box;
37
+ isField(): this is Field;
38
+ isAttached(): boolean;
39
+ read(input: DataInput): void;
40
+ write(output: DataOutput): void;
41
+ serialize(): ArrayBufferLike;
42
+ toArrayBuffer(): ArrayBufferLike;
43
+ incomingEdges(): ReadonlyArray<PointerField>;
44
+ outgoingEdges(): ReadonlyArray<[PointerField, Vertex]>;
45
+ mapFields<T>(map: Func<Field, T>, ...keys: FieldKey[]): ReadonlyArray<T>;
46
+ searchVertex(keys: FieldKeys): Option<Vertex>;
47
+ delete(): void;
48
+ unstage(): void;
49
+ toString(): string;
50
+ }
51
+ //# sourceMappingURL=box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../src/box.ts"],"names":[],"mappings":"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"}
package/dist/box.js ADDED
@@ -0,0 +1,122 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Address } from "./address";
11
+ import { Arrays, asDefined, ByteArrayOutput, ByteCounter, Lazy, Option } from "@opendaw/lib-std";
12
+ import { PointerHub } from "./pointer-hub";
13
+ import { Serializer } from "./serializer";
14
+ export class Box {
15
+ static DEBUG_DELETION = false;
16
+ static Index = 0 | 0;
17
+ #address;
18
+ #graph;
19
+ #name;
20
+ #pointerRules;
21
+ #fields;
22
+ #creationIndex = Box.Index++;
23
+ constructor({ uuid, graph, name, pointerRules }) {
24
+ this.#address = Address.compose(uuid);
25
+ this.#graph = graph;
26
+ this.#name = name;
27
+ this.#pointerRules = pointerRules;
28
+ this.#fields = this.initializeFields();
29
+ if (pointerRules.mandatory) {
30
+ this.graph.edges().watchVertex(this);
31
+ }
32
+ }
33
+ fields() { return Object.values(this.#fields); }
34
+ getField(key) { return asDefined(this.#fields[key]); }
35
+ optField(key) { return Option.wrap(this.#fields[key]); }
36
+ subscribe(propagation, procedure) {
37
+ return this.graph.subscribeVertexUpdates(propagation, this.address, procedure);
38
+ }
39
+ get box() { return this; }
40
+ get name() { return this.#name; }
41
+ get graph() { return this.#graph; }
42
+ get parent() { return this; }
43
+ get address() { return this.#address; }
44
+ get pointerRules() { return this.#pointerRules; }
45
+ get creationIndex() { return this.#creationIndex; }
46
+ get pointerHub() { return new PointerHub(this); }
47
+ estimateMemory() {
48
+ const byteCounter = new ByteCounter();
49
+ this.write(byteCounter);
50
+ return byteCounter.count;
51
+ }
52
+ isBox() { return true; }
53
+ isField() { return false; }
54
+ isAttached() { return this.#graph.findBox(this.address.uuid).nonEmpty(); }
55
+ read(input) { Serializer.readFields(input, this.#fields); }
56
+ write(output) { Serializer.writeFields(output, this.#fields); }
57
+ serialize() {
58
+ const output = ByteArrayOutput.create();
59
+ output.writeInt(this.#creationIndex); // allows to re-load the boxes in same order as created
60
+ output.writeString(this.name);
61
+ output.writeBytes(new Int8Array(this.address.uuid.buffer));
62
+ this.write(output);
63
+ return output.toArrayBuffer();
64
+ }
65
+ toArrayBuffer() {
66
+ const output = ByteArrayOutput.create();
67
+ this.write(output);
68
+ return output.toArrayBuffer();
69
+ }
70
+ incomingEdges() { return this.graph.edges().incomingEdgesOf(this); }
71
+ outgoingEdges() { return this.graph.edges().outgoingEdgesOf(this); }
72
+ mapFields(map, ...keys) {
73
+ if (keys.length === 0) {
74
+ return Arrays.empty();
75
+ }
76
+ let parent = this.getField(keys[0]);
77
+ const result = [map(parent)];
78
+ for (let index = 1; index < keys.length; index++) {
79
+ parent = parent.getField(keys[index]);
80
+ result.push(map(parent));
81
+ }
82
+ return result;
83
+ }
84
+ searchVertex(keys) {
85
+ if (keys.length === 0) {
86
+ return Option.wrap(this);
87
+ }
88
+ let parent = this.optField(keys[0]);
89
+ if (parent.isEmpty()) {
90
+ return Option.None;
91
+ }
92
+ for (let index = 1; index < keys.length; index++) {
93
+ parent = parent.unwrap().optField(keys[index]);
94
+ if (parent.isEmpty()) {
95
+ return Option.None;
96
+ }
97
+ }
98
+ return parent;
99
+ }
100
+ delete() {
101
+ const { boxes, pointers } = this.graph.dependenciesOf(this);
102
+ if (Box.DEBUG_DELETION) {
103
+ console.debug(`Delete ${this.toString()}`);
104
+ console.debug("\tunplugs", [...pointers].map(x => x.toString()).join("\n"));
105
+ console.debug("\tunstages", [...boxes].map(x => x.toString()).join("\n"), this);
106
+ }
107
+ for (const pointer of pointers) {
108
+ pointer.defer();
109
+ }
110
+ for (const box of boxes) {
111
+ box.unstage();
112
+ }
113
+ this.unstage();
114
+ }
115
+ unstage() { this.graph.unstageBox(this); }
116
+ toString() { return `${this.constructor.name} ${this.address.toString()}`; }
117
+ }
118
+ __decorate([
119
+ Lazy,
120
+ __metadata("design:type", PointerHub),
121
+ __metadata("design:paramtypes", [])
122
+ ], Box.prototype, "pointerHub", null);
@@ -0,0 +1,16 @@
1
+ import { int, Procedure, Subscription } from "@opendaw/lib-std";
2
+ import { Address, Addressable } from "./address";
3
+ export declare enum Propagation {
4
+ This = 0,
5
+ Parent = 1,
6
+ Children = 2
7
+ }
8
+ export interface Dispatchers<TARGET extends Addressable> {
9
+ subscribe(propagation: Propagation, address: Address, procedure: Procedure<TARGET>): Subscription;
10
+ dispatch(target: TARGET): void;
11
+ countStations(): int;
12
+ }
13
+ export declare namespace Dispatchers {
14
+ const create: <TARGET extends Addressable>() => Dispatchers<TARGET>;
15
+ }
16
+ //# sourceMappingURL=dispatchers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatchers.d.ts","sourceRoot":"","sources":["../src/dispatchers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAwB,MAAM,kBAAkB,CAAA;AACpF,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,MAAM,WAAW,CAAA;AAE9C,oBAAY,WAAW;IAAE,IAAI,IAAA;IAAE,MAAM,IAAA;IAAE,QAAQ,IAAA;CAAC;AAEhD,MAAM,WAAW,WAAW,CAAC,MAAM,SAAS,WAAW;IACnD,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,YAAY,CAAA;IACjG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,aAAa,IAAI,GAAG,CAAA;CACvB;AAED,yBAAiB,WAAW,CAAC;IAClB,MAAM,MAAM,GAAI,MAAM,SAAS,WAAW,OAAK,WAAW,CAAC,MAAM,CAAkC,CAAA;CAC7G"}
@@ -0,0 +1,127 @@
1
+ import { Terminator, Unhandled } from "@opendaw/lib-std";
2
+ import { Addressable } from "./address";
3
+ export var Propagation;
4
+ (function (Propagation) {
5
+ Propagation[Propagation["This"] = 0] = "This";
6
+ Propagation[Propagation["Parent"] = 1] = "Parent";
7
+ Propagation[Propagation["Children"] = 2] = "Children";
8
+ })(Propagation || (Propagation = {}));
9
+ export var Dispatchers;
10
+ (function (Dispatchers) {
11
+ Dispatchers.create = () => new DispatchersImpl();
12
+ })(Dispatchers || (Dispatchers = {}));
13
+ class DispatchersImpl {
14
+ #thisDispatcher = new Dispatcher(Addressable.equals);
15
+ #parentDispatcher = new Dispatcher(Addressable.startsWith);
16
+ #childrenDispatcher = new Dispatcher(Addressable.endsWith);
17
+ #deferredStations = [];
18
+ #order = 0 | 0;
19
+ #dispatching = false;
20
+ subscribe(propagation, address, procedure) {
21
+ const monitor = new Monitor(address, propagation, this.#order++, procedure);
22
+ if (this.#dispatching) {
23
+ const deferred = new DeferredMonitor(monitor, propagation);
24
+ this.#deferredStations.push(deferred);
25
+ return deferred;
26
+ }
27
+ else {
28
+ return this.subscribeMonitor(monitor, propagation);
29
+ }
30
+ }
31
+ dispatch(target) {
32
+ this.#dispatching = true;
33
+ const invoked = [
34
+ ...this.#thisDispatcher.filter(target),
35
+ ...this.#parentDispatcher.filter(target),
36
+ ...this.#childrenDispatcher.filter(target)
37
+ ];
38
+ invoked
39
+ .sort(({ order: a }, { order: b }) => a - b)
40
+ .forEach((station) => station.procedure(target));
41
+ this.#dispatching = false;
42
+ this.#deferredStations.forEach((station) => station.subscribe(this));
43
+ this.#deferredStations.length = 0;
44
+ }
45
+ subscribeMonitor(monitor, propagation) {
46
+ switch (propagation) {
47
+ case Propagation.This:
48
+ return this.#thisDispatcher.subscribe(monitor);
49
+ case Propagation.Parent:
50
+ return this.#parentDispatcher.subscribe(monitor);
51
+ case Propagation.Children:
52
+ return this.#childrenDispatcher.subscribe(monitor);
53
+ default:
54
+ return Unhandled(propagation);
55
+ }
56
+ }
57
+ countStations() {
58
+ return this.#thisDispatcher.count() + this.#parentDispatcher.count() + this.#childrenDispatcher.count();
59
+ }
60
+ }
61
+ class Monitor {
62
+ address;
63
+ propagation;
64
+ order;
65
+ procedure;
66
+ constructor(address, propagation, order, procedure) {
67
+ this.address = address;
68
+ this.propagation = propagation;
69
+ this.order = order;
70
+ this.procedure = procedure;
71
+ }
72
+ toString() {
73
+ return `{ Monitor address: ${this.address}, propagation: ${Propagation[this.propagation]}, order: ${this.order} }`;
74
+ }
75
+ }
76
+ class Dispatcher {
77
+ filterStrategy;
78
+ #monitors = [];
79
+ #sorted = true;
80
+ constructor(filterStrategy) {
81
+ this.filterStrategy = filterStrategy;
82
+ }
83
+ subscribe(monitor) {
84
+ this.#monitors.push(monitor);
85
+ this.#sorted = this.#monitors.length < 2;
86
+ return {
87
+ terminate: () => {
88
+ let index = this.#monitors.length;
89
+ while (--index >= 0) {
90
+ if (this.#monitors[index] === monitor) {
91
+ this.#monitors.splice(index, 1);
92
+ }
93
+ }
94
+ }
95
+ };
96
+ }
97
+ stations() {
98
+ if (!this.#sorted) {
99
+ this.#monitors.sort(Addressable.Comparator);
100
+ this.#sorted = true;
101
+ }
102
+ return this.#monitors;
103
+ }
104
+ filter(target) { return this.filterStrategy(target.address, this.stations()); }
105
+ count() { return this.#monitors.length; }
106
+ }
107
+ class DeferredMonitor {
108
+ monitor;
109
+ propagation;
110
+ #terminator = new Terminator();
111
+ #terminated = false;
112
+ constructor(monitor, propagation) {
113
+ this.monitor = monitor;
114
+ this.propagation = propagation;
115
+ }
116
+ subscribe(dispatchers) {
117
+ if (this.#terminated) {
118
+ return;
119
+ }
120
+ this.#terminator.terminate();
121
+ this.#terminator.own(dispatchers.subscribeMonitor(this.monitor, this.propagation));
122
+ }
123
+ terminate() {
124
+ this.#terminated = true;
125
+ this.#terminator.terminate();
126
+ }
127
+ }
@@ -0,0 +1,21 @@
1
+ import { BoxGraph } from "./graph";
2
+ import { Nullish, Option, Provider } from "@opendaw/lib-std";
3
+ export interface ModificationProcess {
4
+ approve(): void;
5
+ revert(): void;
6
+ }
7
+ export declare class Editing {
8
+ #private;
9
+ constructor(graph: BoxGraph);
10
+ get graph(): BoxGraph;
11
+ isEmpty(): boolean;
12
+ clear(): void;
13
+ undo(): boolean;
14
+ redo(): boolean;
15
+ canModify(): boolean;
16
+ modify<R>(modifier: Provider<Nullish<R>>, mark?: boolean): Option<R>;
17
+ beginModification(): ModificationProcess;
18
+ mark(): void;
19
+ clearPending(): void;
20
+ }
21
+ //# sourceMappingURL=editing.d.ts.map
@@ -0,0 +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,EAAsB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAiB/E,MAAM,WAAW,mBAAmB;IAChC,OAAO,IAAI,IAAI,CAAA;IACf,MAAM,IAAI,IAAI,CAAA;CACjB;AAED,qBAAa,OAAO;;gBASJ,KAAK,EAAE,QAAQ;IAI3B,IAAI,KAAK,IAAI,QAAQ,CAAqB;IAE1C,OAAO,IAAI,OAAO;IAElB,KAAK,IAAI,IAAI;IAOb,IAAI,IAAI,OAAO;IAWf,IAAI,IAAI,OAAO;IAef,SAAS,IAAI,OAAO;IAEpB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,OAAc,GAAG,MAAM,CAAC,CAAC,CAAC;IAW1E,iBAAiB,IAAI,mBAAmB;IAoCxC,IAAI,IAAI,IAAI;IAOZ,YAAY,IAAI,IAAI;CAKvB"}