tarojs-plugin-chucker 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chuckerStore = void 0;
4
+ class ChuckerStore {
5
+ constructor() {
6
+ this.logs = [];
7
+ this.listeners = new Set();
8
+ this.maxLogs = 100;
9
+ this.isInitialized = false;
10
+ this.lastNotifyTime = 0;
11
+ this.notifyTimeout = null;
12
+ }
13
+ init(maxLogs = 100) {
14
+ this.maxLogs = maxLogs;
15
+ if (this.isInitialized)
16
+ return;
17
+ this.isInitialized = true;
18
+ }
19
+ // ──────────────────────────────────────────────
20
+ // Internal API (used by interceptors)
21
+ // ──────────────────────────────────────────────
22
+ handleRequestStart(log) {
23
+ this.logs = [log, ...this.logs];
24
+ this.trimLogs();
25
+ this.notify();
26
+ }
27
+ handleRequestComplete(payload) {
28
+ this.logs = this.logs.map((log) => {
29
+ if (log.id === payload.id) {
30
+ return { ...log, ...payload };
31
+ }
32
+ return log;
33
+ });
34
+ this.notify();
35
+ }
36
+ // ──────────────────────────────────────────────
37
+ // Public API (for user-created log entries)
38
+ // ──────────────────────────────────────────────
39
+ /**
40
+ * Add a complete log entry in one call.
41
+ * Useful for logging one-shot events that don't need async tracking.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * chuckerStore.log({
46
+ * type: "websocket",
47
+ * method: "MESSAGE",
48
+ * url: "wss://example.com/ws",
49
+ * requestData: { event: "ping" },
50
+ * status: "success",
51
+ * responseData: { event: "pong" },
52
+ * });
53
+ * ```
54
+ */
55
+ log(input) {
56
+ const id = input.id || "usr_" + Math.random().toString(36).substring(2, 9);
57
+ const log = {
58
+ ...input,
59
+ id,
60
+ startTime: input.startTime || Date.now(),
61
+ };
62
+ this.handleRequestStart(log);
63
+ return id;
64
+ }
65
+ /**
66
+ * Start tracking an async operation. Returns the generated log `id`.
67
+ * Call `completeTracking(id, result)` when the operation finishes.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * const id = chuckerStore.startTracking({
72
+ * type: "graphql",
73
+ * method: "QUERY",
74
+ * url: "https://api.example.com/graphql",
75
+ * requestData: { query: "{ users { id name } }" },
76
+ * });
77
+ *
78
+ * // ... later when response arrives
79
+ * chuckerStore.completeTracking(id, {
80
+ * status: 200,
81
+ * responseData: { users: [...] },
82
+ * });
83
+ * ```
84
+ */
85
+ startTracking(input) {
86
+ const id = input.id || "usr_" + Math.random().toString(36).substring(2, 9);
87
+ const log = {
88
+ ...input,
89
+ id,
90
+ startTime: input.startTime || Date.now(),
91
+ };
92
+ this.handleRequestStart(log);
93
+ return id;
94
+ }
95
+ /**
96
+ * Complete a previously tracked operation.
97
+ * Duration is calculated automatically if not provided.
98
+ */
99
+ completeTracking(id, result = {}) {
100
+ var _a;
101
+ const existing = this.logs.find((log) => log.id === id);
102
+ const duration = (_a = result.duration) !== null && _a !== void 0 ? _a : (existing ? Date.now() - existing.startTime : undefined);
103
+ this.handleRequestComplete({
104
+ id,
105
+ ...result,
106
+ duration,
107
+ });
108
+ }
109
+ // ──────────────────────────────────────────────
110
+ // Core
111
+ // ──────────────────────────────────────────────
112
+ trimLogs() {
113
+ if (this.logs.length > this.maxLogs) {
114
+ this.logs = this.logs.slice(0, this.maxLogs);
115
+ }
116
+ }
117
+ getLogs() {
118
+ return this.logs;
119
+ }
120
+ clear() {
121
+ this.logs = [];
122
+ this.executeNotify();
123
+ }
124
+ subscribe(listener) {
125
+ this.listeners.add(listener);
126
+ // Provide initial state immediately
127
+ listener(this.logs);
128
+ return () => {
129
+ this.listeners.delete(listener);
130
+ };
131
+ }
132
+ executeNotify() {
133
+ this.lastNotifyTime = Date.now();
134
+ if (this.notifyTimeout) {
135
+ clearTimeout(this.notifyTimeout);
136
+ this.notifyTimeout = null;
137
+ }
138
+ this.listeners.forEach((listener) => {
139
+ try {
140
+ listener(this.logs);
141
+ }
142
+ catch (e) {
143
+ console.error("Chucker store notify error:", e);
144
+ }
145
+ });
146
+ }
147
+ notify() {
148
+ const now = Date.now();
149
+ const throttleDelay = 80;
150
+ if (this.notifyTimeout) {
151
+ clearTimeout(this.notifyTimeout);
152
+ this.notifyTimeout = null;
153
+ }
154
+ const timeSinceLastNotify = now - this.lastNotifyTime;
155
+ if (timeSinceLastNotify >= throttleDelay) {
156
+ this.executeNotify();
157
+ }
158
+ else {
159
+ this.notifyTimeout = setTimeout(() => {
160
+ this.executeNotify();
161
+ }, throttleDelay - timeSinceLastNotify);
162
+ }
163
+ }
164
+ }
165
+ const globalObj = typeof global !== "undefined" ? global : typeof window !== "undefined" ? window : {};
166
+ // @ts-ignore
167
+ if (!globalObj.__CHUCKER_STORE__) {
168
+ // @ts-ignore
169
+ globalObj.__CHUCKER_STORE__ = new ChuckerStore();
170
+ }
171
+ // @ts-ignore
172
+ exports.chuckerStore = globalObj.__CHUCKER_STORE__;
@@ -0,0 +1,2 @@
1
+ export declare function generateCurl(url: string, method: string, headers?: Record<string, string>, data?: any): string;
2
+ export declare function formatJson(val: any): string;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCurl = generateCurl;
4
+ exports.formatJson = formatJson;
5
+ function generateCurl(url, method, headers = {}, data = null) {
6
+ let curl = `curl -X ${method.toUpperCase()} "${url}"`;
7
+ // Append headers
8
+ Object.entries(headers).forEach(([key, val]) => {
9
+ const escapedVal = String(val).replace(/"/g, '\\"');
10
+ curl += ` -H "${key}: ${escapedVal}"`;
11
+ });
12
+ // Append body data
13
+ if (data !== undefined && data !== null) {
14
+ let dataStr = "";
15
+ if (typeof data === "object") {
16
+ try {
17
+ dataStr = JSON.stringify(data);
18
+ }
19
+ catch (e) {
20
+ dataStr = String(data);
21
+ }
22
+ }
23
+ else {
24
+ dataStr = String(data);
25
+ }
26
+ // Escape single quotes in the payload
27
+ const escapedData = dataStr.replace(/'/g, "'\\''");
28
+ curl += ` -d '${escapedData}'`;
29
+ }
30
+ return curl;
31
+ }
32
+ function formatJson(val) {
33
+ if (val === undefined || val === null)
34
+ return "";
35
+ if (typeof val === "string") {
36
+ try {
37
+ const parsed = JSON.parse(val.trim());
38
+ return JSON.stringify(parsed, null, 2);
39
+ }
40
+ catch (e) {
41
+ return val;
42
+ }
43
+ }
44
+ try {
45
+ return JSON.stringify(val, null, 2);
46
+ }
47
+ catch (e) {
48
+ return String(val);
49
+ }
50
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "tarojs-plugin-chucker",
3
+ "version": "1.0.0",
4
+ "description": "A Chucker-like debugger plugin for Taro JS miniapps to track api requests, responses and native plugin calls",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "exports": {
12
+ ".": "./dist/index.js",
13
+ "./runtime": "./dist/runtime/index.js"
14
+ },
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "watch": "tsc -w",
18
+ "prepare": "pnpm run build",
19
+ "test": "jest",
20
+ "lint": "oxlint src tests",
21
+ "lint:fix": "oxlint --fix src tests",
22
+ "format": "oxfmt --write src tests",
23
+ "preversion": "pnpm run lint && pnpm run test && pnpm run build",
24
+ "postversion": "git push && git push --tags",
25
+ "release:patch": "npm version patch -m \"release: v%s\"",
26
+ "release:minor": "npm version minor -m \"release: v%s\"",
27
+ "release:major": "npm version major -m \"release: v%s\"",
28
+ "publish:npm": "pnpm run build && npm publish"
29
+ },
30
+ "keywords": [
31
+ "taro",
32
+ "plugin",
33
+ "chucker",
34
+ "debug",
35
+ "network",
36
+ "miniprogram"
37
+ ],
38
+ "author": "",
39
+ "license": "ISC",
40
+ "peerDependencies": {
41
+ "@tarojs/components": ">=3.0.0",
42
+ "@tarojs/taro": ">=3.0.0",
43
+ "react": ">=16.8.0"
44
+ },
45
+ "devDependencies": {
46
+ "@tarojs/components": "^4.2.0",
47
+ "@tarojs/plugin-platform-weapp": "^4.2.0",
48
+ "@tarojs/service": "^4.2.0",
49
+ "@tarojs/taro": "^4.2.0",
50
+ "@types/jest": "^29.0.0",
51
+ "@types/node": "^18.0.0",
52
+ "@types/react": "^18.0.0",
53
+ "jest": "^29.0.0",
54
+ "oxfmt": "^0.58.0",
55
+ "oxlint": "^1.73.0",
56
+ "react": "^18.0.0",
57
+ "ts-jest": "^29.0.0",
58
+ "typescript": "^5.0.0"
59
+ }
60
+ }