proxy-facades 1.0.0

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 (136) hide show
  1. package/.idea/.name +1 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/proxy-facades.iml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/DEVELOPMENT.md +15 -0
  6. package/LICENSE +21 -0
  7. package/RecordedReadOnProxiedObjectExt.d.ts +22 -0
  8. package/RecordedReadOnProxiedObjectExt.d.ts.map +1 -0
  9. package/RecordedReadOnProxiedObjectExt.js +41 -0
  10. package/RecordedReadOnProxiedObjectExt.js.map +1 -0
  11. package/RecordedReadOnProxiedObjectExt.ts +41 -0
  12. package/Util.d.ts +85 -0
  13. package/Util.d.ts.map +1 -0
  14. package/Util.js +239 -0
  15. package/Util.js.map +1 -0
  16. package/Util.ts +254 -0
  17. package/class-trackers/Array.d.ts +93 -0
  18. package/class-trackers/Array.d.ts.map +1 -0
  19. package/class-trackers/Array.js +193 -0
  20. package/class-trackers/Array.js.map +1 -0
  21. package/class-trackers/Array.ts +245 -0
  22. package/class-trackers/Iterator.d.ts +38 -0
  23. package/class-trackers/Iterator.d.ts.map +1 -0
  24. package/class-trackers/Iterator.js +69 -0
  25. package/class-trackers/Iterator.js.map +1 -0
  26. package/class-trackers/Iterator.ts +73 -0
  27. package/class-trackers/Map.d.ts +128 -0
  28. package/class-trackers/Map.d.ts.map +1 -0
  29. package/class-trackers/Map.js +310 -0
  30. package/class-trackers/Map.js.map +1 -0
  31. package/class-trackers/Map.ts +403 -0
  32. package/class-trackers/Set.d.ts +85 -0
  33. package/class-trackers/Set.d.ts.map +1 -0
  34. package/class-trackers/Set.js +197 -0
  35. package/class-trackers/Set.js.map +1 -0
  36. package/class-trackers/Set.ts +245 -0
  37. package/class-trackers/index.d.ts +7 -0
  38. package/class-trackers/index.d.ts.map +1 -0
  39. package/class-trackers/index.js +36 -0
  40. package/class-trackers/index.js.map +1 -0
  41. package/class-trackers/index.ts +38 -0
  42. package/class-trackers/readme.md +2 -0
  43. package/common.d.ts +235 -0
  44. package/common.d.ts.map +1 -0
  45. package/common.js +378 -0
  46. package/common.js.map +1 -0
  47. package/common.ts +501 -0
  48. package/dev_generateEsRuntimeBehaviourCheckerCode.d.ts +10 -0
  49. package/dev_generateEsRuntimeBehaviourCheckerCode.d.ts.map +1 -0
  50. package/dev_generateEsRuntimeBehaviourCheckerCode.js +76 -0
  51. package/dev_generateEsRuntimeBehaviourCheckerCode.js.map +1 -0
  52. package/dev_generateEsRuntimeBehaviourCheckerCode.ts +85 -0
  53. package/dist/mjs/RecordedReadOnProxiedObjectExt.d.ts +22 -0
  54. package/dist/mjs/RecordedReadOnProxiedObjectExt.d.ts.map +1 -0
  55. package/dist/mjs/RecordedReadOnProxiedObjectExt.js +37 -0
  56. package/dist/mjs/RecordedReadOnProxiedObjectExt.js.map +1 -0
  57. package/dist/mjs/Util.d.ts +85 -0
  58. package/dist/mjs/Util.d.ts.map +1 -0
  59. package/dist/mjs/Util.js +223 -0
  60. package/dist/mjs/Util.js.map +1 -0
  61. package/dist/mjs/class-trackers/Array.d.ts +93 -0
  62. package/dist/mjs/class-trackers/Array.d.ts.map +1 -0
  63. package/dist/mjs/class-trackers/Array.js +186 -0
  64. package/dist/mjs/class-trackers/Array.js.map +1 -0
  65. package/dist/mjs/class-trackers/Iterator.d.ts +38 -0
  66. package/dist/mjs/class-trackers/Iterator.d.ts.map +1 -0
  67. package/dist/mjs/class-trackers/Iterator.js +65 -0
  68. package/dist/mjs/class-trackers/Iterator.js.map +1 -0
  69. package/dist/mjs/class-trackers/Map.d.ts +128 -0
  70. package/dist/mjs/class-trackers/Map.d.ts.map +1 -0
  71. package/dist/mjs/class-trackers/Map.js +299 -0
  72. package/dist/mjs/class-trackers/Map.js.map +1 -0
  73. package/dist/mjs/class-trackers/Set.d.ts +85 -0
  74. package/dist/mjs/class-trackers/Set.d.ts.map +1 -0
  75. package/dist/mjs/class-trackers/Set.js +189 -0
  76. package/dist/mjs/class-trackers/Set.js.map +1 -0
  77. package/dist/mjs/class-trackers/index.d.ts +7 -0
  78. package/dist/mjs/class-trackers/index.d.ts.map +1 -0
  79. package/dist/mjs/class-trackers/index.js +32 -0
  80. package/dist/mjs/class-trackers/index.js.map +1 -0
  81. package/dist/mjs/common.d.ts +235 -0
  82. package/dist/mjs/common.d.ts.map +1 -0
  83. package/dist/mjs/common.js +361 -0
  84. package/dist/mjs/common.js.map +1 -0
  85. package/dist/mjs/dev_generateEsRuntimeBehaviourCheckerCode.d.ts +10 -0
  86. package/dist/mjs/dev_generateEsRuntimeBehaviourCheckerCode.d.ts.map +1 -0
  87. package/dist/mjs/dev_generateEsRuntimeBehaviourCheckerCode.js +76 -0
  88. package/dist/mjs/dev_generateEsRuntimeBehaviourCheckerCode.js.map +1 -0
  89. package/dist/mjs/index.d.ts +8 -0
  90. package/dist/mjs/index.d.ts.map +1 -0
  91. package/dist/mjs/index.js +8 -0
  92. package/dist/mjs/index.js.map +1 -0
  93. package/dist/mjs/objectChangeTracking.d.ts +43 -0
  94. package/dist/mjs/objectChangeTracking.d.ts.map +1 -0
  95. package/dist/mjs/objectChangeTracking.js +209 -0
  96. package/dist/mjs/objectChangeTracking.js.map +1 -0
  97. package/dist/mjs/origChangeTracking.d.ts +14 -0
  98. package/dist/mjs/origChangeTracking.d.ts.map +1 -0
  99. package/dist/mjs/origChangeTracking.js +58 -0
  100. package/dist/mjs/origChangeTracking.js.map +1 -0
  101. package/dist/mjs/proxyFacade.d.ts +45 -0
  102. package/dist/mjs/proxyFacade.d.ts.map +1 -0
  103. package/dist/mjs/proxyFacade.js +179 -0
  104. package/dist/mjs/proxyFacade.js.map +1 -0
  105. package/dist/mjs/watchedProxyFacade.d.ts +84 -0
  106. package/dist/mjs/watchedProxyFacade.d.ts.map +1 -0
  107. package/dist/mjs/watchedProxyFacade.js +300 -0
  108. package/dist/mjs/watchedProxyFacade.js.map +1 -0
  109. package/index.d.ts +8 -0
  110. package/index.d.ts.map +1 -0
  111. package/index.js +36 -0
  112. package/index.js.map +1 -0
  113. package/index.ts +7 -0
  114. package/index_esm.mjs +44 -0
  115. package/objectChangeTracking.d.ts +43 -0
  116. package/objectChangeTracking.d.ts.map +1 -0
  117. package/objectChangeTracking.js +214 -0
  118. package/objectChangeTracking.js.map +1 -0
  119. package/objectChangeTracking.ts +251 -0
  120. package/origChangeTracking.d.ts +14 -0
  121. package/origChangeTracking.d.ts.map +1 -0
  122. package/origChangeTracking.js +63 -0
  123. package/origChangeTracking.js.map +1 -0
  124. package/origChangeTracking.ts +72 -0
  125. package/package.json +52 -0
  126. package/proxyFacade.d.ts +45 -0
  127. package/proxyFacade.d.ts.map +1 -0
  128. package/proxyFacade.js +187 -0
  129. package/proxyFacade.js.map +1 -0
  130. package/proxyFacade.ts +222 -0
  131. package/readme.md +111 -0
  132. package/watchedProxyFacade.d.ts +84 -0
  133. package/watchedProxyFacade.d.ts.map +1 -0
  134. package/watchedProxyFacade.js +312 -0
  135. package/watchedProxyFacade.js.map +1 -0
  136. package/watchedProxyFacade.ts +369 -0
