@traqula/core 0.0.23 → 0.0.24

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 (51) hide show
  1. package/dist/cjs/lib/AstCoreFactory.js +136 -149
  2. package/dist/cjs/lib/AstCoreFactory.js.map +1 -0
  3. package/dist/cjs/lib/generator-builder/builderTypes.js +2 -15
  4. package/dist/cjs/lib/generator-builder/builderTypes.js.map +1 -0
  5. package/dist/cjs/lib/generator-builder/dynamicGenerator.js +189 -200
  6. package/dist/cjs/lib/generator-builder/dynamicGenerator.js.map +1 -0
  7. package/dist/cjs/lib/generator-builder/generatorBuilder.js +103 -117
  8. package/dist/cjs/lib/generator-builder/generatorBuilder.js.map +1 -0
  9. package/dist/cjs/lib/generator-builder/generatorTypes.js +2 -15
  10. package/dist/cjs/lib/generator-builder/generatorTypes.js.map +1 -0
  11. package/dist/cjs/lib/index.js +39 -57
  12. package/dist/cjs/lib/index.js.map +1 -0
  13. package/dist/cjs/lib/indirection-builder/IndirBuilder.js +63 -85
  14. package/dist/cjs/lib/indirection-builder/IndirBuilder.js.map +1 -0
  15. package/dist/cjs/lib/indirection-builder/dynamicIndirected.js +28 -50
  16. package/dist/cjs/lib/indirection-builder/dynamicIndirected.js.map +1 -0
  17. package/dist/cjs/lib/indirection-builder/helpers.js +11 -31
  18. package/dist/cjs/lib/indirection-builder/helpers.js.map +1 -0
  19. package/dist/cjs/lib/lexer-builder/LexerBuilder.js +92 -114
  20. package/dist/cjs/lib/lexer-builder/LexerBuilder.js.map +1 -0
  21. package/dist/cjs/lib/parser-builder/builderTypes.js +2 -15
  22. package/dist/cjs/lib/parser-builder/builderTypes.js.map +1 -0
  23. package/dist/cjs/lib/parser-builder/dynamicParser.js +115 -136
  24. package/dist/cjs/lib/parser-builder/dynamicParser.js.map +1 -0
  25. package/dist/cjs/lib/parser-builder/parserBuilder.js +167 -169
  26. package/dist/cjs/lib/parser-builder/parserBuilder.js.map +1 -0
  27. package/dist/cjs/lib/parser-builder/ruleDefTypes.js +2 -15
  28. package/dist/cjs/lib/parser-builder/ruleDefTypes.js.map +1 -0
  29. package/dist/cjs/lib/transformers/TransformerObject.js +196 -198
  30. package/dist/cjs/lib/transformers/TransformerObject.js.map +1 -0
  31. package/dist/cjs/lib/transformers/TransformerSubTyped.js +120 -141
  32. package/dist/cjs/lib/transformers/TransformerSubTyped.js.map +1 -0
  33. package/dist/cjs/lib/transformers/TransformerTyped.js +99 -120
  34. package/dist/cjs/lib/transformers/TransformerTyped.js.map +1 -0
  35. package/dist/cjs/lib/types.js +2 -15
  36. package/dist/cjs/lib/types.js.map +1 -0
  37. package/dist/cjs/lib/utils.js +13 -34
  38. package/dist/cjs/lib/utils.js.map +1 -0
  39. package/package.json +9 -9
  40. package/dist/cjs/test/generatorBuilder/generatorBuilder.types.test.js +0 -30
  41. package/dist/cjs/test/grammar-builder/parserBuilder.types.test.js +0 -27
  42. package/dist/cjs/test/transformer.test.js +0 -82
  43. package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.d.ts +0 -1
  44. package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.js +0 -38
  45. package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.js.map +0 -1
  46. package/dist/esm/test/grammar-builder/parserBuilder.types.test.d.ts +0 -1
  47. package/dist/esm/test/grammar-builder/parserBuilder.types.test.js +0 -38
  48. package/dist/esm/test/grammar-builder/parserBuilder.types.test.js.map +0 -1
  49. package/dist/esm/test/transformer.test.d.ts +0 -1
  50. package/dist/esm/test/transformer.test.js +0 -82
  51. package/dist/esm/test/transformer.test.js.map +0 -1
@@ -1,213 +1,211 @@
1
1
  "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var TransformerObject_exports = {};
