@traqula/core 0.0.18 → 0.0.20

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 (36) hide show
  1. package/lib/AstCoreFactory.js +1 -1
  2. package/lib/AstCoreFactory.js.map +1 -1
  3. package/lib/TransformerObject.d.ts +64 -0
  4. package/lib/TransformerObject.js +204 -0
  5. package/lib/TransformerObject.js.map +1 -0
  6. package/lib/TransformerSubTyped.d.ts +94 -0
  7. package/lib/TransformerSubTyped.js +116 -0
  8. package/lib/TransformerSubTyped.js.map +1 -0
  9. package/lib/TransformerTyped.d.ts +62 -0
  10. package/lib/TransformerTyped.js +95 -0
  11. package/lib/TransformerTyped.js.map +1 -0
  12. package/lib/generator-builder/dynamicGenerator.d.ts +13 -3
  13. package/lib/generator-builder/dynamicGenerator.js +90 -60
  14. package/lib/generator-builder/dynamicGenerator.js.map +1 -1
  15. package/lib/generator-builder/generatorBuilder.d.ts +5 -2
  16. package/lib/generator-builder/generatorBuilder.js +6 -3
  17. package/lib/generator-builder/generatorBuilder.js.map +1 -1
  18. package/lib/generator-builder/generatorTypes.d.ts +35 -21
  19. package/lib/generator-builder/generatorTypes.js.map +1 -1
  20. package/lib/index.cjs +346 -138
  21. package/lib/index.d.ts +3 -1
  22. package/lib/index.js +3 -1
  23. package/lib/index.js.map +1 -1
  24. package/lib/indirection-builder/IndirBuilder.d.ts +4 -1
  25. package/lib/indirection-builder/IndirBuilder.js +6 -3
  26. package/lib/indirection-builder/IndirBuilder.js.map +1 -1
  27. package/lib/parser-builder/parserBuilder.d.ts +12 -8
  28. package/lib/parser-builder/parserBuilder.js +6 -3
  29. package/lib/parser-builder/parserBuilder.js.map +1 -1
  30. package/lib/utils.d.ts +4 -0
  31. package/lib/utils.js +4 -0
  32. package/lib/utils.js.map +1 -1
  33. package/package.json +2 -2
  34. package/lib/Transformers.d.ts +0 -129
  35. package/lib/Transformers.js +0 -226
  36. package/lib/Transformers.js.map +0 -1
