dazscript-framework 0.1.15 → 0.1.17
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 +365 -93
- package/babel.config.js +33 -33
- package/dist/babel/trace-babel-plugin.js +243 -243
- package/dist/babel/trace-log-babel-plugin.js +164 -164
- package/dist/scripts/install-generator.js +185 -185
- package/package.json +72 -70
- package/src/common/dz-dump.ts +120 -120
- package/src/common/log.ts +56 -56
- package/src/common/trace.ts +26 -26
- package/src/core/action-decorator.ts +15 -15
- package/src/core/base-script.ts +30 -30
- package/src/core/custom-action.ts +11 -11
- package/src/core/global.ts +4 -4
- package/src/dialog/basic-dialog.ts +40 -32
- package/src/dialog/builders/button-builder.ts +52 -52
- package/src/dialog/builders/checkbox-builder.ts +29 -29
- package/src/dialog/builders/color-picker-builder.ts +35 -35
- package/src/dialog/builders/combo-box-builder.ts +38 -35
- package/src/dialog/builders/combo-edit-builder.ts +35 -35
- package/src/dialog/builders/dialog-builder.ts +49 -49
- package/src/dialog/builders/groupbox-builder.ts +121 -82
- package/src/dialog/builders/label-builder.ts +33 -28
- package/src/dialog/builders/layout-builder.ts +59 -59
- package/src/dialog/builders/line-edit-builder.ts +124 -119
- package/src/dialog/builders/list-box-builder.ts +103 -0
- package/src/dialog/builders/list-view-builder.ts +396 -328
- package/src/dialog/builders/node-selection-builder.ts +55 -55
- package/src/dialog/builders/path-combo-box-builder.ts +24 -24
- package/src/dialog/builders/popup-menu-builder.ts +46 -46
- package/src/dialog/builders/radio-builder.ts +42 -42
- package/src/dialog/builders/slider-builder.ts +39 -22
- package/src/dialog/builders/splitter-builder.ts +88 -88
- package/src/dialog/builders/tab-builder.ts +120 -106
- package/src/dialog/builders/widget-builder.ts +136 -124
- package/src/dialog/builders/widgets-builder.ts +140 -135
- package/src/dialog/input-dialog.ts +30 -27
- package/src/dialog/input-validator.ts +8 -8
- package/src/dialog/selection-dialog.ts +47 -0
- package/src/dialog/shared.ts +8 -8
- package/src/helpers/action-helper.ts +214 -81
- package/src/helpers/array-helper.ts +170 -145
- package/src/helpers/camera-helper.ts +12 -12
- package/src/helpers/custom-action-helper.ts +176 -176
- package/src/helpers/directory-helper.ts +14 -0
- package/src/helpers/file-helper.ts +90 -90
- package/src/helpers/http-helper.ts +190 -0
- package/src/helpers/input-helper.ts +18 -18
- package/src/helpers/list-view-helper.ts +105 -89
- package/src/helpers/menu-helper.ts +28 -28
- package/src/helpers/message-box-helper.ts +25 -15
- package/src/helpers/node-helper.ts +461 -236
- package/src/helpers/number-helper.ts +10 -10
- package/src/helpers/numeric-property-helper.ts +91 -91
- package/src/helpers/object-helper.ts +2 -2
- package/src/helpers/pane-helper.ts +28 -20
- package/src/helpers/progress-helper.ts +51 -33
- package/src/helpers/property-helper.ts +61 -52
- package/src/helpers/record-helper.ts +16 -16
- package/src/helpers/scene-helper.ts +144 -94
- package/src/helpers/script-helper.ts +15 -15
- package/src/helpers/skeleton-helper.ts +26 -26
- package/src/helpers/splitter-helper.ts +8 -8
- package/src/helpers/string-helper.ts +39 -31
- package/src/helpers/surface-helper.ts +5 -5
- package/src/helpers/undo-helper.ts +8 -8
- package/src/helpers/viewport-helper.ts +21 -8
- package/src/lib/delayed.ts +38 -38
- package/src/lib/dictionary.ts +3 -0
- package/src/lib/frame-keys.ts +67 -67
- package/src/lib/guid.ts +2 -2
- package/src/lib/menu-item.ts +10 -9
- package/src/lib/observable.ts +147 -94
- package/src/lib/set.ts +50 -25
- package/src/lib/settings.ts +112 -104
- package/src/lib/tree-node.ts +149 -145
- package/src/samples/config.ts +2 -2
- package/src/samples/hello-world.dsa.ts +12 -12
- package/src/samples/sample-dialog.dsa.ts +51 -51
- package/src/samples/sample-dialog.ts +48 -48
- package/src/shared/set-keyboard-shortcut.ts +146 -102
- package/tsconfig.json +116 -116
- package/webpack.config.js +70 -70
package/src/lib/frame-keys.ts
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import { find } from '@dsf/helpers/array-helper';
|
|
2
|
-
|
|
3
|
-
export class PropertyKey {
|
|
4
|
-
index: number
|
|
5
|
-
frame: number = 0
|
|
6
|
-
time: DzTime
|
|
7
|
-
value: number
|
|
8
|
-
|
|
9
|
-
toJSON(): Object {
|
|
10
|
-
return {
|
|
11
|
-
index: this.index,
|
|
12
|
-
time: this.time.valueOf(),
|
|
13
|
-
frame: this.frame,
|
|
14
|
-
value: this.value,
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class PropertyKeys {
|
|
20
|
-
constructor(private _items: PropertyKey[]) {
|
|
21
|
-
if (!this._items) this._items = [];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
forEach(callback: (key: PropertyKey) => any) {
|
|
25
|
-
this._items.forEach(key => {
|
|
26
|
-
callback(key);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
get items(): PropertyKey[] {
|
|
31
|
-
return this._items;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get first(): PropertyKey | null {
|
|
35
|
-
return this._items[0]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
get length(): number {
|
|
39
|
-
return this._items.length;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get current(): PropertyKey {
|
|
43
|
-
return find(this._items, k => k.time.valueOf() == Scene.getTime().valueOf())
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
get previous(): PropertyKey {
|
|
47
|
-
return find(this._items.sort((a, b) => b.index - a.index), k => k.time.valueOf() < Scene.getTime().valueOf())
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get next(): PropertyKey {
|
|
51
|
-
return find(this._items, k => k.time.valueOf() > Scene.getTime().valueOf())
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Given the animation frame number or time, return the property key
|
|
56
|
-
* @param frameorTime frame number or time
|
|
57
|
-
* @returns the property key
|
|
58
|
-
*/
|
|
59
|
-
at(frameorTime: number | DzTime): PropertyKey | null {
|
|
60
|
-
return typeof frameorTime === 'number'
|
|
61
|
-
? find(this._items, k => k.frame === frameorTime)
|
|
62
|
-
: find(this._items, k => k.time === frameorTime)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
any(): boolean {
|
|
66
|
-
return this.items.length > 0
|
|
67
|
-
}
|
|
1
|
+
import { find } from '@dsf/helpers/array-helper';
|
|
2
|
+
|
|
3
|
+
export class PropertyKey {
|
|
4
|
+
index: number
|
|
5
|
+
frame: number = 0
|
|
6
|
+
time: DzTime
|
|
7
|
+
value: number
|
|
8
|
+
|
|
9
|
+
toJSON(): Object {
|
|
10
|
+
return {
|
|
11
|
+
index: this.index,
|
|
12
|
+
time: this.time.valueOf(),
|
|
13
|
+
frame: this.frame,
|
|
14
|
+
value: this.value,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class PropertyKeys {
|
|
20
|
+
constructor(private _items: PropertyKey[]) {
|
|
21
|
+
if (!this._items) this._items = [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
forEach(callback: (key: PropertyKey) => any) {
|
|
25
|
+
this._items.forEach(key => {
|
|
26
|
+
callback(key);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get items(): PropertyKey[] {
|
|
31
|
+
return this._items;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get first(): PropertyKey | null {
|
|
35
|
+
return this._items[0]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get length(): number {
|
|
39
|
+
return this._items.length;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get current(): PropertyKey {
|
|
43
|
+
return find(this._items, k => k.time.valueOf() == Scene.getTime().valueOf())
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get previous(): PropertyKey {
|
|
47
|
+
return find(this._items.sort((a, b) => b.index - a.index), k => k.time.valueOf() < Scene.getTime().valueOf())
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get next(): PropertyKey {
|
|
51
|
+
return find(this._items, k => k.time.valueOf() > Scene.getTime().valueOf())
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Given the animation frame number or time, return the property key
|
|
56
|
+
* @param frameorTime frame number or time
|
|
57
|
+
* @returns the property key
|
|
58
|
+
*/
|
|
59
|
+
at(frameorTime: number | DzTime): PropertyKey | null {
|
|
60
|
+
return typeof frameorTime === 'number'
|
|
61
|
+
? find(this._items, k => k.frame === frameorTime)
|
|
62
|
+
: find(this._items, k => k.time === frameorTime)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
any(): boolean {
|
|
66
|
+
return this.items.length > 0
|
|
67
|
+
}
|
|
68
68
|
}
|
package/src/lib/guid.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export const createUID = (): string => {
|
|
2
|
-
return "uuid-" + ((new Date).getTime().toString(16) + Math.floor(1E7 * Math.random()).toString(16));
|
|
1
|
+
export const createUID = (): string => {
|
|
2
|
+
return "uuid-" + ((new Date).getTime().toString(16) + Math.floor(1E7 * Math.random()).toString(16));
|
|
3
3
|
}
|
package/src/lib/menu-item.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export type MenuItem = {
|
|
2
|
-
description: string
|
|
3
|
-
shortcut: string
|
|
4
|
-
name: string
|
|
5
|
-
label: string
|
|
6
|
-
path: string
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
export type MenuItem = {
|
|
2
|
+
description: string
|
|
3
|
+
shortcut: string
|
|
4
|
+
name: string
|
|
5
|
+
label: string
|
|
6
|
+
path: string
|
|
7
|
+
filePath?: string
|
|
8
|
+
icon: string
|
|
9
|
+
hidden: boolean
|
|
10
|
+
}
|
package/src/lib/observable.ts
CHANGED
|
@@ -1,94 +1,147 @@
|
|
|
1
|
-
export class Observable<T> {
|
|
2
|
-
protected _value: T;
|
|
3
|
-
private _beforeChange
|
|
4
|
-
private
|
|
5
|
-
private
|
|
6
|
-
private _paused
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
1
|
+
export class Observable<T> {
|
|
2
|
+
protected _value: T;
|
|
3
|
+
private _beforeChange?: (previous: T, current: T) => T;
|
|
4
|
+
private _afterChange?: (previous: T, current: T) => T;
|
|
5
|
+
private _onChange: Array<(value: T) => void> = [];
|
|
6
|
+
private _paused = false;
|
|
7
|
+
|
|
8
|
+
// NEW: guards + comparator
|
|
9
|
+
private _isSetting = false;
|
|
10
|
+
private _pendingValue?: T; // last requested value during an active set
|
|
11
|
+
private _equals: (a: T, b: T) => boolean;
|
|
12
|
+
private static readonly MAX_AFTER_CHANGE_DEPTH = 10;
|
|
13
|
+
private static readonly MAX_CHAINED_SETS = 100; // limit for cascading listener-driven sets
|
|
14
|
+
|
|
15
|
+
constructor(value?: T, onChange?: (value: T) => void, equals?: (a: T, b: T) => boolean) {
|
|
16
|
+
this._value = value as T;
|
|
17
|
+
if (onChange) this._onChange.push(onChange);
|
|
18
|
+
this._equals = equals ?? ((a, b) => a === b);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get value(): T { return this._value; }
|
|
22
|
+
|
|
23
|
+
set value(next: T) {
|
|
24
|
+
// Coalesce: if actively setting, just remember the latest requested value.
|
|
25
|
+
if (this._isSetting) { this._pendingValue = next; return; }
|
|
26
|
+
|
|
27
|
+
let currentRequested: T | undefined = next;
|
|
28
|
+
let chainedSets = 0;
|
|
29
|
+
let afterDepth = 0;
|
|
30
|
+
|
|
31
|
+
while (currentRequested !== undefined) {
|
|
32
|
+
const prev = this._value;
|
|
33
|
+
let candidate = this._beforeChange?.(prev, currentRequested) ?? currentRequested;
|
|
34
|
+
currentRequested = undefined; // consume
|
|
35
|
+
|
|
36
|
+
if (this._equals(prev, candidate)) {
|
|
37
|
+
// No actual change; ignore any pending identical value.
|
|
38
|
+
this._pendingValue = undefined;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this._isSetting = true;
|
|
43
|
+
this._value = candidate;
|
|
44
|
+
if (!this._paused) this._onChange.slice().forEach(cb => cb(this._value));
|
|
45
|
+
|
|
46
|
+
// Apply afterChange transformations (bounded)
|
|
47
|
+
let transformed = this._afterChange?.(prev, this._value);
|
|
48
|
+
while (transformed !== undefined && !this._equals(this._value, transformed)) {
|
|
49
|
+
afterDepth++;
|
|
50
|
+
if (afterDepth > Observable.MAX_AFTER_CHANGE_DEPTH) {
|
|
51
|
+
this._isSetting = false;
|
|
52
|
+
this._pendingValue = undefined;
|
|
53
|
+
throw new Error(`Observable: _afterChange exceeded depth ${Observable.MAX_AFTER_CHANGE_DEPTH}. Possible loop.`);
|
|
54
|
+
}
|
|
55
|
+
this._value = transformed;
|
|
56
|
+
if (!this._paused) this._onChange.slice().forEach(cb => cb(this._value));
|
|
57
|
+
transformed = this._afterChange?.(prev, this._value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this._isSetting = false;
|
|
61
|
+
|
|
62
|
+
// If a listener requested a new value during this cycle, process it
|
|
63
|
+
if (this._pendingValue !== undefined && !this._equals(this._value, this._pendingValue)) {
|
|
64
|
+
currentRequested = this._pendingValue;
|
|
65
|
+
this._pendingValue = undefined;
|
|
66
|
+
chainedSets++;
|
|
67
|
+
if (chainedSets > Observable.MAX_CHAINED_SETS) {
|
|
68
|
+
throw new Error(`Observable: Too many chained set operations (>${Observable.MAX_CHAINED_SETS}). Possible loop.`);
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
// Either no pending or it's same-value;
|
|
72
|
+
this._pendingValue = undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
connect(onChange: (value: T) => void): this {
|
|
78
|
+
if (this._onChange.indexOf(onChange) === -1) this._onChange.push(onChange);
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
intercept(
|
|
83
|
+
beforeChange: (previous: T, current: T) => T,
|
|
84
|
+
afterChange?: (previous: T, current: T) => T
|
|
85
|
+
): this {
|
|
86
|
+
this._beforeChange = beforeChange;
|
|
87
|
+
this._afterChange = afterChange;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
disconnect(onChange: (value: T) => void) {
|
|
92
|
+
const i = this._onChange.indexOf(onChange);
|
|
93
|
+
if (i > -1) this._onChange.splice(i, 1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
trigger(): void {
|
|
97
|
+
if (!this._paused) this._onChange.slice().forEach(cb => cb(this._value));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
pause(callback?: () => void): void {
|
|
101
|
+
this._paused = true;
|
|
102
|
+
callback?.();
|
|
103
|
+
this.resume();
|
|
104
|
+
}
|
|
105
|
+
resume(): void { this._paused = false; }
|
|
106
|
+
|
|
107
|
+
// Optional: silent set (no callbacks) for derived/computed cases
|
|
108
|
+
setSilently(next: T): void { this._value = next; }
|
|
109
|
+
|
|
110
|
+
toJSON() { return this._value; }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export class BooleanObservable extends Observable<boolean> {
|
|
114
|
+
private combined: BooleanObservable[] = [];
|
|
115
|
+
private _isUpdatingFromCombined = false;
|
|
116
|
+
|
|
117
|
+
combine(...observables: BooleanObservable[]): this {
|
|
118
|
+
observables.forEach(obs => {
|
|
119
|
+
// Prevent circular references
|
|
120
|
+
if (obs === this) {
|
|
121
|
+
throw new Error('BooleanObservable: Cannot combine with itself');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this.combined.push(obs);
|
|
125
|
+
obs.connect(() => {
|
|
126
|
+
// Prevent circular updates
|
|
127
|
+
if (this._isUpdatingFromCombined) return;
|
|
128
|
+
|
|
129
|
+
this._isUpdatingFromCombined = true;
|
|
130
|
+
try {
|
|
131
|
+
this.value = this.combined.every(b => b.value);
|
|
132
|
+
} finally {
|
|
133
|
+
this._isUpdatingFromCombined = false;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
// initialize once
|
|
138
|
+
this._isUpdatingFromCombined = true;
|
|
139
|
+
try {
|
|
140
|
+
this.value = this.combined.every(b => b.value);
|
|
141
|
+
} finally {
|
|
142
|
+
this._isUpdatingFromCombined = false;
|
|
143
|
+
}
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
package/src/lib/set.ts
CHANGED
|
@@ -1,25 +1,50 @@
|
|
|
1
|
-
export default class CustomSet<T> {
|
|
2
|
-
private items: Record<string, T> = {};
|
|
3
|
-
|
|
4
|
-
add(item: T): void {
|
|
5
|
-
const key = this.getKey(item);
|
|
6
|
-
this.items[key] = item;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
has(item: T): boolean {
|
|
10
|
-
const key = this.getKey(item);
|
|
11
|
-
return key in this.items;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
export default class CustomSet<T> {
|
|
2
|
+
private items: Record<string, T> = {};
|
|
3
|
+
|
|
4
|
+
add(item: T): void {
|
|
5
|
+
const key = this.getKey(item);
|
|
6
|
+
this.items[key] = item;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
has(item: T): boolean {
|
|
10
|
+
const key = this.getKey(item);
|
|
11
|
+
return key in this.items;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
remove(item: T): void {
|
|
15
|
+
const key = this.getKey(item);
|
|
16
|
+
delete this.items[key];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
clear(): void {
|
|
20
|
+
this.items = {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
forEach(callback: (item: T) => void): void {
|
|
24
|
+
for (const key in this.items) {
|
|
25
|
+
if (this.items.hasOwnProperty(key)) {
|
|
26
|
+
callback(this.items[key]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private getKey(item: T): string {
|
|
32
|
+
if (typeof item === 'object') {
|
|
33
|
+
// For object items, use a unique identifier (e.g., JSON string) as the key
|
|
34
|
+
return JSON.stringify(item);
|
|
35
|
+
}
|
|
36
|
+
return String(item);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
values(): T[] {
|
|
40
|
+
let values: T[] = [];
|
|
41
|
+
|
|
42
|
+
for (const key in this.items) {
|
|
43
|
+
if (this.items.hasOwnProperty(key)) {
|
|
44
|
+
values.push(this.items[key]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return values;
|
|
49
|
+
}
|
|
50
|
+
}
|