20
- __export(TransformerObject_exports, {
21
- TransformerObject: () => TransformerObject
22
- });
23
- module.exports = __toCommonJS(TransformerObject_exports);
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransformerObject = void 0;
24
4
  class TransformerObject {
25
- defaultContext;
26
- maxStackSize = 1e6;
27
- /**
28
- * Creates stateless transformer.
29
- * @param defaultContext
30
- */
31
- constructor(defaultContext = {}) {
32
- this.defaultContext = defaultContext;
33
- }
34
- clone(newDefaultContext = {}) {
35
- return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });
36
- }
37
- /**
38
- * Function to shallow clone any type.
39
- * @param obj
40
- * @protected
41
- */
42
- cloneObj(obj) {
43
- if (obj === null || typeof obj !== "object") {
44
- return obj;
5
+ defaultContext;
6
+ maxStackSize = 1_000_000;
7
+ /**
8
+ * Creates stateless transformer.
9
+ * @param defaultContext
10
+ */
11
+ constructor(defaultContext = {}) {
12
+ this.defaultContext = defaultContext;
45
13
  }
46
- const proto = Object.getPrototypeOf(obj);
47
- if (proto === Object.prototype || proto === null) {
48
- return { ...obj };
14
+ clone(newDefaultContext = {}) {
15
+ return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });
49
16
  }
50
- return Object.assign(Object.create(proto), obj);
51
- }
52
- /**
53
- * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.
54
- * @param startObject object to start iterating from
55
- * @param mapper mapper to transform the various objects - argument is a copy of the original
56
- * @param preVisitor callback that is evaluated before iterating deeper.
57
- * If continues is false, we do not iterate deeper, current object is still mapped. - default: true
58
- * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.
59
- * - Default false
60
- */
61
- transformObject(startObject, mapper, preVisitor = () => ({})) {
62
- const defaults = this.defaultContext;
63
- const defaultCopyFlag = defaults.copy ?? true;
64
- const defaultContinues = defaults.continue ?? true;
65
- const defaultIgnoreKeys = defaults.ignoreKeys;
66
- const defaultShallowKeys = defaults.shallowKeys;
67
- const defaultDidShortCut = defaults.shortcut ?? false;
68
- let didShortCut = false;
69
- const resultWrap = { res: startObject };
70
- const stack = [startObject];
71
- const stackParent = [resultWrap];
72
- const stackParentKey = ["res"];
73
- const handleMapperOnLen = [];
74
- const mapperCopyStack = [];
75
- const mapperOrigStack = [];
76
- const mapperParent = [];
77
- const mapperParentKey = [];
78
- function handleMapper() {
79
- while (stack.length === handleMapperOnLen.at(-1)) {
80
- handleMapperOnLen.pop();
81
- const copyToMap = mapperCopyStack.pop();
82
- const origToMap = mapperOrigStack.pop();
83
- const parent = mapperParent.pop();
84
- const parentKey = mapperParentKey.pop();
85
- parent[parentKey] = mapper(copyToMap, origToMap);
86
- }
17
+ /**
18
+ * Function to shallow clone any type.
19
+ * @param obj
20
+ * @protected
21
+ */
22
+ cloneObj(obj) {
23
+ if (obj === null || typeof obj !== 'object') {
24
+ return obj;
25
+ }
26
+ const proto = Object.getPrototypeOf(obj);
27
+ // Fast path: plain object
28
+ if (proto === Object.prototype || proto === null) {
29
+ // Spread or assign preserves fast properties
30
+ return { ...obj };
31
+ }
32
+ // Otherwise, preserve prototype for custom objects
33
+ return Object.assign(Object.create(proto), obj);
87
34
  }
88
- while (stack.length > 0 && stack.length < this.maxStackSize) {
89
- const curObject = stack.pop();
90
- const curParent = stackParent.pop();
91
- const curKey = stackParentKey.pop();
92
- if (!didShortCut) {
93
- if (Array.isArray(curObject)) {
94
- const newArr = [...curObject];
95
- handleMapperOnLen.push(stack.length);
96
- mapperCopyStack.push(newArr);
97
- mapperOrigStack.push(curObject);
98
- mapperParent.push(curParent);
99
- mapperParentKey.push(curKey);
100
- for (let index = curObject.length - 1; index >= 0; index--) {
101
- const val = curObject[index];
102
- if (val !== null && typeof val === "object") {
103
- stack.push(val);
104
- stackParent.push(newArr);
105
- stackParentKey.push(index.toString());
35
+ /**
36
+ * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.
37
+ * @param startObject object to start iterating from
38
+ * @param mapper mapper to transform the various objects - argument is a copy of the original
39
+ * @param preVisitor callback that is evaluated before iterating deeper.
40
+ * If continues is false, we do not iterate deeper, current object is still mapped. - default: true
41
+ * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.
42
+ * - Default false
43
+ */
44
+ transformObject(startObject, mapper, preVisitor = () => ({})) {
45
+ const defaults = this.defaultContext;
46
+ const defaultCopyFlag = defaults.copy ?? true;
47
+ const defaultContinues = defaults.continue ?? true;
48
+ const defaultIgnoreKeys = defaults.ignoreKeys;
49
+ const defaultShallowKeys = defaults.shallowKeys;
50
+ const defaultDidShortCut = defaults.shortcut ?? false;
51
+ // Code handles own stack instead of using recursion - this optimizes it for deep operations.
52
+ let didShortCut = false;
53
+ const resultWrap = { res: startObject };
54
+ // Grows with stack
55
+ const stack = [startObject];
56
+ const stackParent = [resultWrap];
57
+ const stackParentKey = ['res'];
58
+ // Grows with reverse stack - when popping down the stack, you realise you still want to map something.
59
+ // Counter of stack size when we started adding the children of this object, going beyond this means a new parent
60
+ const handleMapperOnLen = [];
61
+ const mapperCopyStack = [];
62
+ const mapperOrigStack = [];
63
+ const mapperParent = [];
64
+ const mapperParentKey = [];
65
+ function handleMapper() {
66
+ while (stack.length === handleMapperOnLen.at(-1)) {
67
+ handleMapperOnLen.pop();
68
+ const copyToMap = mapperCopyStack.pop();
69
+ const origToMap = mapperOrigStack.pop();
70
+ const parent = mapperParent.pop();
71
+ const parentKey = mapperParentKey.pop();
72
+ parent[parentKey] = mapper(copyToMap, origToMap);
106
73
  }
107
- }
108
- handleMapper();
109
- continue;
110
74
  }
111
- const context = preVisitor(curObject);
112
- const copyFlag = context.copy ?? defaultCopyFlag;
113
- const continues = context.continue ?? defaultContinues;
114
- const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;
115
- const shallowKeys = context.shallowKeys ?? defaultShallowKeys;
116
- didShortCut = context.shortcut ?? defaultDidShortCut;
117
- const copy = copyFlag ? this.cloneObj(curObject) : curObject;
118
- handleMapperOnLen.push(stack.length);
119
- mapperCopyStack.push(copy);
120
- mapperOrigStack.push(curObject);
121
- mapperParent.push(curParent);
122
- mapperParentKey.push(curKey);
123
- if (continues && !didShortCut) {
124
- for (const key in copy) {
125
- if (!Object.hasOwn(copy, key)) {
126
- continue;
127
- }
128
- const val = copy[key];
129
- const onlyShallow = shallowKeys && shallowKeys?.has(key);
130
- if (onlyShallow) {
131
- copy[key] = this.cloneObj(val);
132
- }
133
- if (ignoreKeys && ignoreKeys.has(key)) {
134
- continue;
75
+ while (stack.length > 0 && stack.length < this.maxStackSize) {
76
+ const curObject = stack.pop();
77
+ const curParent = stackParent.pop();
78
+ const curKey = stackParentKey.pop();
79
+ // Only add to the stack when you did not shortcut
80
+ if (!didShortCut) {
81
+ if (Array.isArray(curObject)) {
82
+ const newArr = [...curObject];
83
+ handleMapperOnLen.push(stack.length);
84
+ mapperCopyStack.push(newArr);
85
+ mapperOrigStack.push(curObject);
86
+ mapperParent.push(curParent);
87
+ mapperParentKey.push(curKey);
88
+ for (let index = curObject.length - 1; index >= 0; index--) {
89
+ const val = curObject[index];
90
+ if (val !== null && typeof val === 'object') {
91
+ stack.push(val);
92
+ stackParent.push(newArr);
93
+ stackParentKey.push(index.toString());
94
+ }
95
+ }
96
+ handleMapper();
97
+ continue;
98
+ }
99
+ // Perform pre visit before expanding the stack
100
+ const context = preVisitor(curObject);
101
+ const copyFlag = context.copy ?? defaultCopyFlag;
102
+ const continues = context.continue ?? defaultContinues;
103
+ const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;
104
+ const shallowKeys = context.shallowKeys ?? defaultShallowKeys;
105
+ didShortCut = context.shortcut ?? defaultDidShortCut;
106
+ const copy = copyFlag ? this.cloneObj(curObject) : curObject;
107
+ // Register that you want to be visited
108
+ handleMapperOnLen.push(stack.length);
109
+ mapperCopyStack.push(copy);
110
+ mapperOrigStack.push(curObject);
111
+ mapperParent.push(curParent);
112
+ mapperParentKey.push(curKey);
113
+ // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.
114
+ if (continues && !didShortCut) {
115
+ for (const key in copy) {
116
+ if (!Object.hasOwn(copy, key)) {
117
+ continue;
118
+ }
119
+ const val = copy[key];
120
+ // If shallow copy required, do
121
+ const onlyShallow = shallowKeys && shallowKeys?.has(key);
122
+ if (onlyShallow) {
123
+ // Do not add stack entry - assign straight away
124
+ copy[key] = this.cloneObj(val);
125
+ }
126
+ if (ignoreKeys && ignoreKeys.has(key)) {
127
+ // Do not add stack entry
128
+ continue;
129
+ }
130
+ if (!onlyShallow && val !== null && typeof val === 'object') {
131
+ // Do add stack entry.
132
+ stack.push(val);
133
+ stackParentKey.push(key);
134
+ stackParent.push(copy);
135
+ }
136
+ }
137
+ }
135
138
  }
136
- if (!onlyShallow && val !== null && typeof val === "object") {
137
- stack.push(val);
138
- stackParentKey.push(key);
139
- stackParent.push(copy);
140
- }
141
- }
139
+ handleMapper();
142
140
  }
143
- }
144
- handleMapper();
145
- }
146
- if (stack.length >= this.maxStackSize) {
147
- throw new Error("Transform object stack overflowed");
148
- }
149
- handleMapper();
150
- return resultWrap.res;
151
- }
152
- /**
153
- * Visitor that visits all objects. Visits deeper objects first.
154
- */
155
- visitObject(startObject, visitor, preVisitor = () => ({})) {
156
- const defaults = this.defaultContext;
157
- const defaultContinues = defaults.continue ?? true;
158
- const defaultIgnoreKeys = defaults.ignoreKeys;
159
- const defaultShortcut = defaults.shortcut ?? false;
160
- let didShortCut = false;
161
- const stack = [startObject];
162
- const handleVisitorOnLen = [];
163
- const visitorStack = [];
164
- function handleVisitor() {
165
- while (stack.length === handleVisitorOnLen.at(-1)) {
166
- handleVisitorOnLen.pop();
167
- const toVisit = visitorStack.pop();
168
- visitor(toVisit);
169
- }
170
- }
171
- while (stack.length > 0 && stack.length < this.maxStackSize) {
172
- const curObject = stack.pop();
173
- if (!didShortCut) {
174
- if (Array.isArray(curObject)) {
175
- for (let i = curObject.length - 1; i >= 0; i--) {
176
- stack.push(curObject[i]);
177
- }
178
- handleVisitor();
179
- continue;
141
+ if (stack.length >= this.maxStackSize) {
142
+ throw new Error('Transform object stack overflowed');
180
143
  }
181
- const context = preVisitor(curObject);
182
- didShortCut = context.shortcut ?? defaultShortcut;
183
- const continues = context.continue ?? defaultContinues;
184
- const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;
185
- handleVisitorOnLen.push(stack.length);
186
- visitorStack.push(curObject);
187
- if (continues && !didShortCut) {
188
- for (const key in curObject) {
189
- if (!Object.hasOwn(curObject, key)) {
190
- continue;
191
- }
192
- if (ignoreKeys && ignoreKeys.has(key)) {
193
- continue;
144
+ handleMapper();
145
+ return resultWrap.res;
146
+ }
147
+ /**
148
+ * Visitor that visits all objects. Visits deeper objects first.
149
+ */
150
+ visitObject(startObject, visitor, preVisitor = () => ({})) {
151
+ const defaults = this.defaultContext;
152
+ const defaultContinues = defaults.continue ?? true;
153
+ const defaultIgnoreKeys = defaults.ignoreKeys;
154
+ const defaultShortcut = defaults.shortcut ?? false;
155
+ let didShortCut = false;
156
+ // Stack of things to preVisit
157
+ const stack = [startObject];
158
+ // When the stack is done preVisiting things above this lengths, visit the bellow
159
+ const handleVisitorOnLen = [];
160
+ const visitorStack = [];
161
+ function handleVisitor() {
162
+ while (stack.length === handleVisitorOnLen.at(-1)) {
163
+ handleVisitorOnLen.pop();
164
+ const toVisit = visitorStack.pop();
165
+ visitor(toVisit);
194
166
  }
195
- const val = curObject[key];
196
- if (val && typeof val === "object") {
197
- stack.push(val);
167
+ }
168
+ while (stack.length > 0 && stack.length < this.maxStackSize) {
169
+ const curObject = stack.pop();
170
+ if (!didShortCut) {
171
+ if (Array.isArray(curObject)) {
172
+ for (let i = curObject.length - 1; i >= 0; i--) {
173
+ stack.push(curObject[i]);
174
+ }
175
+ handleVisitor();
176
+ continue;
177
+ }
178
+ // Perform pre visit before expanding the stack
179
+ const context = preVisitor(curObject);
180
+ didShortCut = context.shortcut ?? defaultShortcut;
181
+ const continues = context.continue ?? defaultContinues;
182
+ const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;
183
+ // Register that you want to be visited
184
+ handleVisitorOnLen.push(stack.length);
185
+ visitorStack.push(curObject);
186
+ // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.
187
+ if (continues && !didShortCut) {
188
+ for (const key in curObject) {
189
+ if (!Object.hasOwn(curObject, key)) {
190
+ continue;
191
+ }
192
+ if (ignoreKeys && ignoreKeys.has(key)) {
193
+ continue;
194
+ }
195
+ const val = curObject[key];
196
+ if (val && typeof val === 'object') {
197
+ stack.push(val);
198
+ }
199
+ }
200
+ }
198
201
  }
199
- }
202
+ handleVisitor();
200
203
  }
201
- }
202
- handleVisitor();
203
- }
204
- if (stack.length >= this.maxStackSize) {
205
- throw new Error("Transform object stack overflowed");
204
+ if (stack.length >= this.maxStackSize) {
205
+ throw new Error('Transform object stack overflowed');
206
+ }
207
+ handleVisitor();
206
208
  }
207
- handleVisitor();
208
- }
209
209
  }
210
- // Annotate the CommonJS export names for ESM import in node:
211
- 0 && (module.exports = {
212
- TransformerObject
213
- });
210
+ exports.TransformerObject = TransformerObject;
211
+ //# sourceMappingURL=TransformerObject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransformerObject.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerObject.ts"],"names":[],"mappings":"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","sourcesContent":["export interface VisitContext {\n /**\n * Whether you should stop iterating after this object. Default false.\n */\n shortcut?: boolean;\n /**\n * Whether you should continue iterating deeper with this object. Default true.\n */\n continue?: boolean;\n /**\n * Object keys that can be ignored, meaning they do not get visited.\n */\n ignoreKeys?: Set<string>;\n}\n\nexport interface TransformContext extends VisitContext {\n /**\n * Object keys that will be shallowly copied but not traversed.\n * When the same key is included here and in ignoreKeys, the copy will still be made.\n */\n shallowKeys?: Set<string>;\n /**\n * Whether the visited object should be shallowly copied or not. Defaults to true.\n */\n copy?: boolean;\n}\n\nexport interface SelectiveTraversalContext<Nodes> {\n /**\n * Nodes you should visit next. Defaults to empty list\n */\n next?: Nodes[];\n /**\n * Whether you should stop visiting after visiting this object. Default false.\n */\n shortcut?: boolean;\n}\n\nexport class TransformerObject {\n protected maxStackSize = 1_000_000;\n /**\n * Creates stateless transformer.\n * @param defaultContext\n */\n public constructor(protected readonly defaultContext: TransformContext = {}) {}\n\n public clone(newDefaultContext: TransformContext = {}): TransformerObject {\n return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });\n }\n\n /**\n * Function to shallow clone any type.\n * @param obj\n * @protected\n */\n protected cloneObj<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const proto = Object.getPrototypeOf(obj);\n\n // Fast path: plain object\n if (proto === Object.prototype || proto === null) {\n // Spread or assign preserves fast properties\n return { ...obj };\n }\n\n // Otherwise, preserve prototype for custom objects\n return Object.assign(Object.create(proto), obj);\n }\n\n /**\n * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.\n * @param startObject object to start iterating from\n * @param mapper mapper to transform the various objects - argument is a copy of the original\n * @param preVisitor callback that is evaluated before iterating deeper.\n * If continues is false, we do not iterate deeper, current object is still mapped. - default: true\n * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.\n * - Default false\n */\n public transformObject(\n startObject: object,\n mapper: (copy: object, orig: object) => unknown,\n preVisitor: (orig: object) => TransformContext = () => ({}),\n ): unknown {\n const defaults = this.defaultContext;\n const defaultCopyFlag = defaults.copy ?? true;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShallowKeys = defaults.shallowKeys;\n const defaultDidShortCut = defaults.shortcut ?? false;\n\n // Code handles own stack instead of using recursion - this optimizes it for deep operations.\n let didShortCut = false;\n const resultWrap = { res: startObject };\n\n // Grows with stack\n const stack = [ startObject ];\n const stackParent: object[] = [ resultWrap ];\n const stackParentKey: string[] = [ 'res' ];\n\n // Grows with reverse stack - when popping down the stack, you realise you still want to map something.\n // Counter of stack size when we started adding the children of this object, going beyond this means a new parent\n const handleMapperOnLen: number[] = [];\n const mapperCopyStack: object[] = [];\n const mapperOrigStack: object[] = [];\n const mapperParent: object[] = [];\n const mapperParentKey: string[] = [];\n\n function handleMapper(): void {\n while (stack.length === handleMapperOnLen.at(-1)) {\n handleMapperOnLen.pop();\n const copyToMap = mapperCopyStack.pop()!;\n const origToMap = mapperOrigStack.pop()!;\n const parent = <Record<string, unknown>> mapperParent.pop()!;\n const parentKey = mapperParentKey.pop()!;\n parent[parentKey] = mapper(copyToMap, origToMap);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n const curParent = stackParent.pop()!;\n const curKey = stackParentKey.pop()!;\n\n // Only add to the stack when you did not shortcut\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n const newArr = [ ...curObject ];\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(newArr);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n for (let index = curObject.length - 1; index >= 0; index--) {\n const val = curObject[index];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n stackParent.push(newArr);\n stackParentKey.push(index.toString());\n }\n }\n handleMapper();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(<any>curObject);\n const copyFlag = context.copy ?? defaultCopyFlag;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n const shallowKeys = context.shallowKeys ?? defaultShallowKeys;\n didShortCut = context.shortcut ?? defaultDidShortCut;\n\n const copy = copyFlag ? this.cloneObj(curObject) : curObject;\n\n // Register that you want to be visited\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(copy);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in copy) {\n if (!Object.hasOwn(copy, key)) {\n continue;\n }\n const val = (<Record<string, unknown>> copy)[key];\n\n // If shallow copy required, do\n const onlyShallow = shallowKeys && shallowKeys?.has(key);\n if (onlyShallow) {\n // Do not add stack entry - assign straight away\n (<Record<string, unknown>> copy)[key] = this.cloneObj(val);\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n // Do not add stack entry\n continue;\n }\n if (!onlyShallow && val !== null && typeof val === 'object') {\n // Do add stack entry.\n stack.push(val);\n stackParentKey.push(key);\n stackParent.push(copy);\n }\n }\n }\n }\n handleMapper();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleMapper();\n\n return <any> resultWrap.res;\n }\n\n /**\n * Visitor that visits all objects. Visits deeper objects first.\n */\n public visitObject(\n startObject: object,\n visitor: (orig: object) => void,\n preVisitor: (orig: object) => VisitContext = () => ({}),\n ): void {\n const defaults = this.defaultContext;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShortcut = defaults.shortcut ?? false;\n\n let didShortCut = false;\n\n // Stack of things to preVisit\n const stack = [ startObject ];\n // When the stack is done preVisiting things above this lengths, visit the bellow\n const handleVisitorOnLen: number[] = [];\n const visitorStack: object[] = [];\n\n function handleVisitor(): void {\n while (stack.length === handleVisitorOnLen.at(-1)) {\n handleVisitorOnLen.pop();\n const toVisit = visitorStack.pop()!;\n visitor(toVisit);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n for (let i = curObject.length - 1; i >= 0; i--) {\n stack.push(curObject[i]);\n }\n handleVisitor();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(curObject);\n didShortCut = context.shortcut ?? defaultShortcut;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n\n // Register that you want to be visited\n handleVisitorOnLen.push(stack.length);\n visitorStack.push(curObject);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in curObject) {\n if (!Object.hasOwn(curObject, key)) {\n continue;\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n continue;\n }\n const val = (<Record<string, unknown>> curObject)[key];\n if (val && typeof val === 'object') {\n stack.push(val);\n }\n }\n }\n }\n handleVisitor();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleVisitor();\n }\n}\n"]}