@@ -16,7 +16,7 @@ export class AstCoreFactory {
16
16
  if (filtered.length === 0) {
17
17
  return this.gen();
18
18
  }
19
- const first = filtered[0];
19
+ const first = filtered.at(0);
20
20
  const last = filtered.at(-1);
21
21
  return {
22
22
  sourceLocationType: 'source',
@@ -1 +1 @@
1
- {"version":3,"file":"AstCoreFactory.js","sourceRoot":"","sources":["AstCoreFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IToken } from 'chevrotain';\n\nimport type {\n SourceLocation,\n SourceLocationNodeAutoGenerate,\n SourceLocationNodeReplace,\n SourceLocationNoMaterialize,\n SourceLocationSource,\n SourceLocationStringReplace,\n Node,\n Localized,\n Wrap,\n} from './nodeTypings.js';\n\nexport type Typed<Type extends PropertyKey> = { type: Type };\nexport type SubTyped<Type extends PropertyKey, Subtype extends PropertyKey> = { type: Type; subType: Subtype };\n\nexport class AstCoreFactory {\n public wrap<T>(val: T, loc: SourceLocation): Wrap<T> {\n return { val, loc };\n }\n\n public isLocalized(obj: unknown): obj is Localized {\n return typeof obj === 'object' && obj !== null && 'loc' in obj &&\n typeof obj.loc === 'object' && obj.loc !== null && 'sourceLocationType' in obj.loc;\n }\n\n public sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation {\n const pureElements = elements.filter(x => x !== undefined);\n if (pureElements.length === 0) {\n return this.sourceLocationNoMaterialize();\n }\n const filtered = pureElements.filter(element =>\n !this.isLocalized(element) || this.isSourceLocationSource(element.loc) ||\n this.isSourceLocationStringReplace(element.loc) || this.isSourceLocationNodeReplace(element.loc));\n if (filtered.length === 0) {\n return this.gen();\n }\n const first = filtered[0];\n const last = filtered.at(-1)!;\n return {\n sourceLocationType: 'source',\n start: this.isLocalized(first) ?\n (<SourceLocationSource | SourceLocationStringReplace> first.loc).start :\n first.startOffset,\n end: this.isLocalized(last) ?\n (<SourceLocationSource | SourceLocationStringReplace> last.loc).end :\n (last.endOffset! + 1),\n };\n }\n\n public sourceLocationNoMaterialize(): SourceLocationNoMaterialize {\n return { sourceLocationType: 'noMaterialize' };\n }\n\n /**\n * Returns a copy of the argument that is not materialized\n */\n public dematerialized<T extends Node>(arg: T): T & { loc: SourceLocationNoMaterialize } {\n return { ...arg, loc: this.sourceLocationNoMaterialize() };\n }\n\n public safeObjectTransform(value: unknown, mapper: (some: object) => any): any {\n if (value && typeof value === 'object') {\n // If you wonder why this is all so hard, this is the reason. We cannot lose the methods of our Array objects\n if (Array.isArray(value)) {\n return value.map(x => this.safeObjectTransform(x, mapper));\n }\n return mapper(value);\n }\n return value;\n }\n\n public forcedAutoGenTree<T extends object>(obj: T): T {\n const copy = { ...obj };\n for (const [ key, value ] of Object.entries(copy)) {\n (<Record<string, object>> copy)[key] = this.safeObjectTransform(value, obj => this.forcedAutoGenTree(obj));\n }\n if (this.isLocalized(copy)) {\n copy.loc = this.gen();\n }\n return copy;\n }\n\n public forceMaterialized<T extends Node>(arg: T): T {\n if (this.isSourceLocationNoMaterialize(arg.loc)) {\n return this.forcedAutoGenTree(arg);\n }\n return { ...arg };\n }\n\n public isSourceLocation(loc: object): loc is SourceLocation {\n return 'sourceLocationType' in loc;\n }\n\n public sourceLocationSource(start: number, end: number): SourceLocationSource {\n return {\n sourceLocationType: 'source',\n start,\n end,\n };\n }\n\n public gen(): SourceLocationNodeAutoGenerate {\n return { sourceLocationType: 'autoGenerate' };\n }\n\n public isSourceLocationSource(loc: object): loc is SourceLocationSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';\n }\n\n public isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';\n }\n\n public sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace {\n if (this.isSourceLocationSource(loc)) {\n return this.sourceLocationNodeReplace(loc);\n }\n throw new Error('not possible');\n }\n\n public sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(startOrLoc: number | SourceLocationSource, end?: number): SourceLocationNodeReplace {\n let starting;\n let ending;\n if (typeof startOrLoc === 'number') {\n starting = startOrLoc;\n ending = end!;\n } else {\n starting = startOrLoc.start;\n ending = startOrLoc.end;\n }\n return {\n sourceLocationType: 'nodeReplace',\n start: starting,\n end: ending,\n };\n }\n\n public isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';\n }\n\n public isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';\n }\n\n public nodeShouldPrint(node: Localized): boolean {\n return this.isSourceLocationNodeReplace(node.loc) ||\n this.isSourceLocationNodeAutoGenerate(node.loc);\n }\n\n public printFilter(node: Localized, callback: () => void): void {\n if (this.nodeShouldPrint(node)) {\n callback();\n }\n }\n\n public isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';\n }\n\n public isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type> {\n const casted: { type?: any } = obj;\n return casted.type === type;\n }\n\n public isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType):\n obj is SubTyped<Type, SubType> {\n const temp: { type?: unknown; subType?: unknown } = obj;\n return temp.type === type && temp.subType === subType;\n }\n}\n"]}
1
+ {"version":3,"file":"AstCoreFactory.js","sourceRoot":"","sources":["AstCoreFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IToken } from 'chevrotain';\n\nimport type {\n SourceLocation,\n SourceLocationNodeAutoGenerate,\n SourceLocationNodeReplace,\n SourceLocationNoMaterialize,\n SourceLocationSource,\n SourceLocationStringReplace,\n Node,\n Localized,\n Wrap,\n} from './nodeTypings.js';\n\nexport type Typed<Type extends PropertyKey> = { type: Type };\nexport type SubTyped<Type extends PropertyKey, Subtype extends PropertyKey> = { type: Type; subType: Subtype };\n\nexport class AstCoreFactory {\n public wrap<T>(val: T, loc: SourceLocation): Wrap<T> {\n return { val, loc };\n }\n\n public isLocalized(obj: unknown): obj is Localized {\n return typeof obj === 'object' && obj !== null && 'loc' in obj &&\n typeof obj.loc === 'object' && obj.loc !== null && 'sourceLocationType' in obj.loc;\n }\n\n public sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation {\n const pureElements = elements.filter(x => x !== undefined);\n if (pureElements.length === 0) {\n return this.sourceLocationNoMaterialize();\n }\n const filtered = pureElements.filter(element =>\n !this.isLocalized(element) || this.isSourceLocationSource(element.loc) ||\n this.isSourceLocationStringReplace(element.loc) || this.isSourceLocationNodeReplace(element.loc));\n if (filtered.length === 0) {\n return this.gen();\n }\n const first = filtered.at(0)!;\n const last = filtered.at(-1)!;\n return {\n sourceLocationType: 'source',\n start: this.isLocalized(first) ?\n (<SourceLocationSource | SourceLocationStringReplace> first.loc).start :\n first.startOffset,\n end: this.isLocalized(last) ?\n (<SourceLocationSource | SourceLocationStringReplace> last.loc).end :\n (last.endOffset! + 1),\n };\n }\n\n public sourceLocationNoMaterialize(): SourceLocationNoMaterialize {\n return { sourceLocationType: 'noMaterialize' };\n }\n\n /**\n * Returns a copy of the argument that is not materialized\n */\n public dematerialized<T extends Node>(arg: T): T & { loc: SourceLocationNoMaterialize } {\n return { ...arg, loc: this.sourceLocationNoMaterialize() };\n }\n\n public safeObjectTransform(value: unknown, mapper: (some: object) => any): any {\n if (value && typeof value === 'object') {\n // If you wonder why this is all so hard, this is the reason. We cannot lose the methods of our Array objects\n if (Array.isArray(value)) {\n return value.map(x => this.safeObjectTransform(x, mapper));\n }\n return mapper(value);\n }\n return value;\n }\n\n public forcedAutoGenTree<T extends object>(obj: T): T {\n const copy = { ...obj };\n for (const [ key, value ] of Object.entries(copy)) {\n (<Record<string, object>> copy)[key] = this.safeObjectTransform(value, obj => this.forcedAutoGenTree(obj));\n }\n if (this.isLocalized(copy)) {\n copy.loc = this.gen();\n }\n return copy;\n }\n\n public forceMaterialized<T extends Node>(arg: T): T {\n if (this.isSourceLocationNoMaterialize(arg.loc)) {\n return this.forcedAutoGenTree(arg);\n }\n return { ...arg };\n }\n\n public isSourceLocation(loc: object): loc is SourceLocation {\n return 'sourceLocationType' in loc;\n }\n\n public sourceLocationSource(start: number, end: number): SourceLocationSource {\n return {\n sourceLocationType: 'source',\n start,\n end,\n };\n }\n\n public gen(): SourceLocationNodeAutoGenerate {\n return { sourceLocationType: 'autoGenerate' };\n }\n\n public isSourceLocationSource(loc: object): loc is SourceLocationSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';\n }\n\n public isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';\n }\n\n public sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace {\n if (this.isSourceLocationSource(loc)) {\n return this.sourceLocationNodeReplace(loc);\n }\n throw new Error('not possible');\n }\n\n public sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(startOrLoc: number | SourceLocationSource, end?: number): SourceLocationNodeReplace {\n let starting;\n let ending;\n if (typeof startOrLoc === 'number') {\n starting = startOrLoc;\n ending = end!;\n } else {\n starting = startOrLoc.start;\n ending = startOrLoc.end;\n }\n return {\n sourceLocationType: 'nodeReplace',\n start: starting,\n end: ending,\n };\n }\n\n public isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';\n }\n\n public isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';\n }\n\n public nodeShouldPrint(node: Localized): boolean {\n return this.isSourceLocationNodeReplace(node.loc) ||\n this.isSourceLocationNodeAutoGenerate(node.loc);\n }\n\n public printFilter(node: Localized, callback: () => void): void {\n if (this.nodeShouldPrint(node)) {\n callback();\n }\n }\n\n public isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';\n }\n\n public isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type> {\n const casted: { type?: any } = obj;\n return casted.type === type;\n }\n\n public isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType):\n obj is SubTyped<Type, SubType> {\n const temp: { type?: unknown; subType?: unknown } = obj;\n return temp.type === type && temp.subType === subType;\n }\n}\n"]}
@@ -0,0 +1,64 @@
1
+ export interface VisitContext {
2
+ /**
3
+ * Whether you should stop iterating after this object. Default false.
4
+ */
5
+ shortcut?: boolean;
6
+ /**
7
+ * Whether you should continue iterating deeper with this object. Default true.
8
+ */
9
+ continue?: boolean;
10
+ /**
11
+ * Object keys that can be ignored, meaning they do not get visited.
12
+ */
13
+ ignoreKeys?: Set<string>;
14
+ }
15
+ export interface TransformContext extends VisitContext {
16
+ /**
17
+ * Object keys that will be shallowly copied but not traversed.
18
+ * When the same key is included here and in ignoreKeys, the copy will still be made.
19
+ */
20
+ shallowKeys?: Set<string>;
21
+ /**
22
+ * Whether the visited object should be shallowly copied or not. Defaults to true.
23
+ */
24
+ copy?: boolean;
25
+ }
26
+ export interface SelectiveTraversalContext<Nodes> {
27
+ /**
28
+ * Nodes you should visit next. Defaults to empty list
29
+ */
30
+ next?: Nodes[];
31
+ /**
32
+ * Whether you should stop visiting after visiting this object. Default false.
33
+ */
34
+ shortcut?: boolean;
35
+ }
36
+ export declare class TransformerObject {
37
+ protected readonly defaultContext: TransformContext;
38
+ protected maxStackSize: number;
39
+ /**
40
+ * Creates stateless transformer.
41
+ * @param defaultContext
42
+ */
43
+ constructor(defaultContext?: TransformContext);
44
+ /**
45
+ * Function to shallow clone any type.
46
+ * @param obj
47
+ * @protected
48
+ */
49
+ protected clone<T>(obj: T): T;
50
+ /**
51
+ * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.
52
+ * @param startObject object to start iterating from
53
+ * @param mapper mapper to transform the various objects - argument is a copy of the original
54
+ * @param preVisitor callback that is evaluated before iterating deeper.
55
+ * If continues is false, we do not iterate deeper, current object is still mapped. - default: true
56
+ * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.
57
+ * - Default false
58
+ */
59
+ transformObject(startObject: object, mapper: (copy: object, orig: object) => unknown, preVisitor?: (orig: object) => TransformContext): unknown;
60
+ /**
61
+ * Visitor that visits all objects. Visits deeper objects first.
62
+ */
63
+ visitObject(startObject: object, visitor: (orig: object) => void, preVisitor?: (orig: object) => VisitContext): void;
64
+ }
@@ -0,0 +1,204 @@
1
+ export class TransformerObject {
2
+ defaultContext;
3
+ maxStackSize = 1_000_000;
4
+ /**
5
+ * Creates stateless transformer.
6
+ * @param defaultContext
7
+ */
8
+ constructor(defaultContext = {}) {
9
+ this.defaultContext = defaultContext;
10
+ }
11
+ /**
12
+ * Function to shallow clone any type.
13
+ * @param obj
14
+ * @protected
15
+ */
16
+ clone(obj) {
17
+ if (obj === null || typeof obj !== 'object') {
18
+ return obj;
19
+ }
20
+ const proto = Object.getPrototypeOf(obj);
21
+ // Fast path: plain object
22
+ if (proto === Object.prototype || proto === null) {
23
+ // Spread or assign preserves fast properties
24
+ return { ...obj };
25
+ }
26
+ // Otherwise, preserve prototype for custom objects
27
+ return Object.assign(Object.create(proto), obj);
28
+ }
29
+ /**
30
+ * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.
31
+ * @param startObject object to start iterating from
32
+ * @param mapper mapper to transform the various objects - argument is a copy of the original
33
+ * @param preVisitor callback that is evaluated before iterating deeper.
34
+ * If continues is false, we do not iterate deeper, current object is still mapped. - default: true
35
+ * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.
36
+ * - Default false
37
+ */
38
+ transformObject(startObject, mapper, preVisitor = () => ({})) {
39
+ const defaults = this.defaultContext;
40
+ const defaultCopyFlag = defaults.copy ?? true;
41
+ const defaultContinues = defaults.continue ?? true;
42
+ const defaultIgnoreKeys = defaults.ignoreKeys;
43
+ const defaultShallowKeys = defaults.shallowKeys;
44
+ const defaultDidShortCut = defaults.shortcut ?? false;
45
+ // Code handles own stack instead of using recursion - this optimizes it for deep operations.
46
+ let didShortCut = false;
47
+ const resultWrap = { res: startObject };
48
+ // Grows with stack
49
+ const stack = [startObject];
50
+ const stackParent = [resultWrap];
51
+ const stackParentKey = ['res'];
52
+ // Grows with reverse stack - when popping down the stack, you realise you still want to map something.
53
+ // Counter of stack size when we started adding the children of this object, going beyond this means a new parent
54
+ const handleMapperOnLen = [];
55
+ const mapperCopyStack = [];
56
+ const mapperOrigStack = [];
57
+ const mapperParent = [];
58
+ const mapperParentKey = [];
59
+ function handleMapper() {
60
+ while (stack.length === handleMapperOnLen.at(-1)) {
61
+ handleMapperOnLen.pop();
62
+ const copyToMap = mapperCopyStack.pop();
63
+ const origToMap = mapperOrigStack.pop();
64
+ const parent = mapperParent.pop();
65
+ const parentKey = mapperParentKey.pop();
66
+ parent[parentKey] = mapper(copyToMap, origToMap);
67
+ }
68
+ }
69
+ while (stack.length > 0 && stack.length < this.maxStackSize) {
70
+ const curObject = stack.pop();
71
+ const curParent = stackParent.pop();
72
+ const curKey = stackParentKey.pop();
73
+ // Only add to the stack when you did not shortcut
74
+ if (!didShortCut) {
75
+ if (Array.isArray(curObject)) {
76
+ const newArr = [...curObject];
77
+ handleMapperOnLen.push(stack.length);
78
+ mapperCopyStack.push(newArr);
79
+ mapperOrigStack.push(curObject);
80
+ mapperParent.push(curParent);
81
+ mapperParentKey.push(curKey);
82
+ for (let index = curObject.length - 1; index >= 0; index--) {
83
+ const val = curObject[index];
84
+ if (val !== null && typeof val === 'object') {
85
+ stack.push(val);
86
+ stackParent.push(newArr);
87
+ stackParentKey.push(index.toString());
88
+ }
89
+ }
90
+ handleMapper();
91
+ continue;
92
+ }
93
+ // Perform pre visit before expanding the stack
94
+ const context = preVisitor(curObject);
95
+ const copyFlag = context.copy ?? defaultCopyFlag;
96
+ const continues = context.continue ?? defaultContinues;
97
+ const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;
98
+ const shallowKeys = context.shallowKeys ?? defaultShallowKeys;
99
+ didShortCut = context.shortcut ?? defaultDidShortCut;
100
+ const copy = copyFlag ? this.clone(curObject) : curObject;
101
+ // Register that you want to be visited
102
+ handleMapperOnLen.push(stack.length);
103
+ mapperCopyStack.push(copy);
104
+ mapperOrigStack.push(curObject);
105
+ mapperParent.push(curParent);
106
+ mapperParentKey.push(curKey);
107
+ // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.
108
+ if (continues && !didShortCut) {
109
+ for (const key in copy) {
110
+ if (!Object.hasOwn(copy, key)) {
111
+ continue;
112
+ }
113
+ const val = copy[key];
114
+ // If shallow copy required, do
115
+ const onlyShallow = shallowKeys && shallowKeys?.has(key);
116
+ if (onlyShallow) {
117
+ // Do not add stack entry - assign straight away
118
+ copy[key] = this.clone(val);
119
+ }
120
+ if (ignoreKeys && ignoreKeys.has(key)) {
121
+ // Do not add stack entry
122
+ continue;
123
+ }
124
+ if (!onlyShallow && val !== null && typeof val === 'object') {
125
+ // Do add stack entry.
126
+ stack.push(val);
127
+ stackParentKey.push(key);
128
+ stackParent.push(copy);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ handleMapper();
134
+ }
135
+ if (stack.length >= this.maxStackSize) {
136
+ throw new Error('Transform object stack overflowed');
137
+ }
138
+ handleMapper();
139
+ return resultWrap.res;
140
+ }
141
+ /**
142
+ * Visitor that visits all objects. Visits deeper objects first.
143
+ */
144
+ visitObject(startObject, visitor, preVisitor = () => ({})) {
145
+ const defaults = this.defaultContext;
146
+ const defaultContinues = defaults.continue ?? true;
147
+ const defaultIgnoreKeys = defaults.ignoreKeys;
148
+ const defaultShortcut = defaults.shortcut ?? false;
149
+ let didShortCut = false;
150
+ // Stack of things to preVisit
151
+ const stack = [startObject];
152
+ // When the stack is done preVisiting things above this lengths, visit the bellow
153
+ const handleVisitorOnLen = [];
154
+ const visitorStack = [];
155
+ function handleVisitor() {
156
+ while (stack.length === handleVisitorOnLen.at(-1)) {
157
+ handleVisitorOnLen.pop();
158
+ const toVisit = visitorStack.pop();
159
+ visitor(toVisit);
160
+ }
161
+ }
162
+ while (stack.length > 0 && stack.length < this.maxStackSize) {
163
+ const curObject = stack.pop();
164
+ if (!didShortCut) {
165
+ if (Array.isArray(curObject)) {
166
+ for (let i = curObject.length - 1; i >= 0; i--) {
167
+ stack.push(curObject[i]);
168
+ }
169
+ handleVisitor();
170
+ continue;
171
+ }
172
+ // Perform pre visit before expanding the stack
173
+ const context = preVisitor(curObject);
174
+ didShortCut = context.shortcut ?? defaultShortcut;
175
+ const continues = context.continue ?? defaultContinues;
176
+ const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;
177
+ // Register that you want to be visited
178
+ handleVisitorOnLen.push(stack.length);
179
+ visitorStack.push(curObject);
180
+ // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.
181
+ if (continues && !didShortCut) {
182
+ for (const key in curObject) {
183
+ if (!Object.hasOwn(curObject, key)) {
184
+ continue;
185
+ }
186
+ if (ignoreKeys && ignoreKeys.has(key)) {
187
+ continue;
188
+ }
189
+ const val = curObject[key];
190
+ if (val && typeof val === 'object') {
191
+ stack.push(val);
192
+ }
193
+ }
194
+ }
195
+ }
196
+ handleVisitor();
197
+ }
198
+ if (stack.length >= this.maxStackSize) {
199
+ throw new Error('Transform object stack overflowed');
200
+ }
201
+ handleVisitor();
202
+ }
203
+ }
204
+ //# sourceMappingURL=TransformerObject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransformerObject.js","sourceRoot":"","sources":["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 /**\n * Function to shallow clone any type.\n * @param obj\n * @protected\n */\n protected clone<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.clone(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.clone(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"]}
@@ -0,0 +1,94 @@
1
+ import type { Node } from './nodeTypings.js';
2
+ import type { SelectiveTraversalContext, TransformContext, VisitContext } from './TransformerObject.js';
3
+ import type { DefaultNodePreVisitor, Safeness, SafeWrap } from './TransformerTyped.js';
4
+ import { TransformerTyped } from './TransformerTyped.js';
5
+ export declare class TransformerSubTyped<Nodes extends Pick<Node, 'type' | 'subType'>> extends TransformerTyped<Nodes> {
6
+ constructor(defaultContext?: TransformContext, defaultNodePreVisitor?: DefaultNodePreVisitor<Nodes>);
7
+ /**
8
+ * Shares the functionality and first two arguments with {@link this.transformNode}.
9
+ * The third argument allows you to also transform based on the subType of objects.
10
+ * Note that when a callback for the subtype is provided, the callback for the general type is **NOT** executed.
11
+ * @param startObject
12
+ * @param nodeCallBacks
13
+ * @param nodeSpecificCallBacks
14
+ */
15
+ transformNodeSpecific<Safe extends Safeness = 'safe', OutType = unknown>(startObject: object, nodeCallBacks: {
16
+ [T in Nodes['type']]?: {
17
+ transform?: (copy: SafeWrap<Safe, Extract<Nodes, {
18
+ type: T;
19
+ }>>, orig: Extract<Nodes, {
20
+ type: T;
21
+ }>) => unknown;
22
+ preVisitor?: (orig: Extract<Nodes, {
23
+ type: T;
24
+ }>) => TransformContext;
25
+ };
26
+ }, nodeSpecificCallBacks: {
27
+ [Type in Nodes['type']]?: {
28
+ [SubType in Extract<Nodes, {
29
+ type: Type;
30
+ subType: string;
31
+ }>['subType']]?: {
32
+ transform?: (op: SafeWrap<Safe, Extract<Nodes, {
33
+ type: Type;
34
+ subType: SubType;
35
+ }>>) => unknown;
36
+ preVisitor?: (op: Extract<Nodes, {
37
+ type: Type;
38
+ subType: SubType;
39
+ }>) => TransformContext;
40
+ };
41
+ };
42
+ }): Safe extends 'unsafe' ? OutType : unknown;
43
+ /**
44
+ * Similar to {@link this.visitNode} but also allows you to match based on the subtype of objects.
45
+ * When both nodeCallBack and NodeSpecific callBack are matched, will only visit nodeSpecifCallback
46
+ */
47
+ visitNodeSpecific(startObject: object, nodeCallBacks: {
48
+ [T in Nodes['type']]?: {
49
+ visitor?: (op: Extract<Nodes, {
50
+ type: T;
51
+ }>) => void;
52
+ preVisitor?: (op: Extract<Nodes, {
53
+ type: T;
54
+ }>) => VisitContext;
55
+ };
56
+ }, nodeSpecificCallBacks: {
57
+ [Type in Nodes['type']]?: {
58
+ [Subtype in Extract<Nodes, {
59
+ type: Type;
60
+ subType: string;
61
+ }>['subType']]?: {
62
+ visitor?: (op: Extract<Nodes, {
63
+ type: Type;
64
+ subType: Subtype;
65
+ }>) => void;
66
+ preVisitor?: (op: Extract<Nodes, {
67
+ type: Type;
68
+ subType: Subtype;
69
+ }>) => VisitContext;
70
+ };
71
+ };
72
+ }): void;
73
+ /**
74
+ * Similar to {@link this.traverseNodes} but also allows you to match based on the subtype of objects.
75
+ * @param currentNode
76
+ * @param traverseNode
77
+ * @param traverseSubNode
78
+ */
79
+ traverseSubNodes(currentNode: Nodes, traverseNode: {
80
+ [Type in Nodes['type']]?: (op: Extract<Nodes, {
81
+ type: Type;
82
+ }>) => SelectiveTraversalContext<Nodes>;
83
+ }, traverseSubNode: {
84
+ [Type in Nodes['type']]?: {
85
+ [Subtype in Extract<Nodes, {
86
+ type: Type;
87
+ subType: string;
88
+ }>['subType']]?: (op: Extract<Nodes, {
89
+ type: Type;
90
+ subType: Subtype;
91
+ }>) => SelectiveTraversalContext<Nodes>;
92
+ };
93
+ }): void;
94
+ }
@@ -0,0 +1,116 @@
1
+ import { TransformerTyped } from './TransformerTyped.js';
2
+ export class TransformerSubTyped extends TransformerTyped {
3
+ constructor(defaultContext = {}, defaultNodePreVisitor = {}) {
4
+ super(defaultContext, defaultNodePreVisitor);
5
+ }
6
+ ;
7
+ /**
8
+ * Shares the functionality and first two arguments with {@link this.transformNode}.
9
+ * The third argument allows you to also transform based on the subType of objects.
10
+ * Note that when a callback for the subtype is provided, the callback for the general type is **NOT** executed.
11
+ * @param startObject
12
+ * @param nodeCallBacks
13
+ * @param nodeSpecificCallBacks
14
+ */
15
+ transformNodeSpecific(startObject, nodeCallBacks, nodeSpecificCallBacks) {
16
+ const transformWrapper = (copy, orig) => {
17
+ let ogTransform;
18
+ const casted = copy;
19
+ if (casted.type && casted.subType) {
20
+ const specific = nodeSpecificCallBacks[casted.type];
21
+ if (specific) {
22
+ ogTransform = specific[casted.subType]?.transform;
23
+ }
24
+ if (!ogTransform) {
25
+ ogTransform = nodeCallBacks[casted.type]?.transform;
26
+ }
27
+ }
28
+ return ogTransform ? ogTransform(casted, orig) : copy;
29
+ };
30
+ const preVisitWrapper = (curObject) => {
31
+ let ogPreVisit;
32
+ const casted = curObject;
33
+ if (casted.type && casted.subType) {
34
+ const specific = nodeSpecificCallBacks[casted.type];
35
+ if (specific) {
36
+ ogPreVisit = specific[casted.subType]?.preVisitor;
37
+ }
38
+ if (!ogPreVisit) {
39
+ ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;
40
+ }
41
+ }
42
+ return ogPreVisit ? ogPreVisit(casted) : {};
43
+ };
44
+ return this.transformObject(startObject, transformWrapper, preVisitWrapper);
45
+ }
46
+ /**
47
+ * Similar to {@link this.visitNode} but also allows you to match based on the subtype of objects.
48
+ * When both nodeCallBack and NodeSpecific callBack are matched, will only visit nodeSpecifCallback
49
+ */
50
+ visitNodeSpecific(startObject, nodeCallBacks, nodeSpecificCallBacks) {
51
+ const visitWrapper = (curObject) => {
52
+ let ogTransform;
53
+ const casted = curObject;
54
+ if (casted.type && casted.subType) {
55
+ const specific = nodeSpecificCallBacks[casted.type];
56
+ if (specific) {
57
+ ogTransform = specific[casted.subType]?.visitor;
58
+ }
59
+ if (!ogTransform) {
60
+ ogTransform = nodeCallBacks[casted.type]?.visitor;
61
+ }
62
+ }
63
+ if (ogTransform) {
64
+ ogTransform(casted);
65
+ }
66
+ };
67
+ const preVisitWrapper = (curObject) => {
68
+ let ogPreVisit;
69
+ const casted = curObject;
70
+ if (casted.type && casted.subType) {
71
+ const specific = nodeSpecificCallBacks[casted.type];
72
+ if (specific) {
73
+ ogPreVisit = specific[casted.subType]?.preVisitor;
74
+ }
75
+ if (!ogPreVisit) {
76
+ ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;
77
+ }
78
+ }
79
+ return ogPreVisit ? ogPreVisit(casted) : {};
80
+ };
81
+ this.visitObject(startObject, visitWrapper, preVisitWrapper);
82
+ }
83
+ /**
84
+ * Similar to {@link this.traverseNodes} but also allows you to match based on the subtype of objects.
85
+ * @param currentNode
86
+ * @param traverseNode
87
+ * @param traverseSubNode
88
+ */
89
+ traverseSubNodes(currentNode, traverseNode, traverseSubNode) {
90
+ let didShortCut = false;
91
+ const recurse = (curNode) => {
92
+ let traverser;
93
+ const subObj = traverseSubNode[curNode.type];
94
+ if (subObj) {
95
+ traverser = subObj[curNode.subType];
96
+ }
97
+ if (!traverser) {
98
+ traverser = traverseNode[curNode.type];
99
+ }
100
+ if (traverser) {
101
+ const { next, shortcut } = traverser(curNode);
102
+ didShortCut = shortcut ?? false;
103
+ if (!didShortCut) {
104
+ for (const node of next ?? []) {
105
+ if (didShortCut) {
106
+ return;
107
+ }
108
+ recurse(node);
109
+ }
110
+ }
111
+ }
112
+ };
113
+ recurse(currentNode);
114
+ }
115
+ }
116
+ //# sourceMappingURL=TransformerSubTyped.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransformerSubTyped.js","sourceRoot":"","sources":["TransformerSubTyped.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Node } from './nodeTypings.js';\nimport type { SelectiveTraversalContext, TransformContext, VisitContext } from './TransformerObject.js';\nimport type { DefaultNodePreVisitor, Safeness, SafeWrap } from './TransformerTyped.js';\nimport { TransformerTyped } from './TransformerTyped.js';\n\nexport class TransformerSubTyped<Nodes extends Pick<Node, 'type' | 'subType'>> extends TransformerTyped<Nodes> {\n public constructor(\n defaultContext: TransformContext = {},\n defaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ) {\n super(defaultContext, defaultNodePreVisitor);\n };\n\n /**\n * Shares the functionality and first two arguments with {@link this.transformNode}.\n * The third argument allows you to also transform based on the subType of objects.\n * Note that when a callback for the subtype is provided, the callback for the general type is **NOT** executed.\n * @param startObject\n * @param nodeCallBacks\n * @param nodeSpecificCallBacks\n */\n public transformNodeSpecific<Safe extends Safeness = 'safe', OutType = unknown>(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n transform?: (copy: SafeWrap<Safe, Extract<Nodes, { type: T }>>, orig: Extract<Nodes, { type: T }>) => unknown;\n preVisitor?: (orig: Extract<Nodes, { type: T }>) => TransformContext;\n }},\n nodeSpecificCallBacks: {[Type in Nodes['type']]?: {\n [SubType in Extract<Nodes, { type: Type; subType: string }>['subType']]?: {\n transform?: (op: SafeWrap<Safe, Extract<Nodes, { type: Type; subType: SubType }>>) => unknown;\n preVisitor?: (op: Extract<Nodes, { type: Type; subType: SubType }>) => TransformContext;\n }}},\n ): Safe extends 'unsafe' ? OutType : unknown {\n const transformWrapper = (copy: object, orig: object): unknown => {\n let ogTransform: ((copy: any, orig: any) => unknown) | undefined;\n const casted = <{ type?: Nodes['type']; subType?: string }>copy;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogTransform = specific[<keyof typeof specific> casted.subType]?.transform;\n }\n if (!ogTransform) {\n ogTransform = nodeCallBacks[casted.type]?.transform;\n }\n }\n return ogTransform ? ogTransform(casted, orig) : copy;\n };\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n const casted = <{ type?: Nodes['type']; subType?: string }>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogPreVisit = specific[<keyof typeof specific> casted.subType]?.preVisitor;\n }\n if (!ogPreVisit) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n }\n }\n return ogPreVisit ? ogPreVisit(casted) : {};\n };\n return <any> this.transformObject(startObject, transformWrapper, preVisitWrapper);\n }\n\n /**\n * Similar to {@link this.visitNode} but also allows you to match based on the subtype of objects.\n * When both nodeCallBack and NodeSpecific callBack are matched, will only visit nodeSpecifCallback\n */\n public visitNodeSpecific(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n visitor?: (op: Extract<Nodes, { type: T }>) => void;\n preVisitor?: (op: Extract<Nodes, { type: T }>) => VisitContext;\n }},\n nodeSpecificCallBacks: {[Type in Nodes['type']]?:\n {[Subtype in Extract<Nodes, { type: Type; subType: string }>['subType']]?: {\n visitor?: (op: Extract<Nodes, { type: Type; subType: Subtype }>) => void;\n preVisitor?: (op: Extract<Nodes, { type: Type; subType: Subtype }>) => VisitContext;\n }}},\n ): void {\n const visitWrapper = (curObject: object): void => {\n let ogTransform: ((node: any) => void) | undefined;\n const casted = <{ type?: Nodes['type']; subType?: string }>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogTransform = specific[<keyof typeof specific> casted.subType]?.visitor;\n }\n if (!ogTransform) {\n ogTransform = nodeCallBacks[casted.type]?.visitor;\n }\n }\n if (ogTransform) {\n ogTransform(casted);\n }\n };\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n const casted = <{ type?: Nodes['type']; subType?: string }>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogPreVisit = specific[<keyof typeof specific> casted.subType]?.preVisitor;\n }\n if (!ogPreVisit) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n }\n }\n return ogPreVisit ? ogPreVisit(casted) : {};\n };\n this.visitObject(startObject, visitWrapper, preVisitWrapper);\n }\n\n /**\n * Similar to {@link this.traverseNodes} but also allows you to match based on the subtype of objects.\n * @param currentNode\n * @param traverseNode\n * @param traverseSubNode\n */\n public traverseSubNodes(\n currentNode: Nodes,\n traverseNode: {[Type in Nodes['type']]?:\n (op: Extract<Nodes, { type: Type }>) => SelectiveTraversalContext<Nodes> },\n traverseSubNode: {[Type in Nodes['type']]?:\n {[Subtype in Extract<Nodes, { type: Type; subType: string }>['subType']]?:\n (op: Extract<Nodes, { type: Type; subType: Subtype }>) => SelectiveTraversalContext<Nodes> }},\n ): void {\n let didShortCut = false;\n\n const recurse = (curNode: Nodes): void => {\n let traverser: ((call: any) => SelectiveTraversalContext<Nodes>) | undefined;\n const subObj = traverseSubNode[<Nodes['type']>curNode.type];\n if (subObj) {\n traverser = subObj[<keyof typeof subObj>curNode.subType];\n }\n if (!traverser) {\n traverser = traverseNode[<Nodes['type']>curNode.type];\n }\n if (traverser) {\n const { next, shortcut } = traverser(<any>curNode);\n didShortCut = shortcut ?? false;\n if (!didShortCut) {\n for (const node of next ?? []) {\n if (didShortCut) {\n return;\n }\n recurse(node);\n }\n }\n }\n };\n\n recurse(currentNode);\n }\n}\n"]}