@traqula/core 0.0.22 → 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.
- package/dist/cjs/lib/AstCoreFactory.js +136 -149
- package/dist/cjs/lib/AstCoreFactory.js.map +1 -0
- package/dist/cjs/lib/generator-builder/builderTypes.js +2 -15
- package/dist/cjs/lib/generator-builder/builderTypes.js.map +1 -0
- package/dist/cjs/lib/generator-builder/dynamicGenerator.js +189 -200
- package/dist/cjs/lib/generator-builder/dynamicGenerator.js.map +1 -0
- package/dist/cjs/lib/generator-builder/generatorBuilder.js +103 -117
- package/dist/cjs/lib/generator-builder/generatorBuilder.js.map +1 -0
- package/dist/cjs/lib/generator-builder/generatorTypes.js +2 -15
- package/dist/cjs/lib/generator-builder/generatorTypes.js.map +1 -0
- package/dist/cjs/lib/index.js +39 -57
- package/dist/cjs/lib/index.js.map +1 -0
- package/dist/cjs/lib/indirection-builder/IndirBuilder.js +63 -85
- package/dist/cjs/lib/indirection-builder/IndirBuilder.js.map +1 -0
- package/dist/cjs/lib/indirection-builder/dynamicIndirected.js +28 -50
- package/dist/cjs/lib/indirection-builder/dynamicIndirected.js.map +1 -0
- package/dist/cjs/lib/indirection-builder/helpers.js +11 -31
- package/dist/cjs/lib/indirection-builder/helpers.js.map +1 -0
- package/dist/cjs/lib/lexer-builder/LexerBuilder.js +92 -114
- package/dist/cjs/lib/lexer-builder/LexerBuilder.js.map +1 -0
- package/dist/cjs/lib/parser-builder/builderTypes.js +2 -15
- package/dist/cjs/lib/parser-builder/builderTypes.js.map +1 -0
- package/dist/cjs/lib/parser-builder/dynamicParser.js +115 -136
- package/dist/cjs/lib/parser-builder/dynamicParser.js.map +1 -0
- package/dist/cjs/lib/parser-builder/parserBuilder.js +167 -169
- package/dist/cjs/lib/parser-builder/parserBuilder.js.map +1 -0
- package/dist/cjs/lib/parser-builder/ruleDefTypes.js +2 -15
- package/dist/cjs/lib/parser-builder/ruleDefTypes.js.map +1 -0
- package/dist/cjs/lib/transformers/TransformerObject.js +196 -198
- package/dist/cjs/lib/transformers/TransformerObject.js.map +1 -0
- package/dist/cjs/lib/transformers/TransformerSubTyped.js +120 -141
- package/dist/cjs/lib/transformers/TransformerSubTyped.js.map +1 -0
- package/dist/cjs/lib/transformers/TransformerTyped.js +99 -120
- package/dist/cjs/lib/transformers/TransformerTyped.js.map +1 -0
- package/dist/cjs/lib/types.js +2 -15
- package/dist/cjs/lib/types.js.map +1 -0
- package/dist/cjs/lib/utils.js +13 -34
- package/dist/cjs/lib/utils.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/package.json +9 -8
- package/dist/cjs/test/generatorBuilder/generatorBuilder.types.test.js +0 -30
- package/dist/cjs/test/grammar-builder/parserBuilder.types.test.js +0 -27
- package/dist/cjs/test/transformer.test.js +0 -82
- package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.d.ts +0 -1
- package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.js +0 -38
- package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.js.map +0 -1
- package/dist/esm/test/grammar-builder/parserBuilder.types.test.d.ts +0 -1
- package/dist/esm/test/grammar-builder/parserBuilder.types.test.js +0 -38
- package/dist/esm/test/grammar-builder/parserBuilder.types.test.js.map +0 -1
- package/dist/esm/test/transformer.test.d.ts +0 -1
- package/dist/esm/test/transformer.test.js +0 -82
- package/dist/esm/test/transformer.test.js.map +0 -1
|
@@ -1,213 +1,211 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
return { ...obj };
|
|
14
|
+
clone(newDefaultContext = {}) {
|
|
15
|
+
return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });
|
|
49
16
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
137
|
-
stack.push(val);
|
|
138
|
-
stackParentKey.push(key);
|
|
139
|
-
stackParent.push(copy);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
139
|
+
handleMapper();
|
|
142
140
|
}
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
211
|
-
|
|
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"]}
|