@grest-ts/locator 0.0.6 → 0.0.7
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/LICENSE +21 -21
- package/README.md +209 -209
- package/dist/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/GGLocator.ts +45 -45
- package/src/GGLocatorKey.ts +29 -29
- package/src/GGLocatorScope.ts +205 -205
- package/src/GGLocatorScopeDebug.ts +153 -153
- package/src/GGLocatorStorage.ts +9 -9
- package/src/index-browser.ts +4 -4
- package/src/index-node.ts +8 -8
|
@@ -1,153 +1,153 @@
|
|
|
1
|
-
// Console ANSI colors - defined inline to avoid circular dependency with @grest-ts/logger
|
|
2
|
-
const LOG_COLORS = {
|
|
3
|
-
reset: '\x1b[0m',
|
|
4
|
-
bright: '\x1b[1m',
|
|
5
|
-
dim: '\x1b[2m',
|
|
6
|
-
cyan: '\x1b[36m',
|
|
7
|
-
yellow: '\x1b[33m',
|
|
8
|
-
green: '\x1b[32m',
|
|
9
|
-
gray: '\x1b[90m',
|
|
10
|
-
magenta: '\x1b[35m',
|
|
11
|
-
blue: '\x1b[34m',
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export interface GGLocatorDebugService {
|
|
15
|
-
key: string;
|
|
16
|
-
className: string | undefined;
|
|
17
|
-
stack: string[];
|
|
18
|
-
composeLine: string | undefined;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface GGLocatorRawServiceData {
|
|
22
|
-
key: string;
|
|
23
|
-
value: any;
|
|
24
|
-
rawStack: string[];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class GGLocatorScopeDebugList {
|
|
28
|
-
|
|
29
|
-
public readonly scopes: GGLocatorScopeDebug[] = [];
|
|
30
|
-
|
|
31
|
-
public add(tree: GGLocatorScopeDebug) {
|
|
32
|
-
this.scopes.push(tree);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public toString(color: boolean = false): string {
|
|
36
|
-
return this.scopes.map(t => t.toString(color)).join("\n\n");
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public toJSON(): object {
|
|
40
|
-
return {
|
|
41
|
-
scopes: this.scopes.map(s => s.toJSON())
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export class GGLocatorScopeDebug {
|
|
48
|
-
|
|
49
|
-
public readonly scopeName: string;
|
|
50
|
-
public readonly creationStack: string[];
|
|
51
|
-
public readonly services: GGLocatorDebugService[] = [];
|
|
52
|
-
|
|
53
|
-
constructor(scopeName: string, rawCreationStack: string[]) {
|
|
54
|
-
this.scopeName = scopeName;
|
|
55
|
-
this.creationStack = this.processCreationStack(rawCreationStack);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private processCreationStack(rawStack: string[]): string[] {
|
|
59
|
-
return rawStack
|
|
60
|
-
.map(line => this.normalizeStackLine(line))
|
|
61
|
-
.filter((line): line is string => line !== undefined);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public add(key: string, value: any, rawStack: string[] | undefined): void {
|
|
65
|
-
this.services.push(this.processService({key: key, value, rawStack: rawStack ?? []}));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private processService(raw: GGLocatorRawServiceData): GGLocatorDebugService {
|
|
69
|
-
const className = raw.value?.constructor?.name;
|
|
70
|
-
|
|
71
|
-
// Find compose index and trim stack up to and including compose
|
|
72
|
-
const composeIndex = raw.rawStack.findIndex(line => line.includes('.compose'));
|
|
73
|
-
const trimmedStack = composeIndex >= 0
|
|
74
|
-
? raw.rawStack.slice(0, composeIndex + 1)
|
|
75
|
-
: raw.rawStack;
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
key: raw.key,
|
|
79
|
-
className: className !== 'Object' ? className : undefined,
|
|
80
|
-
stack: trimmedStack
|
|
81
|
-
.map(line => this.normalizeStackLine(line))
|
|
82
|
-
.filter((line): line is string => line !== undefined),
|
|
83
|
-
composeLine: this.findComposeLine(raw.rawStack)
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private normalizeStackLine(line: string): string | undefined {
|
|
88
|
-
const trimmed = line.trim();
|
|
89
|
-
if (!trimmed) return undefined;
|
|
90
|
-
|
|
91
|
-
// Extract "at ClassName.method (file:line)" or just the location
|
|
92
|
-
const match = trimmed.match(/at\s+(.+)/);
|
|
93
|
-
const location = match ? match[1] : trimmed;
|
|
94
|
-
return this.normalizePathToFileUrl(location);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private findComposeLine(stack: string[]): string | undefined {
|
|
98
|
-
const composeLine = stack.find(line => line.includes('.compose'));
|
|
99
|
-
if (!composeLine) return undefined;
|
|
100
|
-
return this.normalizeStackLine(composeLine);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
private normalizePathToFileUrl(location: string): string {
|
|
104
|
-
// Convert Windows paths to file:// URLs for better IDE support
|
|
105
|
-
// Matches: (C:\path\file.ts:10:5) or C:\path\file.ts:10:5
|
|
106
|
-
return location.replace(/([\w]:[\\/][^:)]+:\d+:\d+)/g, (path) => {
|
|
107
|
-
const normalizedPath = path.replace(/\\/g, '/');
|
|
108
|
-
return `file:///${normalizedPath}`;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
public toString(color: boolean = false): string {
|
|
113
|
-
const C = color ? LOG_COLORS : {reset: "", bright: "", dim: "", cyan: "", yellow: "", green: "", gray: "", magenta: "", blue: ""};
|
|
114
|
-
const lines: string[] = [];
|
|
115
|
-
|
|
116
|
-
lines.push(`${C.bright}${C.cyan}Scope: ${this.scopeName}${C.reset}`);
|
|
117
|
-
|
|
118
|
-
if (this.creationStack.length > 0) {
|
|
119
|
-
lines.push(`\t${C.dim}Created at:${C.reset}`);
|
|
120
|
-
for (const frame of this.creationStack) {
|
|
121
|
-
lines.push(`\t\t${C.gray}${frame}${C.reset}`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
lines.push(`\t${C.dim}---${C.reset}`);
|
|
126
|
-
|
|
127
|
-
for (const service of this.services) {
|
|
128
|
-
const className = service.className ? `${C.dim} (${service.className})${C.reset}` : "";
|
|
129
|
-
lines.push(`\t${C.yellow}${service.key}${C.reset}${className}`);
|
|
130
|
-
|
|
131
|
-
if (service.composeLine) {
|
|
132
|
-
lines.push(`\t\t${C.green}compose: ${C.reset}${C.gray}${service.composeLine}${C.reset}`);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (service.stack.length > 0) {
|
|
136
|
-
lines.push(`\t\t${C.dim}stack:${C.reset}`);
|
|
137
|
-
for (const frame of service.stack) {
|
|
138
|
-
lines.push(`\t\t\t${C.gray}${frame}${C.reset}`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return lines.join("\n");
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
public toJSON(): object {
|
|
147
|
-
return {
|
|
148
|
-
scopeName: this.scopeName,
|
|
149
|
-
creationStack: this.creationStack,
|
|
150
|
-
services: this.services
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
1
|
+
// Console ANSI colors - defined inline to avoid circular dependency with @grest-ts/logger
|
|
2
|
+
const LOG_COLORS = {
|
|
3
|
+
reset: '\x1b[0m',
|
|
4
|
+
bright: '\x1b[1m',
|
|
5
|
+
dim: '\x1b[2m',
|
|
6
|
+
cyan: '\x1b[36m',
|
|
7
|
+
yellow: '\x1b[33m',
|
|
8
|
+
green: '\x1b[32m',
|
|
9
|
+
gray: '\x1b[90m',
|
|
10
|
+
magenta: '\x1b[35m',
|
|
11
|
+
blue: '\x1b[34m',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export interface GGLocatorDebugService {
|
|
15
|
+
key: string;
|
|
16
|
+
className: string | undefined;
|
|
17
|
+
stack: string[];
|
|
18
|
+
composeLine: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface GGLocatorRawServiceData {
|
|
22
|
+
key: string;
|
|
23
|
+
value: any;
|
|
24
|
+
rawStack: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class GGLocatorScopeDebugList {
|
|
28
|
+
|
|
29
|
+
public readonly scopes: GGLocatorScopeDebug[] = [];
|
|
30
|
+
|
|
31
|
+
public add(tree: GGLocatorScopeDebug) {
|
|
32
|
+
this.scopes.push(tree);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public toString(color: boolean = false): string {
|
|
36
|
+
return this.scopes.map(t => t.toString(color)).join("\n\n");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public toJSON(): object {
|
|
40
|
+
return {
|
|
41
|
+
scopes: this.scopes.map(s => s.toJSON())
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class GGLocatorScopeDebug {
|
|
48
|
+
|
|
49
|
+
public readonly scopeName: string;
|
|
50
|
+
public readonly creationStack: string[];
|
|
51
|
+
public readonly services: GGLocatorDebugService[] = [];
|
|
52
|
+
|
|
53
|
+
constructor(scopeName: string, rawCreationStack: string[]) {
|
|
54
|
+
this.scopeName = scopeName;
|
|
55
|
+
this.creationStack = this.processCreationStack(rawCreationStack);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private processCreationStack(rawStack: string[]): string[] {
|
|
59
|
+
return rawStack
|
|
60
|
+
.map(line => this.normalizeStackLine(line))
|
|
61
|
+
.filter((line): line is string => line !== undefined);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public add(key: string, value: any, rawStack: string[] | undefined): void {
|
|
65
|
+
this.services.push(this.processService({key: key, value, rawStack: rawStack ?? []}));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private processService(raw: GGLocatorRawServiceData): GGLocatorDebugService {
|
|
69
|
+
const className = raw.value?.constructor?.name;
|
|
70
|
+
|
|
71
|
+
// Find compose index and trim stack up to and including compose
|
|
72
|
+
const composeIndex = raw.rawStack.findIndex(line => line.includes('.compose'));
|
|
73
|
+
const trimmedStack = composeIndex >= 0
|
|
74
|
+
? raw.rawStack.slice(0, composeIndex + 1)
|
|
75
|
+
: raw.rawStack;
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
key: raw.key,
|
|
79
|
+
className: className !== 'Object' ? className : undefined,
|
|
80
|
+
stack: trimmedStack
|
|
81
|
+
.map(line => this.normalizeStackLine(line))
|
|
82
|
+
.filter((line): line is string => line !== undefined),
|
|
83
|
+
composeLine: this.findComposeLine(raw.rawStack)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private normalizeStackLine(line: string): string | undefined {
|
|
88
|
+
const trimmed = line.trim();
|
|
89
|
+
if (!trimmed) return undefined;
|
|
90
|
+
|
|
91
|
+
// Extract "at ClassName.method (file:line)" or just the location
|
|
92
|
+
const match = trimmed.match(/at\s+(.+)/);
|
|
93
|
+
const location = match ? match[1] : trimmed;
|
|
94
|
+
return this.normalizePathToFileUrl(location);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private findComposeLine(stack: string[]): string | undefined {
|
|
98
|
+
const composeLine = stack.find(line => line.includes('.compose'));
|
|
99
|
+
if (!composeLine) return undefined;
|
|
100
|
+
return this.normalizeStackLine(composeLine);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private normalizePathToFileUrl(location: string): string {
|
|
104
|
+
// Convert Windows paths to file:// URLs for better IDE support
|
|
105
|
+
// Matches: (C:\path\file.ts:10:5) or C:\path\file.ts:10:5
|
|
106
|
+
return location.replace(/([\w]:[\\/][^:)]+:\d+:\d+)/g, (path) => {
|
|
107
|
+
const normalizedPath = path.replace(/\\/g, '/');
|
|
108
|
+
return `file:///${normalizedPath}`;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public toString(color: boolean = false): string {
|
|
113
|
+
const C = color ? LOG_COLORS : {reset: "", bright: "", dim: "", cyan: "", yellow: "", green: "", gray: "", magenta: "", blue: ""};
|
|
114
|
+
const lines: string[] = [];
|
|
115
|
+
|
|
116
|
+
lines.push(`${C.bright}${C.cyan}Scope: ${this.scopeName}${C.reset}`);
|
|
117
|
+
|
|
118
|
+
if (this.creationStack.length > 0) {
|
|
119
|
+
lines.push(`\t${C.dim}Created at:${C.reset}`);
|
|
120
|
+
for (const frame of this.creationStack) {
|
|
121
|
+
lines.push(`\t\t${C.gray}${frame}${C.reset}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
lines.push(`\t${C.dim}---${C.reset}`);
|
|
126
|
+
|
|
127
|
+
for (const service of this.services) {
|
|
128
|
+
const className = service.className ? `${C.dim} (${service.className})${C.reset}` : "";
|
|
129
|
+
lines.push(`\t${C.yellow}${service.key}${C.reset}${className}`);
|
|
130
|
+
|
|
131
|
+
if (service.composeLine) {
|
|
132
|
+
lines.push(`\t\t${C.green}compose: ${C.reset}${C.gray}${service.composeLine}${C.reset}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (service.stack.length > 0) {
|
|
136
|
+
lines.push(`\t\t${C.dim}stack:${C.reset}`);
|
|
137
|
+
for (const frame of service.stack) {
|
|
138
|
+
lines.push(`\t\t\t${C.gray}${frame}${C.reset}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return lines.join("\n");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public toJSON(): object {
|
|
147
|
+
return {
|
|
148
|
+
scopeName: this.scopeName,
|
|
149
|
+
creationStack: this.creationStack,
|
|
150
|
+
services: this.services
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
package/src/GGLocatorStorage.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {GGLocatorScope} from "./GGLocatorScope";
|
|
2
|
-
import {BrowserAsyncStorage, type IAsyncStorage} from "@grest-ts/common";
|
|
3
|
-
|
|
4
|
-
// Browser-safe by default. Node.js entry replaces with real AsyncLocalStorage.
|
|
5
|
-
export let GG_ASYNC_STORAGE: IAsyncStorage<GGLocatorScope> = new BrowserAsyncStorage();
|
|
6
|
-
|
|
7
|
-
export function _initLocatorStorage(storage: IAsyncStorage<GGLocatorScope>): void {
|
|
8
|
-
GG_ASYNC_STORAGE = storage;
|
|
9
|
-
}
|
|
1
|
+
import type {GGLocatorScope} from "./GGLocatorScope";
|
|
2
|
+
import {BrowserAsyncStorage, type IAsyncStorage} from "@grest-ts/common";
|
|
3
|
+
|
|
4
|
+
// Browser-safe by default. Node.js entry replaces with real AsyncLocalStorage.
|
|
5
|
+
export let GG_ASYNC_STORAGE: IAsyncStorage<GGLocatorScope> = new BrowserAsyncStorage();
|
|
6
|
+
|
|
7
|
+
export function _initLocatorStorage(storage: IAsyncStorage<GGLocatorScope>): void {
|
|
8
|
+
GG_ASYNC_STORAGE = storage;
|
|
9
|
+
}
|
package/src/index-browser.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {GGLocatorScope, GGLocatorServiceType} from "./GGLocatorScope";
|
|
2
|
-
export type {GGLocatorLifecycleCallbacks} from "./GGLocatorScope";
|
|
3
|
-
export {GGLocatorKey} from "./GGLocatorKey";
|
|
4
|
-
export {GGLocator} from "./GGLocator";
|
|
1
|
+
export {GGLocatorScope, GGLocatorServiceType} from "./GGLocatorScope";
|
|
2
|
+
export type {GGLocatorLifecycleCallbacks} from "./GGLocatorScope";
|
|
3
|
+
export {GGLocatorKey} from "./GGLocatorKey";
|
|
4
|
+
export {GGLocator} from "./GGLocator";
|
package/src/index-node.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {AsyncLocalStorage} from "node:async_hooks";
|
|
2
|
-
import {_initLocatorStorage} from "./GGLocatorStorage";
|
|
3
|
-
_initLocatorStorage(new AsyncLocalStorage());
|
|
4
|
-
|
|
5
|
-
export {GGLocatorScope, GGLocatorServiceType} from "./GGLocatorScope";
|
|
6
|
-
export type {GGLocatorLifecycleCallbacks} from "./GGLocatorScope";
|
|
7
|
-
export {GGLocatorKey} from "./GGLocatorKey";
|
|
8
|
-
export {GGLocator} from "./GGLocator";
|
|
1
|
+
import {AsyncLocalStorage} from "node:async_hooks";
|
|
2
|
+
import {_initLocatorStorage} from "./GGLocatorStorage";
|
|
3
|
+
_initLocatorStorage(new AsyncLocalStorage());
|
|
4
|
+
|
|
5
|
+
export {GGLocatorScope, GGLocatorServiceType} from "./GGLocatorScope";
|
|
6
|
+
export type {GGLocatorLifecycleCallbacks} from "./GGLocatorScope";
|
|
7
|
+
export {GGLocatorKey} from "./GGLocatorKey";
|
|
8
|
+
export {GGLocator} from "./GGLocator";
|