@@ -0,0 +1,245 @@
1
+ import {
2
+ ChangeOperation,
3
+ ClassTrackingConfiguration,
4
+ DualUseTracker,
5
+ ForWatchedProxyHandler, IWatchedProxyHandler_common, makeIteratorTranslateValue,
6
+ ObjKey,
7
+ RecordedRead,
8
+ RecordedReadOnProxiedObject, runChangeOperation, UnspecificObjectChange
9
+ } from "../common";
10
+ import {arraysAreShallowlyEqual} from "../Util";
11
+ import {
12
+ getChangeHooksForObject,
13
+ changeHooksForObject
14
+ } from "../objectChangeTracking";
15
+ import {installChangeTracker} from "../origChangeTracking";
16
+ import {WatchedProxyHandler} from "../watchedProxyFacade";
17
+ import {RecordedReadOnProxiedObjectExt} from "../RecordedReadOnProxiedObjectExt";
18
+
19
+
20
+ /**
21
+ * Listeners for one array.
22
+ * Note for specificity: There will be only one of the **change** events fired. The Recorded...Read.onChange handler will add the listeners to all possible candidates. It's this way around.
23
+ * {@link ObjectChangeHooks} are also subscribed on Arrays
24
+ */
25
+ class ArrayChangeHooks {
26
+
27
+ }
28
+
29
+ export const changeHooksForArray = new WeakMap<unknown[], ArrayChangeHooks>();
30
+ export function getChangeHooksForArray(array: unknown[]) {
31
+ let result = changeHooksForArray.get(array);
32
+ if(result === undefined) {
33
+ changeHooksForArray.set(array, result = new ArrayChangeHooks());
34
+ }
35
+ return result;
36
+ }
37
+
38
+ /**
39
+ * Can be either used as a supervisor-class in a WatchedProxyHandler, or installed on the non-proxied object via Object.setPrototypeOf
40
+ * The "this" may be different in these cases.
41
+ */
42
+ export class ArrayChangeTracker<T> extends Array<T> implements DualUseTracker<Array<T>>{
43
+
44
+
45
+ // TODO: In the future, implement more fine granular change listeners that act on change of a certain index.
46
+
47
+ get _watchedProxyHandler(): IWatchedProxyHandler_common | undefined {
48
+ return undefined;
49
+ }
50
+
51
+ protected _withUnspecificChange<R>(changeFn: () => R): R {
52
+ return runChangeOperation(this, new UnspecificObjectChange(this), [getChangeHooksForObject(this).unspecificChange], changeFn)
53
+ }
54
+
55
+ //push(...items: any[]): number //already calls set
56
+
57
+ pop(...args: any[]) {
58
+ return this._withUnspecificChange(() => super.pop())
59
+ }
60
+
61
+ /**
62
+ * Will return the original object when this class is used as supervisor class in the WatchedProxyHandler
63
+ */
64
+ get _target(): Array<T> {
65
+ return this;
66
+ }
67
+
68
+ /**
69
+ * Pretend that this is an array
70
+ */
71
+ get ["constructor"]() {
72
+ return Array;
73
+ }
74
+
75
+ shift(...args: any[]): T | undefined {
76
+ return this._withUnspecificChange(() => super.shift())
77
+ }
78
+
79
+ //@ts-ignore
80
+ sort(...args: any[]): Array<T> {
81
+ return this._withUnspecificChange(()=> super.sort());
82
+ }
83
+
84
+
85
+ //@ts-ignore
86
+ fill(...args: any[]): Array<T> {
87
+ return this._withUnspecificChange(() => super.fill(...args as [any, any, any]));
88
+ }
89
+
90
+ }
91
+
92
+ export class RecordedArrayValuesRead extends RecordedReadOnProxiedObjectExt {
93
+ values: unknown[];
94
+
95
+ protected get origObj() {
96
+ return this.obj as unknown[];
97
+ }
98
+
99
+
100
+ constructor(values: unknown[]) {
101
+ super();
102
+ this.values = values;
103
+ }
104
+
105
+ getAffectingChangeHooks(target: this["obj"]) {
106
+ return [
107
+ getChangeHooksForObject(target).changeOwnKeys,
108
+ getChangeHooksForObject(target).changeAnyProperty,
109
+ getChangeHooksForObject(target).unspecificChange,
110
+ ]
111
+ }
112
+
113
+ equals(other: RecordedRead): boolean {
114
+ if (!(other instanceof RecordedArrayValuesRead)) {
115
+ return false;
116
+ }
117
+
118
+ return this.proxyHandler === other.proxyHandler && this.obj === other.obj && arraysAreShallowlyEqual(this.values, other.values);
119
+ }
120
+
121
+ get isChanged(): boolean {
122
+ return !arraysAreShallowlyEqual(this.values, this.origObj);
123
+ }
124
+
125
+
126
+ }
127
+
128
+ /**
129
+ * Patches methods / accessors
130
+ */
131
+ export class ArrayReadTracker<T> extends Array<T> implements ForWatchedProxyHandler<Array<T>> {
132
+ get _watchedProxyHandler(): WatchedProxyHandler {
133
+ throw new Error("not calling from inside a WatchedProxyHandler"); // Will return the handler when called through the handler
134
+ }
135
+
136
+ get _target(): Array<T> {
137
+ throw new Error("not calling from inside a WatchedProxyHandler"); // Will return the value when called through the handler
138
+ }
139
+
140
+ protected _fireAfterValuesRead() {
141
+ let recordedArrayValuesRead = new RecordedArrayValuesRead([...this._target]);
142
+ this._watchedProxyHandler?.fireAfterRead(recordedArrayValuesRead);
143
+ }
144
+
145
+ /**
146
+ * Pretend that this is an array
147
+ */
148
+ get ["constructor"]() {
149
+ return Array;
150
+ }
151
+
152
+ values(): ArrayIterator<T> {
153
+ const result = this._target.values();
154
+ this._fireAfterValuesRead();
155
+ return makeIteratorTranslateValue(result, (value) => this._watchedProxyHandler.getFacade().getProxyFor(value));
156
+ }
157
+
158
+ entries(): ArrayIterator<[number, T]> {
159
+ const result = this._target.entries();
160
+ this._fireAfterValuesRead();
161
+ return makeIteratorTranslateValue<[number, T], ArrayIterator<[number, T]>/*strange that TS does not infer the types here*/>(result, ([index,value]) => [index, this._watchedProxyHandler.getFacade().getProxyFor(value)]);
162
+ }
163
+
164
+ [Symbol.iterator](): ArrayIterator<T> {
165
+ const result = this._target[Symbol.iterator]();
166
+ this._fireAfterValuesRead();
167
+ return makeIteratorTranslateValue(result, (value) => this._watchedProxyHandler.getFacade().getProxyFor(value));
168
+ }
169
+
170
+ get length(): number {
171
+ const result = this._target.length;
172
+ this._fireAfterValuesRead();
173
+ return result;
174
+ }
175
+
176
+ //@ts-ignore
177
+ shift(...args: any[]) {
178
+ if(this.length == 0) {
179
+ return undefined;
180
+ }
181
+
182
+ return runChangeOperation(this, new UnspecificObjectChange(this), [getChangeHooksForObject(this).changeOwnKeys, getChangeHooksForObject(this).unspecificChange],() => {
183
+ //@ts-ignore
184
+ const result = super.shift(...args);
185
+ this._fireAfterValuesRead();
186
+ return result;
187
+ });
188
+ }
189
+
190
+
191
+ /**
192
+ * Keep this method so it it treated as handled and not as making-unspecific-reads
193
+ * @param args
194
+ */
195
+ forEach(...args: any[]) {
196
+ //@ts-ignore
197
+ return super.forEach(...args); //reads "length" an thererfore triggers the read
198
+ }
199
+
200
+
201
+ //@ts-ignore
202
+ pop(...args: any[]): T | undefined {
203
+ if(this.length == 0) {
204
+ return undefined;
205
+ }
206
+
207
+ return runChangeOperation(this, new UnspecificObjectChange(this),[getChangeHooksForObject(this).changeOwnKeys, getChangeHooksForObject(this).unspecificChange],() => {
208
+ //@ts-ignore
209
+ const result = super.pop(...args);
210
+ this._fireAfterValuesRead();
211
+ return result;
212
+ });
213
+
214
+ }
215
+
216
+ }
217
+
218
+ export const config = new class extends ClassTrackingConfiguration {
219
+ clazz= Array;
220
+ readTracker= ArrayReadTracker;
221
+ changeTracker = ArrayChangeTracker
222
+ /**
223
+ * Built-in Methods, which are using fields / calling methods on the proxy transparently/loyally, so those methods don't call/use internal stuff directly.
224
+ * Tested with, see dev_generateEsRuntimeBehaviourCheckerCode.ts
225
+ * May include read-only / reader methods
226
+ */
227
+ knownHighLevelMethods = new Set<keyof Array<unknown>>(["at", "concat", "map", "forEach", "join", "slice", "some", "filter", "find", "every", "findIndex", "includes", "indexOf", Symbol.iterator, "lastIndexOf", "push", "reduce", "reduceRight", "toLocaleString", "toString", "unshift", "splice", "copyWithin", "reverse"]) as Set<ObjKey>;
228
+
229
+ /**
230
+ * Non-high level. These fire `RecordedUnspecificRead`s then. So better implement them instead to fire i.e RecordedArrayValuesRead.
231
+ */
232
+ readOnlyMethods = new Set<keyof Array<unknown>>(["keys" /* TODO: Implement .keys, mind, that it is different to RecordedOwnKeysRead which allows gaps*/]) as Set<ObjKey>;
233
+
234
+ /**
235
+ * Non-high level. Same as above: better implement them
236
+ */
237
+ readOnlyFields = new Set<keyof Array<unknown>>([Symbol.unscopables]) as Set<ObjKey>;
238
+
239
+ /**
240
+ *
241
+ */
242
+ receiverMustBeNonProxied = false;
243
+
244
+ trackSettingObjectProperties = true;
245
+ }
@@ -0,0 +1,38 @@
1
+ import { Clazz, ForWatchedProxyHandler, GetIteratorValueProxiedFn } from "../common";
2
+ import { WatchedProxyHandler } from "../watchedProxyFacade";
3
+ export declare class IteratorReadTracker<T> extends Iterator<T> implements ForWatchedProxyHandler<Iterator<T>> {
4
+ /**
5
+ * This field should be set by the method that returns the Iterator. I.e. Array#values
6
+ */
7
+ _getValueProxied?: GetIteratorValueProxiedFn<T>;
8
+ get _watchedProxyHandler(): WatchedProxyHandler;
9
+ get _target(): Iterator<T>;
10
+ constructor();
11
+ /**
12
+ * Pretend that this is an Iterator
13
+ */
14
+ get ["constructor"](): IteratorConstructor;
15
+ next(...args: unknown[]): IteratorResult<T, any>;
16
+ }
17
+ export declare const IteratorConfig: {
18
+ clazz: Clazz;
19
+ worksForSubclasses: boolean;
20
+ readTracker: typeof IteratorReadTracker;
21
+ changeTracker: undefined;
22
+ /**
23
+ * The methods, not implemented in readTracker, are high-level
24
+ */
25
+ receiverMustBeNonProxied: boolean;
26
+ /**
27
+ * The Array/Set/Map's [Symbol.Iterator]/keys/values methods already fires a read of **all** values (simply stupid). So the Iterator/IteratorResult does not need to fire any more. The tests also don't expect this to fire.
28
+ * Still could be enabled in the future for really fine granular behaviour tracking
29
+ */
30
+ trackTreads: boolean;
31
+ proxyUnhandledMethodResults: boolean;
32
+ knownHighLevelMethods: Set<import("../common").ObjKey>;
33
+ readOnlyMethods: Set<import("../common").ObjKey>;
34
+ readOnlyFields: Set<import("../common").ObjKey>;
35
+ trackSettingObjectProperties: boolean;
36
+ getTrackerClasses(): Clazz[];
37
+ };
38
+ //# sourceMappingURL=Iterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Iterator.d.ts","sourceRoot":"","sources":["Iterator.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,EAAE,sBAAsB,EAAE,yBAAyB,EAAC,MAAM,WAAW,CAAC;AAC/G,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAqB1D,qBAAa,mBAAmB,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,CAAE,YAAW,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClG;;OAEG;IACH,gBAAgB,CAAC,EAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;IAEhD,IAAI,oBAAoB,IAAI,mBAAmB,CAE9C;IAED,IAAI,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,CAEzB;;IAMD;;OAEG;IACH,IAAI,CAAC,aAAa,CAAC,wBAElB;IAED,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,GAAG,CAAC;CAQnD;AAED,eAAO,MAAM,cAAc;WACE,KAAK;;;;IAI9B;;OAEG;;IAEH;;;OAGG;;;;;;;;CAGN,CAAA"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IteratorConfig = exports.IteratorReadTracker = void 0;
4
+ const common_1 = require("../common");
5
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6
+ // ******** THIS FILE IS NOT USED !!!!!! *********
7
+ // ***********************************************
8
+ // Currently we use a much simpler way to translate the iteration values to proxies, see common.ts/makeIteratorTranslateValue
9
+ // Still we leave this file, cause may be in the future there will be super fine per-iteration read tracking
10
+ // ---------------------------------------------------------------------------------------------------------
11
+ // Supplying a proxy with ReadTracker for to
12
+ // - easily handle all kinds of Subclasses (Array/Set/Map-Iterator)
13
+ // - easily allow high-level methods like forEach, filter, ... This would be difficult when subclassing these
14
+ //
15
+ // TO make it work:
16
+ //inside class ArrayReadTacker {
17
+ // values(): ArrayIterator<T> {
18
+ // const result = this._target.values();
19
+ // this._fireAfterValuesRead();
20
+ // result._getValueProxied = (value) => this._watchedProxyHandler.getFacade().getProxyFor(value)
21
+ // return this._watchedProxyHandler.getFacade().getProxyFor(result); // Wrap in proxy. There's special handling for proxied iterators to return the iteration value proxied.
22
+ // }
23
+ //}
24
+ class IteratorReadTracker extends Iterator {
25
+ get _watchedProxyHandler() {
26
+ throw new Error("not calling from inside a WatchedProxyHandler"); // Will return the handler when called through the handler
27
+ }
28
+ get _target() {
29
+ throw new Error("not calling from inside a WatchedProxyHandler"); // Will return the value when called through the handler
30
+ }
31
+ constructor() {
32
+ super();
33
+ }
34
+ /**
35
+ * Pretend that this is an Iterator
36
+ */
37
+ get ["constructor"]() {
38
+ return Iterator; // TODO: subclass
39
+ }
40
+ next(...args) {
41
+ const { value, done } = this._target.next(...args);
42
+ //@ts-ignore
43
+ return {
44
+ value: this._watchedProxyHandler.getFacade().getProxyFor(value),
45
+ done
46
+ };
47
+ }
48
+ }
49
+ exports.IteratorReadTracker = IteratorReadTracker;
50
+ exports.IteratorConfig = new class extends common_1.ClassTrackingConfiguration {
51
+ constructor() {
52
+ super(...arguments);
53
+ this.clazz = Iterator;
54
+ this.worksForSubclasses = true;
55
+ this.readTracker = IteratorReadTracker;
56
+ this.changeTracker = undefined;
57
+ /**
58
+ * The methods, not implemented in readTracker, are high-level
59
+ */
60
+ this.receiverMustBeNonProxied = false;
61
+ /**
62
+ * The Array/Set/Map's [Symbol.Iterator]/keys/values methods already fires a read of **all** values (simply stupid). So the Iterator/IteratorResult does not need to fire any more. The tests also don't expect this to fire.
63
+ * Still could be enabled in the future for really fine granular behaviour tracking
64
+ */
65
+ this.trackTreads = false;
66
+ this.proxyUnhandledMethodResults = false;
67
+ }
68
+ };
69
+ //# sourceMappingURL=Iterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Iterator.js","sourceRoot":"","sources":["Iterator.ts"],"names":[],"mappings":";;;AAAA,sCAA+G;AAG/G,kDAAkD;AAClD,kDAAkD;AAClD,kDAAkD;AAClD,6HAA6H;AAC7H,4GAA4G;AAC5G,4GAA4G;AAC5G,4CAA4C;AAC5C,mEAAmE;AACnE,6GAA6G;AAC7G,EAAE;AACF,mBAAmB;AACnB,gCAAgC;AAChC,kCAAkC;AAClC,+CAA+C;AAC/C,sCAAsC;AACtC,uGAAuG;AACvG,mLAAmL;AACnL,KAAK;AACL,GAAG;AACH,MAAa,mBAAuB,SAAQ,QAAW;IAMnD,IAAI,oBAAoB;QACpB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC,0DAA0D;IAChI,CAAC;IAED,IAAI,OAAO;QACP,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC,wDAAwD;IAC9H,CAAC;IAED;QACI,KAAK,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,aAAa,CAAC;QACf,OAAO,QAAQ,CAAC,CAAC,iBAAiB;IACtC,CAAC;IAED,IAAI,CAAC,GAAG,IAAe;QACnB,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAW,CAAC,CAAC;QACxD,YAAY;QACZ,OAAO;YACH,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC;YAC/D,IAAI;SACP,CAAA;IACL,CAAC;CACJ;AAjCD,kDAiCC;AAEY,QAAA,cAAc,GAAG,IAAI,KAAM,SAAQ,mCAA0B;IAAxC;;QAC9B,UAAK,GAAC,QAAwB,CAAC;QAC/B,uBAAkB,GAAC,IAAI,CAAC;QACxB,gBAAW,GAAE,mBAAmB,CAAC;QACjC,kBAAa,GAAG,SAAS,CAAC;QAC1B;;WAEG;QACH,6BAAwB,GAAG,KAAK,CAAC;QACjC;;;WAGG;QACH,gBAAW,GAAG,KAAK,CAAC;QACpB,gCAA2B,GAAG,KAAK,CAAC;IACxC,CAAC;CAAA,CAAA"}
@@ -0,0 +1,73 @@
1
+ import {ClassTrackingConfiguration, Clazz, ForWatchedProxyHandler, GetIteratorValueProxiedFn} from "../common";
2
+ import {WatchedProxyHandler} from "../watchedProxyFacade";
3
+ import _ from "underscore";
4
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5
+ // ******** THIS FILE IS NOT USED !!!!!! *********
6
+ // ***********************************************
7
+ // Currently we use a much simpler way to translate the iteration values to proxies, see common.ts/makeIteratorTranslateValue
8
+ // Still we leave this file, cause may be in the future there will be super fine per-iteration read tracking
9
+ // ---------------------------------------------------------------------------------------------------------
10
+ // Supplying a proxy with ReadTracker for to
11
+ // - easily handle all kinds of Subclasses (Array/Set/Map-Iterator)
12
+ // - easily allow high-level methods like forEach, filter, ... This would be difficult when subclassing these
13
+ //
14
+ // TO make it work:
15
+ //inside class ArrayReadTacker {
16
+ // values(): ArrayIterator<T> {
17
+ // const result = this._target.values();
18
+ // this._fireAfterValuesRead();
19
+ // result._getValueProxied = (value) => this._watchedProxyHandler.getFacade().getProxyFor(value)
20
+ // return this._watchedProxyHandler.getFacade().getProxyFor(result); // Wrap in proxy. There's special handling for proxied iterators to return the iteration value proxied.
21
+ // }
22
+ //}
23
+ export class IteratorReadTracker<T> extends Iterator<T> implements ForWatchedProxyHandler<Iterator<T>> {
24
+ /**
25
+ * This field should be set by the method that returns the Iterator. I.e. Array#values
26
+ */
27
+ _getValueProxied?: GetIteratorValueProxiedFn<T>;
28
+
29
+ get _watchedProxyHandler(): WatchedProxyHandler {
30
+ throw new Error("not calling from inside a WatchedProxyHandler"); // Will return the handler when called through the handler
31
+ }
32
+
33
+ get _target(): Iterator<T> {
34
+ throw new Error("not calling from inside a WatchedProxyHandler"); // Will return the value when called through the handler
35
+ }
36
+
37
+ constructor() {
38
+ super();
39
+ }
40
+
41
+ /**
42
+ * Pretend that this is an Iterator
43
+ */
44
+ get ["constructor"]() {
45
+ return Iterator; // TODO: subclass
46
+ }
47
+
48
+ next(...args: unknown[]): IteratorResult<T, any> {
49
+ const {value, done} = this._target.next(...args as any);
50
+ //@ts-ignore
51
+ return {
52
+ value: this._watchedProxyHandler.getFacade().getProxyFor(value),
53
+ done
54
+ }
55
+ }
56
+ }
57
+
58
+ export const IteratorConfig = new class extends ClassTrackingConfiguration {
59
+ clazz=Iterator as any as Clazz;
60
+ worksForSubclasses=true;
61
+ readTracker= IteratorReadTracker;
62
+ changeTracker = undefined;
63
+ /**
64
+ * The methods, not implemented in readTracker, are high-level
65
+ */
66
+ receiverMustBeNonProxied = false;
67
+ /**
68
+ * The Array/Set/Map's [Symbol.Iterator]/keys/values methods already fires a read of **all** values (simply stupid). So the Iterator/IteratorResult does not need to fire any more. The tests also don't expect this to fire.
69
+ * Still could be enabled in the future for really fine granular behaviour tracking
70
+ */
71
+ trackTreads = false;
72
+ proxyUnhandledMethodResults = false;
73
+ }
@@ -0,0 +1,128 @@
1
+ import { EventHook, DualUseTracker, ForWatchedProxyHandler, IWatchedProxyHandler_common, ObjKey, RecordedRead } from "../common";
2
+ import { WatchedProxyHandler } from "../watchedProxyFacade";
3
+ import { RecordedReadOnProxiedObjectExt } from "../RecordedReadOnProxiedObjectExt";
4
+ /**
5
+ * Hooks for one map.
6
+ * Note for specificity: There will be only one of the **change** events fired. The Recorded...Read.onChange handler will add the listeners to all possible candidates. It's this way around.
7
+ * {@link ObjectChangeHooks} are also subscribed on Maps
8
+ */
9
+ declare class MapChangeHooks {
10
+ specificKeyAddedOrRemoved: import("../Util").DefaultMap<unknown, EventHook>;
11
+ anyKeyAddedOrRemoved: EventHook;
12
+ specificValueChanged: import("../Util").DefaultMap<unknown, EventHook>;
13
+ anyValueChanged: EventHook;
14
+ }
15
+ export declare const changeHooksForMap: WeakMap<Map<unknown, unknown>, MapChangeHooks>;
16
+ export declare function getChangeHooksForMap(map: Map<unknown, unknown>): MapChangeHooks;
17
+ /**
18
+ * Can be either used as a supervisor-class in a WatchedProxyHandler, or installed on the non-proxied object via Object.setPrototypeOf
19
+ * The "this" may be different in these cases.
20
+ */
21
+ export declare class MapChangeTracker<K, V> extends Map<K, V> implements DualUseTracker<Map<K, V>> {
22
+ get _watchedProxyHandler(): IWatchedProxyHandler_common | undefined;
23
+ protected _withUnspecificChange<R>(changeFn: () => R): R;
24
+ /**
25
+ * Will return the original object when this class is used as supervisor class in the WatchedProxyHandler
26
+ */
27
+ get _target(): Map<K, V>;
28
+ /**
29
+ * Pretend that this is a Map
30
+ */
31
+ get ["constructor"](): MapConstructor;
32
+ set(key: K, value: V): this;
33
+ delete(key: K): boolean;
34
+ clear(): void;
35
+ }
36
+ export declare class RecordedMap_get extends RecordedReadOnProxiedObjectExt {
37
+ key: unknown;
38
+ keyExists: boolean;
39
+ /**
40
+ * Result of the .get call
41
+ */
42
+ value: unknown;
43
+ obj: Map<unknown, unknown>;
44
+ constructor(key: unknown, keyExists: boolean, value: unknown);
45
+ get isChanged(): boolean;
46
+ getAffectingChangeHooks(target: this["obj"]): EventHook[];
47
+ equals(other: RecordedRead): boolean;
48
+ }
49
+ export declare class RecordedMap_has extends RecordedReadOnProxiedObjectExt {
50
+ key: unknown;
51
+ /**
52
+ * Result of the .has call
53
+ */
54
+ keyExists: boolean;
55
+ obj: Map<unknown, unknown>;
56
+ constructor(key: unknown, keyExists: boolean);
57
+ get isChanged(): boolean;
58
+ getAffectingChangeHooks(target: this["obj"]): EventHook[];
59
+ equals(other: RecordedRead): boolean;
60
+ }
61
+ export declare class RecordedMapKeysRead extends RecordedReadOnProxiedObjectExt {
62
+ keys: Array<unknown>;
63
+ obj: Map<unknown, unknown>;
64
+ constructor(keys: Array<unknown>);
65
+ getAffectingChangeHooks(target: this["obj"]): EventHook[];
66
+ equals(other: RecordedRead): boolean;
67
+ get isChanged(): boolean;
68
+ }
69
+ export declare class RecordedMapValuesRead extends RecordedReadOnProxiedObjectExt {
70
+ values: Array<unknown>;
71
+ obj: Map<unknown, unknown>;
72
+ constructor(values: Array<unknown>);
73
+ getAffectingChangeHooks(target: this["obj"]): EventHook[];
74
+ equals(other: RecordedRead): boolean;
75
+ get isChanged(): boolean;
76
+ }
77
+ export declare class RecordedMapEntriesRead extends RecordedReadOnProxiedObjectExt {
78
+ values: Array<[unknown, unknown]>;
79
+ obj: Map<unknown, unknown>;
80
+ constructor(values: Array<[unknown, unknown]>);
81
+ getAffectingChangeHooks(target: this["obj"]): EventHook[];
82
+ equals(other: RecordedRead): boolean;
83
+ get isChanged(): boolean;
84
+ }
85
+ export declare class MapReadTracker<K, V> extends Map<K, V> implements ForWatchedProxyHandler<Map<K, V>> {
86
+ get _watchedProxyHandler(): WatchedProxyHandler;
87
+ get _target(): Map<K, V>;
88
+ protected _fireAfterEntriesRead(): void;
89
+ /**
90
+ * Pretend that this is a Map
91
+ */
92
+ get ["constructor"](): MapConstructor;
93
+ get(key: K): V | undefined;
94
+ has(key: K): boolean;
95
+ values(): MapIterator<V>;
96
+ entries(): MapIterator<[K, V]>;
97
+ keys(): MapIterator<K>;
98
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>, ...restOfArgs: unknown[]) => void, ...restOfArgs: unknown[]): void;
99
+ [Symbol.iterator](): MapIterator<[K, V]>;
100
+ get size(): number;
101
+ }
102
+ export declare const config: {
103
+ clazz: MapConstructor;
104
+ readTracker: typeof MapReadTracker;
105
+ changeTracker: typeof MapChangeTracker;
106
+ /**
107
+ * Built-in Methods, which are using fields / calling methods on the proxy transparently/loyally, so those methods don't call/use internal stuff directly.
108
+ * Tested with, see dev_generateEsRuntimeBehaviourCheckerCode.ts
109
+ * May include read-only / reader methods
110
+ */
111
+ knownHighLevelMethods: Set<ObjKey>;
112
+ /**
113
+ * Non-high level
114
+ */
115
+ readOnlyMethods: Set<ObjKey>;
116
+ /**
117
+ * Non-high level
118
+ */
119
+ readOnlyFields: Set<ObjKey>;
120
+ receiverMustBeNonProxied: boolean;
121
+ worksForSubclasses: boolean;
122
+ trackTreads: boolean;
123
+ trackSettingObjectProperties: boolean;
124
+ proxyUnhandledMethodResults: boolean;
125
+ getTrackerClasses(): import("../common").Clazz[];
126
+ };
127
+ export {};
128
+ //# sourceMappingURL=Map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Map.d.ts","sourceRoot":"","sources":["Map.ts"],"names":[],"mappings":"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"}