@ansight/capacitor 1.0.2-preview.6
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/AnsightCapacitor.podspec +14 -0
- package/LICENSE +200 -0
- package/Package.swift +38 -0
- package/README.md +139 -0
- package/android/build.gradle +52 -0
- package/android/settings.gradle +20 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/kotlin/ai/ansight/capacitor/AnsightCapacitorPlugin.kt +1131 -0
- package/dist/esm/definitions.d.ts +521 -0
- package/dist/esm/definitions.d.ts.map +1 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/dom.d.ts +9 -0
- package/dist/esm/dom.d.ts.map +1 -0
- package/dist/esm/dom.js +237 -0
- package/dist/esm/dom.js.map +1 -0
- package/dist/esm/index.d.ts +156 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +576 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/options.d.ts +57 -0
- package/dist/esm/options.d.ts.map +1 -0
- package/dist/esm/options.js +294 -0
- package/dist/esm/options.js.map +1 -0
- package/dist/esm/standalone.d.ts +5 -0
- package/dist/esm/standalone.d.ts.map +1 -0
- package/dist/esm/standalone.js +18 -0
- package/dist/esm/standalone.js.map +1 -0
- package/dist/plugin.cjs.js +1176 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +1179 -0
- package/dist/plugin.js.map +1 -0
- package/dist/standalone.js +1764 -0
- package/dist/standalone.js.map +1 -0
- package/ios/Sources/AnsightCapacitorPlugin/AnsightCapacitorPlugin.swift +1144 -0
- package/package.json +81 -0
|
@@ -0,0 +1,1176 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var core = require('@capacitor/core');
|
|
6
|
+
|
|
7
|
+
const nodeIds = new WeakMap();
|
|
8
|
+
let nextNodeId = 1;
|
|
9
|
+
function nodeId(element) {
|
|
10
|
+
const existing = nodeIds.get(element);
|
|
11
|
+
if (existing)
|
|
12
|
+
return existing;
|
|
13
|
+
const id = `dom.${nextNodeId++}`;
|
|
14
|
+
nodeIds.set(element, id);
|
|
15
|
+
return id;
|
|
16
|
+
}
|
|
17
|
+
function isVisible(element, style, bounds) {
|
|
18
|
+
return (style.display !== "none" &&
|
|
19
|
+
style.visibility !== "hidden" &&
|
|
20
|
+
style.opacity !== "0" &&
|
|
21
|
+
bounds.width > 0 &&
|
|
22
|
+
bounds.height > 0);
|
|
23
|
+
}
|
|
24
|
+
function accessibleLabel(element, includeText) {
|
|
25
|
+
const labelledBy = element.getAttribute("aria-labelledby");
|
|
26
|
+
const referenced = labelledBy
|
|
27
|
+
?.split(/\s+/)
|
|
28
|
+
.map((id) => document.getElementById(id)?.textContent?.trim())
|
|
29
|
+
.filter(Boolean)
|
|
30
|
+
.join(" ");
|
|
31
|
+
const label = element.getAttribute("aria-label") ??
|
|
32
|
+
referenced ??
|
|
33
|
+
element.getAttribute("alt") ??
|
|
34
|
+
element.getAttribute("title") ??
|
|
35
|
+
(includeText
|
|
36
|
+
? element.textContent?.replace(/\s+/g, " ").trim().slice(0, 240)
|
|
37
|
+
: undefined);
|
|
38
|
+
return label || undefined;
|
|
39
|
+
}
|
|
40
|
+
function attributes(element) {
|
|
41
|
+
return Object.fromEntries(Array.from(element.attributes, ({ name, value }) => [
|
|
42
|
+
name,
|
|
43
|
+
value.slice(0, 500),
|
|
44
|
+
]));
|
|
45
|
+
}
|
|
46
|
+
function captureNode(element, options, depth, limits) {
|
|
47
|
+
if (limits.count >= limits.maxNodes || depth > limits.maxDepth)
|
|
48
|
+
return null;
|
|
49
|
+
const style = getComputedStyle(element);
|
|
50
|
+
const rect = element.getBoundingClientRect();
|
|
51
|
+
const visible = isVisible(element, style, rect);
|
|
52
|
+
if (!visible && !options.includeHidden)
|
|
53
|
+
return null;
|
|
54
|
+
limits.count += 1;
|
|
55
|
+
const children = Array.from(element.children)
|
|
56
|
+
.map((child) => captureNode(child, options, depth + 1, limits))
|
|
57
|
+
.filter((child) => child !== null);
|
|
58
|
+
const htmlElement = element;
|
|
59
|
+
const disabled = element.hasAttribute("disabled") ||
|
|
60
|
+
element.getAttribute("aria-disabled") === "true";
|
|
61
|
+
return {
|
|
62
|
+
id: nodeId(element),
|
|
63
|
+
type: element.tagName.toLowerCase(),
|
|
64
|
+
label: accessibleLabel(element, options.includeText),
|
|
65
|
+
visible,
|
|
66
|
+
enabled: !disabled,
|
|
67
|
+
focusable: htmlElement.tabIndex >= 0 ||
|
|
68
|
+
["A", "BUTTON", "INPUT", "SELECT", "TEXTAREA", "SUMMARY"].includes(element.tagName),
|
|
69
|
+
childCount: children.length,
|
|
70
|
+
bounds: {
|
|
71
|
+
x: rect.x,
|
|
72
|
+
y: rect.y,
|
|
73
|
+
width: rect.width,
|
|
74
|
+
height: rect.height,
|
|
75
|
+
},
|
|
76
|
+
properties: {
|
|
77
|
+
id: element.id || undefined,
|
|
78
|
+
role: element.getAttribute("role") ?? undefined,
|
|
79
|
+
className: element.getAttribute("class") ?? undefined,
|
|
80
|
+
value: element instanceof HTMLInputElement ||
|
|
81
|
+
element instanceof HTMLSelectElement ||
|
|
82
|
+
element instanceof HTMLTextAreaElement
|
|
83
|
+
? element.value
|
|
84
|
+
: undefined,
|
|
85
|
+
checked: element instanceof HTMLInputElement ? element.checked : undefined,
|
|
86
|
+
attributes: options.includeAttributes ? attributes(element) : undefined,
|
|
87
|
+
},
|
|
88
|
+
children,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function findElement(id) {
|
|
92
|
+
return Array.from(document.querySelectorAll("*")).find((element) => nodeId(element) === id);
|
|
93
|
+
}
|
|
94
|
+
function successful(result, message) {
|
|
95
|
+
return { success: true, message, result };
|
|
96
|
+
}
|
|
97
|
+
function installDomTools$1(registerTool, input = {}) {
|
|
98
|
+
const options = {
|
|
99
|
+
source: input.source ?? "capacitor-dom",
|
|
100
|
+
includeHidden: input.includeHidden ?? false,
|
|
101
|
+
maxDepth: input.maxDepth ?? 30,
|
|
102
|
+
maxNodes: input.maxNodes ?? 1500,
|
|
103
|
+
includeText: input.includeText ?? true,
|
|
104
|
+
includeAttributes: input.includeAttributes ?? true,
|
|
105
|
+
allowActions: input.allowActions ?? false,
|
|
106
|
+
};
|
|
107
|
+
const registrations = [
|
|
108
|
+
registerTool({
|
|
109
|
+
id: "dom.get_document",
|
|
110
|
+
name: "Get DOM document",
|
|
111
|
+
description: "Returns the accessible HTML DOM tree rendered inside the Capacitor WebView.",
|
|
112
|
+
category: "UI",
|
|
113
|
+
scope: "read",
|
|
114
|
+
security: { level: "low", summary: "Reads the current app DOM." },
|
|
115
|
+
}, async () => {
|
|
116
|
+
const root = document.documentElement;
|
|
117
|
+
const limits = {
|
|
118
|
+
maxDepth: options.maxDepth,
|
|
119
|
+
maxNodes: options.maxNodes,
|
|
120
|
+
count: 0,
|
|
121
|
+
};
|
|
122
|
+
const tree = captureNode(root, options, 0, limits);
|
|
123
|
+
return successful({
|
|
124
|
+
platform: "web",
|
|
125
|
+
source: options.source,
|
|
126
|
+
adapter: "@ansight/capacitor",
|
|
127
|
+
capturedAtUtc: new Date().toISOString(),
|
|
128
|
+
truncated: limits.count >= limits.maxNodes,
|
|
129
|
+
root: tree,
|
|
130
|
+
}, "DOM document captured.");
|
|
131
|
+
}),
|
|
132
|
+
registerTool({
|
|
133
|
+
id: "dom.inspect_node",
|
|
134
|
+
name: "Inspect DOM node",
|
|
135
|
+
description: "Returns the current state of a DOM node captured by dom.get_document.",
|
|
136
|
+
category: "UI",
|
|
137
|
+
scope: "read",
|
|
138
|
+
argumentsSchema: {
|
|
139
|
+
type: "object",
|
|
140
|
+
required: ["nodeId"],
|
|
141
|
+
properties: { nodeId: { type: "string" } },
|
|
142
|
+
},
|
|
143
|
+
}, ({ nodeId: id }) => {
|
|
144
|
+
const element = findElement(id);
|
|
145
|
+
if (!element) {
|
|
146
|
+
return {
|
|
147
|
+
success: false,
|
|
148
|
+
message: `DOM node '${id}' was not found.`,
|
|
149
|
+
errorCode: "dom_node_not_found",
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const limits = { maxDepth: 0, maxNodes: 1, count: 0 };
|
|
153
|
+
return successful(captureNode(element, options, 0, limits), "DOM node captured.");
|
|
154
|
+
}),
|
|
155
|
+
registerTool({
|
|
156
|
+
id: "dom.query_selector",
|
|
157
|
+
name: "Query DOM",
|
|
158
|
+
description: "Finds DOM nodes using a CSS selector.",
|
|
159
|
+
category: "UI",
|
|
160
|
+
scope: "read",
|
|
161
|
+
argumentsSchema: {
|
|
162
|
+
type: "object",
|
|
163
|
+
required: ["selector"],
|
|
164
|
+
properties: { selector: { type: "string" } },
|
|
165
|
+
},
|
|
166
|
+
}, ({ selector }) => {
|
|
167
|
+
try {
|
|
168
|
+
const matches = Array.from(document.querySelectorAll(selector)).slice(0, 200);
|
|
169
|
+
return successful(matches.map((element) => ({
|
|
170
|
+
id: nodeId(element),
|
|
171
|
+
type: element.tagName.toLowerCase(),
|
|
172
|
+
label: accessibleLabel(element, true),
|
|
173
|
+
})), `Matched ${matches.length} DOM node(s).`);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
return {
|
|
177
|
+
success: false,
|
|
178
|
+
message: error instanceof Error ? error.message : "Invalid CSS selector.",
|
|
179
|
+
errorCode: "dom_selector_invalid",
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}),
|
|
183
|
+
];
|
|
184
|
+
if (options.allowActions) {
|
|
185
|
+
registrations.push(registerTool({
|
|
186
|
+
id: "dom.invoke_action",
|
|
187
|
+
name: "Invoke DOM action",
|
|
188
|
+
description: "Clicks, focuses, blurs, or changes a DOM node.",
|
|
189
|
+
category: "UI",
|
|
190
|
+
scope: "write",
|
|
191
|
+
argumentsSchema: {
|
|
192
|
+
type: "object",
|
|
193
|
+
required: ["nodeId", "action"],
|
|
194
|
+
properties: {
|
|
195
|
+
nodeId: { type: "string" },
|
|
196
|
+
action: { enum: ["click", "focus", "blur", "setValue"] },
|
|
197
|
+
value: { type: "string" },
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
security: {
|
|
201
|
+
level: "high",
|
|
202
|
+
summary: "Can interact with controls inside the app WebView.",
|
|
203
|
+
},
|
|
204
|
+
}, ({ nodeId: id, action, value }) => {
|
|
205
|
+
const element = findElement(id);
|
|
206
|
+
if (!element) {
|
|
207
|
+
return {
|
|
208
|
+
success: false,
|
|
209
|
+
message: `DOM node '${id}' was not found.`,
|
|
210
|
+
errorCode: "dom_node_not_found",
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (action === "click")
|
|
214
|
+
element.click();
|
|
215
|
+
else if (action === "focus")
|
|
216
|
+
element.focus();
|
|
217
|
+
else if (action === "blur")
|
|
218
|
+
element.blur();
|
|
219
|
+
else if (action === "setValue" &&
|
|
220
|
+
(element instanceof HTMLInputElement ||
|
|
221
|
+
element instanceof HTMLTextAreaElement ||
|
|
222
|
+
element instanceof HTMLSelectElement)) {
|
|
223
|
+
element.value = value ?? "";
|
|
224
|
+
element.dispatchEvent(new Event("input", { bubbles: true }));
|
|
225
|
+
element.dispatchEvent(new Event("change", { bubbles: true }));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
return {
|
|
229
|
+
success: false,
|
|
230
|
+
message: `Unsupported action '${action}'.`,
|
|
231
|
+
errorCode: "dom_action_unsupported",
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return successful({ nodeId: id, action }, `DOM action '${action}' invoked.`);
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
ids: registrations.map(({ id }) => id),
|
|
239
|
+
ready: Promise.all(registrations.map(({ ready }) => ready)),
|
|
240
|
+
unregister: () => Promise.all(registrations.map((registration) => registration.unregister())),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function cloneOptions(options) {
|
|
245
|
+
return JSON.parse(JSON.stringify(options));
|
|
246
|
+
}
|
|
247
|
+
class AnsightOptionsBuilder {
|
|
248
|
+
options;
|
|
249
|
+
constructor(options = {}) {
|
|
250
|
+
this.options = cloneOptions(options);
|
|
251
|
+
}
|
|
252
|
+
withAnsightDefaults() {
|
|
253
|
+
this.options = {
|
|
254
|
+
...this.options,
|
|
255
|
+
useNativeAllInOneDefaults: true,
|
|
256
|
+
sampleFrequencyMilliseconds: 400,
|
|
257
|
+
retentionPeriodSeconds: 120,
|
|
258
|
+
enableFramesPerSecond: true,
|
|
259
|
+
enableBatteryLevel: false,
|
|
260
|
+
sessionJpegCapture: {
|
|
261
|
+
intervalMilliseconds: 2000,
|
|
262
|
+
quality: 60,
|
|
263
|
+
maxWidth: 480,
|
|
264
|
+
},
|
|
265
|
+
touchCapture: {},
|
|
266
|
+
toolGuard: "readOnly",
|
|
267
|
+
hostAutoProbe: {
|
|
268
|
+
...this.options.hostAutoProbe,
|
|
269
|
+
enabled: true,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
return this;
|
|
273
|
+
}
|
|
274
|
+
withNativeAllInOneDefaults() {
|
|
275
|
+
return this.withAnsightDefaults();
|
|
276
|
+
}
|
|
277
|
+
withAnsightSdk(configure) {
|
|
278
|
+
this.withAnsightDefaults().withAllToolAccess();
|
|
279
|
+
configure?.(this);
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
withSampleFrequencyMilliseconds(value) {
|
|
283
|
+
this.options.sampleFrequencyMilliseconds = value;
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
withFramesPerSecond() {
|
|
287
|
+
this.options.enableFramesPerSecond = true;
|
|
288
|
+
return this;
|
|
289
|
+
}
|
|
290
|
+
withoutFramesPerSecond() {
|
|
291
|
+
this.options.enableFramesPerSecond = false;
|
|
292
|
+
return this;
|
|
293
|
+
}
|
|
294
|
+
withBatteryLevel() {
|
|
295
|
+
this.options.enableBatteryLevel = true;
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
298
|
+
withoutBatteryLevel() {
|
|
299
|
+
this.options.enableBatteryLevel = false;
|
|
300
|
+
return this;
|
|
301
|
+
}
|
|
302
|
+
withRetentionPeriodSeconds(value) {
|
|
303
|
+
this.options.retentionPeriodSeconds = value;
|
|
304
|
+
return this;
|
|
305
|
+
}
|
|
306
|
+
withAdditionalChannels(channels) {
|
|
307
|
+
this.options.additionalChannels = channels.map((channel) => ({
|
|
308
|
+
...channel,
|
|
309
|
+
}));
|
|
310
|
+
return this;
|
|
311
|
+
}
|
|
312
|
+
addAdditionalChannel(channel) {
|
|
313
|
+
this.options.additionalChannels = [
|
|
314
|
+
...(this.options.additionalChannels ?? []),
|
|
315
|
+
{ ...channel },
|
|
316
|
+
];
|
|
317
|
+
return this;
|
|
318
|
+
}
|
|
319
|
+
withDefaultMemoryChannels(channels) {
|
|
320
|
+
this.options.defaultMemoryChannels = { ...channels };
|
|
321
|
+
return this;
|
|
322
|
+
}
|
|
323
|
+
withoutDefaultMemoryChannels(channels) {
|
|
324
|
+
const current = {
|
|
325
|
+
managedHeap: true,
|
|
326
|
+
javaHeap: true,
|
|
327
|
+
nativeHeap: true,
|
|
328
|
+
residentSetSize: true,
|
|
329
|
+
rss: true,
|
|
330
|
+
physicalFootprint: true,
|
|
331
|
+
...this.options.defaultMemoryChannels,
|
|
332
|
+
};
|
|
333
|
+
for (const [key, disabled] of Object.entries(channels)) {
|
|
334
|
+
if (disabled)
|
|
335
|
+
current[key] = false;
|
|
336
|
+
}
|
|
337
|
+
this.options.defaultMemoryChannels = current;
|
|
338
|
+
return this;
|
|
339
|
+
}
|
|
340
|
+
withSessionJpegCapture(optionsOrIntervalMilliseconds = {}, quality = 60, maxWidth = 480, captureGpuBackedSurfaces = true) {
|
|
341
|
+
this.options.sessionJpegCapture =
|
|
342
|
+
typeof optionsOrIntervalMilliseconds === "number"
|
|
343
|
+
? {
|
|
344
|
+
intervalMilliseconds: optionsOrIntervalMilliseconds,
|
|
345
|
+
quality,
|
|
346
|
+
maxWidth,
|
|
347
|
+
captureGpuBackedSurfaces,
|
|
348
|
+
}
|
|
349
|
+
: {
|
|
350
|
+
intervalMilliseconds: 2000,
|
|
351
|
+
quality: 60,
|
|
352
|
+
maxWidth: 480,
|
|
353
|
+
...optionsOrIntervalMilliseconds,
|
|
354
|
+
};
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
withoutSessionJpegCapture() {
|
|
358
|
+
this.options.sessionJpegCapture = false;
|
|
359
|
+
return this;
|
|
360
|
+
}
|
|
361
|
+
withTouchCapture(options = {}) {
|
|
362
|
+
this.options.touchCapture = { ...options };
|
|
363
|
+
return this;
|
|
364
|
+
}
|
|
365
|
+
withoutTouchCapture() {
|
|
366
|
+
this.options.touchCapture = false;
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
withLifecycleCapture(options = {}) {
|
|
370
|
+
this.options.lifecycleCapture = {
|
|
371
|
+
...options,
|
|
372
|
+
enabled: options.enabled ?? true,
|
|
373
|
+
};
|
|
374
|
+
return this;
|
|
375
|
+
}
|
|
376
|
+
withToolGuard(toolGuard) {
|
|
377
|
+
this.options.toolGuard = toolGuard;
|
|
378
|
+
return this;
|
|
379
|
+
}
|
|
380
|
+
withToolsDisabled() {
|
|
381
|
+
return this.withToolGuard("disabled");
|
|
382
|
+
}
|
|
383
|
+
withReadOnlyToolAccess() {
|
|
384
|
+
return this.withToolGuard("readOnly");
|
|
385
|
+
}
|
|
386
|
+
withReadWriteToolAccess() {
|
|
387
|
+
return this.withToolGuard("readWrite");
|
|
388
|
+
}
|
|
389
|
+
withAllToolAccess() {
|
|
390
|
+
return this.withToolGuard("fullAccess");
|
|
391
|
+
}
|
|
392
|
+
withHostAutoProbe(options = {}) {
|
|
393
|
+
this.options.hostAutoProbe = {
|
|
394
|
+
...options,
|
|
395
|
+
enabled: options.enabled ?? true,
|
|
396
|
+
};
|
|
397
|
+
return this;
|
|
398
|
+
}
|
|
399
|
+
withoutHostAutoProbe() {
|
|
400
|
+
this.options.hostAutoProbe = {
|
|
401
|
+
...this.options.hostAutoProbe,
|
|
402
|
+
enabled: false,
|
|
403
|
+
};
|
|
404
|
+
return this;
|
|
405
|
+
}
|
|
406
|
+
withHostConnection(options = {}) {
|
|
407
|
+
this.options.hostConnection = { ...options };
|
|
408
|
+
return this;
|
|
409
|
+
}
|
|
410
|
+
configureHostConnection(configure) {
|
|
411
|
+
const current = { ...this.options.hostConnection };
|
|
412
|
+
this.options.hostConnection = configure(current) ?? current;
|
|
413
|
+
return this;
|
|
414
|
+
}
|
|
415
|
+
withBundledHostConnection(options = {}) {
|
|
416
|
+
return this.configureHostConnection((current) => ({
|
|
417
|
+
...current,
|
|
418
|
+
bundledDeveloperConfigJson: options.bundledDeveloperConfigJson,
|
|
419
|
+
bundledConfigJson: options.bundledConfigJson,
|
|
420
|
+
}));
|
|
421
|
+
}
|
|
422
|
+
withHostConnectionDiscoveryPort(discoveryPort) {
|
|
423
|
+
return this.configureHostConnection((current) => ({
|
|
424
|
+
...current,
|
|
425
|
+
discoveryPort,
|
|
426
|
+
}));
|
|
427
|
+
}
|
|
428
|
+
withHostConnectionProfileRetentionSeconds(connectionProfileRetentionSeconds) {
|
|
429
|
+
return this.configureHostConnection((current) => ({
|
|
430
|
+
...current,
|
|
431
|
+
connectionProfileRetentionSeconds,
|
|
432
|
+
}));
|
|
433
|
+
}
|
|
434
|
+
withSecureStorage(options = {}) {
|
|
435
|
+
this.options.secureStorage = {
|
|
436
|
+
...options,
|
|
437
|
+
allowedKeys: options.allowedKeys ? [...options.allowedKeys] : undefined,
|
|
438
|
+
allowedPrefixes: options.allowedPrefixes
|
|
439
|
+
? [...options.allowedPrefixes]
|
|
440
|
+
: undefined,
|
|
441
|
+
};
|
|
442
|
+
return this;
|
|
443
|
+
}
|
|
444
|
+
withRemoteTools(options = {}) {
|
|
445
|
+
this.options.remoteTools = cloneOptions({
|
|
446
|
+
remoteTools: options,
|
|
447
|
+
}).remoteTools;
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
450
|
+
withVisualTreeTools(options = {}) {
|
|
451
|
+
this.options.remoteTools = {
|
|
452
|
+
...this.options.remoteTools,
|
|
453
|
+
visualTree: typeof options === "boolean"
|
|
454
|
+
? options
|
|
455
|
+
: { ...options, enabled: options.enabled ?? true },
|
|
456
|
+
};
|
|
457
|
+
return this;
|
|
458
|
+
}
|
|
459
|
+
withoutVisualTreeTools() {
|
|
460
|
+
this.options.remoteTools = {
|
|
461
|
+
...this.options.remoteTools,
|
|
462
|
+
visualTree: false,
|
|
463
|
+
};
|
|
464
|
+
return this;
|
|
465
|
+
}
|
|
466
|
+
withFileSystemTools(options = {}) {
|
|
467
|
+
this.options.remoteTools = {
|
|
468
|
+
...this.options.remoteTools,
|
|
469
|
+
fileSystem: cloneOptions({ remoteTools: { fileSystem: options } })
|
|
470
|
+
.remoteTools?.fileSystem,
|
|
471
|
+
};
|
|
472
|
+
return this;
|
|
473
|
+
}
|
|
474
|
+
withDatabaseTools(options = {}) {
|
|
475
|
+
this.options.remoteTools = {
|
|
476
|
+
...this.options.remoteTools,
|
|
477
|
+
database: cloneOptions({ remoteTools: { database: options } }).remoteTools
|
|
478
|
+
?.database,
|
|
479
|
+
};
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
withPreferencesTools(options = {}) {
|
|
483
|
+
this.options.remoteTools = {
|
|
484
|
+
...this.options.remoteTools,
|
|
485
|
+
preferences: cloneOptions({ remoteTools: { preferences: options } })
|
|
486
|
+
.remoteTools?.preferences,
|
|
487
|
+
};
|
|
488
|
+
return this;
|
|
489
|
+
}
|
|
490
|
+
withReflectionTools(options = {}) {
|
|
491
|
+
this.options.remoteTools = {
|
|
492
|
+
...this.options.remoteTools,
|
|
493
|
+
reflection: cloneOptions({ remoteTools: { reflection: options } })
|
|
494
|
+
.remoteTools?.reflection,
|
|
495
|
+
};
|
|
496
|
+
return this;
|
|
497
|
+
}
|
|
498
|
+
withDomTools(options = {}) {
|
|
499
|
+
this.options.domTools = { ...options };
|
|
500
|
+
return this;
|
|
501
|
+
}
|
|
502
|
+
withErrorCapture(options = {}) {
|
|
503
|
+
this.options.errorCapture = { ...options };
|
|
504
|
+
return this;
|
|
505
|
+
}
|
|
506
|
+
registerCustomProperty(group, key, value) {
|
|
507
|
+
this.options.customProperties = {
|
|
508
|
+
...this.options.customProperties,
|
|
509
|
+
[group]: {
|
|
510
|
+
...this.options.customProperties?.[group],
|
|
511
|
+
[key]: String(value),
|
|
512
|
+
},
|
|
513
|
+
};
|
|
514
|
+
return this;
|
|
515
|
+
}
|
|
516
|
+
removeCustomProperty(group, key) {
|
|
517
|
+
const groups = cloneOptions({ customProperties: this.options.customProperties })
|
|
518
|
+
.customProperties ?? {};
|
|
519
|
+
delete groups[group]?.[key];
|
|
520
|
+
if (groups[group] && Object.keys(groups[group]).length === 0) {
|
|
521
|
+
delete groups[group];
|
|
522
|
+
}
|
|
523
|
+
this.options.customProperties = groups;
|
|
524
|
+
return this;
|
|
525
|
+
}
|
|
526
|
+
clearCustomProperties() {
|
|
527
|
+
this.options.customProperties = {};
|
|
528
|
+
return this;
|
|
529
|
+
}
|
|
530
|
+
build() {
|
|
531
|
+
return cloneOptions(this.options);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function createOptionsBuilder(options = {}) {
|
|
535
|
+
return new AnsightOptionsBuilder(options);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const AnsightNative = core.registerPlugin("Ansight");
|
|
539
|
+
const toolHandlers = new Map();
|
|
540
|
+
const artifactProviders = new Map();
|
|
541
|
+
const hostConnectionListeners = new Set();
|
|
542
|
+
const logListeners = new Set();
|
|
543
|
+
let toolListener;
|
|
544
|
+
let logListener;
|
|
545
|
+
let lifecycleCleanup;
|
|
546
|
+
let artifactToolRegistrations = [];
|
|
547
|
+
let domToolRegistration;
|
|
548
|
+
function normalizePairingPayload(payload) {
|
|
549
|
+
if (payload == null)
|
|
550
|
+
return payload;
|
|
551
|
+
return typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
552
|
+
}
|
|
553
|
+
function normalizeOptions(input) {
|
|
554
|
+
const options = JSON.parse(JSON.stringify(input));
|
|
555
|
+
if (options.pairingConfig != null) {
|
|
556
|
+
options.pairingConfigJson =
|
|
557
|
+
normalizePairingPayload(options.pairingConfig) ?? undefined;
|
|
558
|
+
delete options.pairingConfig;
|
|
559
|
+
}
|
|
560
|
+
if (options.bundledPairingConfig != null) {
|
|
561
|
+
options.pairingConfigJson =
|
|
562
|
+
normalizePairingPayload(options.bundledPairingConfig) ?? undefined;
|
|
563
|
+
delete options.bundledPairingConfig;
|
|
564
|
+
}
|
|
565
|
+
delete options.domTools;
|
|
566
|
+
delete options.errorCapture;
|
|
567
|
+
delete options.lifecycle;
|
|
568
|
+
return options;
|
|
569
|
+
}
|
|
570
|
+
function normalizeToolResult(value) {
|
|
571
|
+
if (value && typeof value === "object" && "success" in value) {
|
|
572
|
+
return value;
|
|
573
|
+
}
|
|
574
|
+
return { success: true, result: value };
|
|
575
|
+
}
|
|
576
|
+
function errorToolResult(error) {
|
|
577
|
+
return {
|
|
578
|
+
success: false,
|
|
579
|
+
message: error instanceof Error ? error.message : String(error),
|
|
580
|
+
errorCode: "javascript_tool_failed",
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
async function ensureToolListener() {
|
|
584
|
+
toolListener ??= AnsightNative.addListener("ansightToolCall", (call) => {
|
|
585
|
+
const handler = toolHandlers.get(call.toolId);
|
|
586
|
+
void Promise.resolve(handler
|
|
587
|
+
? handler(call.arguments ?? {}, call)
|
|
588
|
+
: {
|
|
589
|
+
success: false,
|
|
590
|
+
message: `No JavaScript handler is registered for '${call.toolId}'.`,
|
|
591
|
+
errorCode: "javascript_tool_not_registered",
|
|
592
|
+
})
|
|
593
|
+
.then(normalizeToolResult)
|
|
594
|
+
.catch(errorToolResult)
|
|
595
|
+
.then((result) => AnsightNative.resolveToolCall({ requestId: call.requestId, result }))
|
|
596
|
+
.catch(() => undefined);
|
|
597
|
+
});
|
|
598
|
+
return toolListener;
|
|
599
|
+
}
|
|
600
|
+
async function ensureLogListener() {
|
|
601
|
+
logListener ??= AnsightNative.addListener("ansightLog", (entry) => {
|
|
602
|
+
for (const listener of logListeners)
|
|
603
|
+
listener(entry);
|
|
604
|
+
});
|
|
605
|
+
return logListener;
|
|
606
|
+
}
|
|
607
|
+
async function emitHostConnectionStatus() {
|
|
608
|
+
if (hostConnectionListeners.size === 0)
|
|
609
|
+
return;
|
|
610
|
+
const [status, capabilities] = await Promise.all([
|
|
611
|
+
AnsightNative.hostConnectionStatus(),
|
|
612
|
+
AnsightNative.hostConnectionCapabilities(),
|
|
613
|
+
]);
|
|
614
|
+
for (const listener of hostConnectionListeners)
|
|
615
|
+
listener(status, capabilities);
|
|
616
|
+
}
|
|
617
|
+
async function afterConnectionChange(operation) {
|
|
618
|
+
const result = await operation();
|
|
619
|
+
await emitHostConnectionStatus();
|
|
620
|
+
return result;
|
|
621
|
+
}
|
|
622
|
+
async function initialize(options = {}) {
|
|
623
|
+
const result = await AnsightNative.initialize(normalizeOptions(options));
|
|
624
|
+
if (options.lifecycle !== false)
|
|
625
|
+
startLifecycleTracking();
|
|
626
|
+
if (options.errorCapture) {
|
|
627
|
+
installErrorHandlers(typeof options.errorCapture === "object" ? options.errorCapture : {});
|
|
628
|
+
}
|
|
629
|
+
if (options.domTools) {
|
|
630
|
+
installDomTools(typeof options.domTools === "object" ? options.domTools : {});
|
|
631
|
+
}
|
|
632
|
+
await emitHostConnectionStatus();
|
|
633
|
+
return result;
|
|
634
|
+
}
|
|
635
|
+
async function initializeAndActivate(options = {}) {
|
|
636
|
+
const result = await AnsightNative.initializeAndActivate(normalizeOptions(options));
|
|
637
|
+
if (options.lifecycle !== false)
|
|
638
|
+
startLifecycleTracking();
|
|
639
|
+
if (options.errorCapture) {
|
|
640
|
+
installErrorHandlers(typeof options.errorCapture === "object" ? options.errorCapture : {});
|
|
641
|
+
}
|
|
642
|
+
if (options.domTools) {
|
|
643
|
+
installDomTools(typeof options.domTools === "object" ? options.domTools : {});
|
|
644
|
+
}
|
|
645
|
+
await emitHostConnectionStatus();
|
|
646
|
+
return result;
|
|
647
|
+
}
|
|
648
|
+
const activate = () => afterConnectionChange(() => AnsightNative.activate());
|
|
649
|
+
async function deactivate() {
|
|
650
|
+
stopLifecycleTracking();
|
|
651
|
+
return afterConnectionChange(() => AnsightNative.deactivate());
|
|
652
|
+
}
|
|
653
|
+
const clear = () => afterConnectionChange(() => AnsightNative.clear());
|
|
654
|
+
const registerMetricChannel = (channel) => AnsightNative.registerMetricChannel({ channel });
|
|
655
|
+
const metric = (value, channel = 255) => AnsightNative.recordMetric({ value, channel });
|
|
656
|
+
const recordMetric = metric;
|
|
657
|
+
function event(input) {
|
|
658
|
+
return AnsightNative.recordEvent(typeof input === "string" ? { label: input } : input);
|
|
659
|
+
}
|
|
660
|
+
const recordEvent = event;
|
|
661
|
+
const screenViewed = (name, details = {}) => AnsightNative.screenViewed({ name, details });
|
|
662
|
+
const trackRoute = screenViewed;
|
|
663
|
+
const setAppLifecycleState = (state) => AnsightNative.setAppLifecycleState({ state });
|
|
664
|
+
function connect(pairingPayload, options = {}) {
|
|
665
|
+
return afterConnectionChange(() => AnsightNative.connect({
|
|
666
|
+
...options,
|
|
667
|
+
pairingPayload: normalizePairingPayload(pairingPayload),
|
|
668
|
+
}));
|
|
669
|
+
}
|
|
670
|
+
function scanPairingQrCode(options = {}) {
|
|
671
|
+
return afterConnectionChange(() => AnsightNative.scanPairingQrCode(options));
|
|
672
|
+
}
|
|
673
|
+
function openSession(pairingPayload, options = {}) {
|
|
674
|
+
return afterConnectionChange(() => AnsightNative.openSession({
|
|
675
|
+
...options,
|
|
676
|
+
pairingPayload: normalizePairingPayload(pairingPayload) ?? "",
|
|
677
|
+
}));
|
|
678
|
+
}
|
|
679
|
+
const disconnect = () => afterConnectionChange(() => AnsightNative.disconnect());
|
|
680
|
+
const completeSession = () => afterConnectionChange(() => AnsightNative.completeSession());
|
|
681
|
+
const closeSession = () => afterConnectionChange(() => AnsightNative.closeSession());
|
|
682
|
+
const savePairingConfig = (pairingPayload, options = {}) => afterConnectionChange(() => AnsightNative.savePairingConfig({
|
|
683
|
+
...options,
|
|
684
|
+
pairingPayload: normalizePairingPayload(pairingPayload) ?? "",
|
|
685
|
+
}));
|
|
686
|
+
const clearSavedPairing = () => afterConnectionChange(() => AnsightNative.clearSavedPairing());
|
|
687
|
+
const clearSavedPairingConfig = clearSavedPairing;
|
|
688
|
+
const clearCachedSession = () => afterConnectionChange(() => AnsightNative.clearCachedSession());
|
|
689
|
+
const notifyHostConnectionConfigChanged = () => afterConnectionChange(() => AnsightNative.notifyHostConnectionConfigChanged());
|
|
690
|
+
const status = () => AnsightNative.status();
|
|
691
|
+
const snapshot = () => AnsightNative.snapshot();
|
|
692
|
+
const hostConnectionStatus = () => AnsightNative.hostConnectionStatus();
|
|
693
|
+
const hostConnectionCapabilities = () => AnsightNative.hostConnectionCapabilities();
|
|
694
|
+
const currentOptions = () => AnsightNative.currentOptions();
|
|
695
|
+
async function recordedMetrics(limit = 0) {
|
|
696
|
+
return (await AnsightNative.recordedMetrics({ limit })).items;
|
|
697
|
+
}
|
|
698
|
+
async function recordedEvents(limit = 0) {
|
|
699
|
+
return (await AnsightNative.recordedEvents({ limit })).items;
|
|
700
|
+
}
|
|
701
|
+
const sendClientLog = (line) => AnsightNative.sendClientLog({ line });
|
|
702
|
+
const captureBuiltInTelemetrySample = () => AnsightNative.captureBuiltInTelemetrySample();
|
|
703
|
+
async function isFramesPerSecondEnabled() {
|
|
704
|
+
return (await AnsightNative.isFramesPerSecondEnabled()).value;
|
|
705
|
+
}
|
|
706
|
+
const enableFramesPerSecond = () => AnsightNative.enableFramesPerSecond();
|
|
707
|
+
const disableFramesPerSecond = () => AnsightNative.disableFramesPerSecond();
|
|
708
|
+
const captureScreenFrame = (options = {}) => AnsightNative.captureScreenFrame(options);
|
|
709
|
+
const enableTouchCapture = () => AnsightNative.enableTouchCapture();
|
|
710
|
+
const disableTouchCapture = () => AnsightNative.disableTouchCapture();
|
|
711
|
+
const updateSessionProperties = (properties) => AnsightNative.updateSessionProperties({ properties });
|
|
712
|
+
const updateCustomProperties = updateSessionProperties;
|
|
713
|
+
const clearSessionProperties = () => AnsightNative.clearSessionProperties();
|
|
714
|
+
const clearCustomProperties = clearSessionProperties;
|
|
715
|
+
const registerCustomProperty = (group, key, value) => AnsightNative.registerCustomProperty({ group, key, value });
|
|
716
|
+
const removeCustomProperty = (group, key) => AnsightNative.removeCustomProperty({ group, key });
|
|
717
|
+
function addHostConnectionStatusListener(listener, options = {}) {
|
|
718
|
+
hostConnectionListeners.add(listener);
|
|
719
|
+
if (options.emitCurrent !== false)
|
|
720
|
+
void emitHostConnectionStatus();
|
|
721
|
+
return {
|
|
722
|
+
remove: () => {
|
|
723
|
+
hostConnectionListeners.delete(listener);
|
|
724
|
+
},
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
function addLogListener(listener) {
|
|
728
|
+
logListeners.add(listener);
|
|
729
|
+
void ensureLogListener();
|
|
730
|
+
return {
|
|
731
|
+
remove: () => {
|
|
732
|
+
logListeners.delete(listener);
|
|
733
|
+
},
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
function registerTool(definition, handler) {
|
|
737
|
+
if (!definition?.id?.trim())
|
|
738
|
+
throw new TypeError("registerTool requires a stable string id.");
|
|
739
|
+
if (typeof handler !== "function")
|
|
740
|
+
throw new TypeError("registerTool requires a handler function.");
|
|
741
|
+
toolHandlers.set(definition.id, handler);
|
|
742
|
+
const ready = ensureToolListener()
|
|
743
|
+
.then(() => AnsightNative.registerCustomTool({ definition }))
|
|
744
|
+
.catch((error) => {
|
|
745
|
+
toolHandlers.delete(definition.id);
|
|
746
|
+
throw error;
|
|
747
|
+
});
|
|
748
|
+
return {
|
|
749
|
+
id: definition.id,
|
|
750
|
+
ready,
|
|
751
|
+
unregister: async () => {
|
|
752
|
+
toolHandlers.delete(definition.id);
|
|
753
|
+
return AnsightNative.unregisterCustomTool({ id: definition.id });
|
|
754
|
+
},
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
function unregisterTool(id) {
|
|
758
|
+
toolHandlers.delete(id);
|
|
759
|
+
return AnsightNative.unregisterCustomTool({ id });
|
|
760
|
+
}
|
|
761
|
+
const listRegisteredTools = () => [...toolHandlers.keys()];
|
|
762
|
+
async function clearRegisteredTools() {
|
|
763
|
+
toolHandlers.clear();
|
|
764
|
+
artifactProviders.clear();
|
|
765
|
+
artifactToolRegistrations = [];
|
|
766
|
+
domToolRegistration = undefined;
|
|
767
|
+
return AnsightNative.clearRegisteredCustomTools();
|
|
768
|
+
}
|
|
769
|
+
function bytesToBase64(bytes) {
|
|
770
|
+
let binary = "";
|
|
771
|
+
for (let offset = 0; offset < bytes.length; offset += 0x8000) {
|
|
772
|
+
binary += String.fromCharCode(...bytes.subarray(offset, offset + 0x8000));
|
|
773
|
+
}
|
|
774
|
+
return btoa(binary);
|
|
775
|
+
}
|
|
776
|
+
function payloadBytes(payload) {
|
|
777
|
+
if (payload instanceof Uint8Array)
|
|
778
|
+
return payload;
|
|
779
|
+
if (payload instanceof ArrayBuffer)
|
|
780
|
+
return new Uint8Array(payload);
|
|
781
|
+
if (Array.isArray(payload))
|
|
782
|
+
return Uint8Array.from(payload);
|
|
783
|
+
if (typeof payload === "object" && payload) {
|
|
784
|
+
const candidate = payload.bytes ?? payload.data;
|
|
785
|
+
if (candidate instanceof Uint8Array)
|
|
786
|
+
return candidate;
|
|
787
|
+
if (candidate instanceof ArrayBuffer)
|
|
788
|
+
return new Uint8Array(candidate);
|
|
789
|
+
if (Array.isArray(candidate))
|
|
790
|
+
return Uint8Array.from(candidate);
|
|
791
|
+
}
|
|
792
|
+
return undefined;
|
|
793
|
+
}
|
|
794
|
+
function installArtifactTools() {
|
|
795
|
+
if (artifactToolRegistrations.length > 0)
|
|
796
|
+
return artifactToolRegistrations;
|
|
797
|
+
artifactToolRegistrations = [
|
|
798
|
+
registerTool({
|
|
799
|
+
id: "artifacts.query",
|
|
800
|
+
name: "Query JavaScript artifacts",
|
|
801
|
+
description: "Lists artifacts exposed by Capacitor JavaScript providers.",
|
|
802
|
+
category: "Artifacts",
|
|
803
|
+
scope: "read",
|
|
804
|
+
}, async (_args, context) => {
|
|
805
|
+
const definitions = [];
|
|
806
|
+
for (const provider of artifactProviders.values()) {
|
|
807
|
+
const query = provider.queryArtifacts ?? provider.query;
|
|
808
|
+
const artifacts = query
|
|
809
|
+
? await query({
|
|
810
|
+
toolRequestId: context.nativeRequestId ?? context.requestId,
|
|
811
|
+
sessionId: context.sessionId,
|
|
812
|
+
queriedAtUtc: new Date().toISOString(),
|
|
813
|
+
})
|
|
814
|
+
: [];
|
|
815
|
+
definitions.push(...artifacts.map((artifact) => ({
|
|
816
|
+
...artifact,
|
|
817
|
+
providerId: provider.descriptor.id,
|
|
818
|
+
})));
|
|
819
|
+
}
|
|
820
|
+
return {
|
|
821
|
+
success: true,
|
|
822
|
+
message: `Found ${definitions.length} artifact(s).`,
|
|
823
|
+
result: {
|
|
824
|
+
providers: [...artifactProviders.values()].map(({ descriptor }) => descriptor),
|
|
825
|
+
artifacts: definitions,
|
|
826
|
+
},
|
|
827
|
+
};
|
|
828
|
+
}),
|
|
829
|
+
registerTool({
|
|
830
|
+
id: "artifacts.request",
|
|
831
|
+
name: "Request JavaScript artifact",
|
|
832
|
+
description: "Creates an artifact through a Capacitor JavaScript provider.",
|
|
833
|
+
category: "Artifacts",
|
|
834
|
+
scope: "read",
|
|
835
|
+
argumentsSchema: {
|
|
836
|
+
type: "object",
|
|
837
|
+
required: ["providerId", "artifactId"],
|
|
838
|
+
properties: {
|
|
839
|
+
providerId: { type: "string" },
|
|
840
|
+
artifactId: { type: "string" },
|
|
841
|
+
},
|
|
842
|
+
},
|
|
843
|
+
}, async (args, context) => {
|
|
844
|
+
const provider = artifactProviders.get(args.providerId);
|
|
845
|
+
const create = provider && (provider.createArtifact ?? provider.create);
|
|
846
|
+
if (!provider || !create) {
|
|
847
|
+
return {
|
|
848
|
+
success: false,
|
|
849
|
+
message: `Artifact provider '${args.providerId}' is unavailable.`,
|
|
850
|
+
errorCode: "artifact_provider_not_found",
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
const result = await create({
|
|
854
|
+
providerId: args.providerId,
|
|
855
|
+
artifactId: args.artifactId,
|
|
856
|
+
arguments: args,
|
|
857
|
+
context: {
|
|
858
|
+
toolRequestId: context.nativeRequestId ?? context.requestId,
|
|
859
|
+
sessionId: context.sessionId,
|
|
860
|
+
requestedAtUtc: new Date().toISOString(),
|
|
861
|
+
},
|
|
862
|
+
});
|
|
863
|
+
const bytes = payloadBytes(result.payload);
|
|
864
|
+
if (bytes) {
|
|
865
|
+
const transfer = await AnsightNative.queueBinaryTransfer({
|
|
866
|
+
requestId: context.nativeRequestId ?? context.requestId,
|
|
867
|
+
base64Data: bytesToBase64(bytes),
|
|
868
|
+
chunkBytes: 64 * 1024,
|
|
869
|
+
});
|
|
870
|
+
return {
|
|
871
|
+
success: transfer.success,
|
|
872
|
+
message: transfer.message,
|
|
873
|
+
result: { metadata: result.metadata, transfer },
|
|
874
|
+
...(!transfer.success && {
|
|
875
|
+
errorCode: "artifact_transfer_unavailable",
|
|
876
|
+
}),
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
const payload = typeof result.payload === "object" &&
|
|
880
|
+
result.payload &&
|
|
881
|
+
"text" in result.payload
|
|
882
|
+
? result.payload.text
|
|
883
|
+
: result.payload;
|
|
884
|
+
return {
|
|
885
|
+
success: true,
|
|
886
|
+
message: `Artifact '${args.artifactId}' created.`,
|
|
887
|
+
result: { metadata: result.metadata, payload },
|
|
888
|
+
};
|
|
889
|
+
}),
|
|
890
|
+
];
|
|
891
|
+
return artifactToolRegistrations;
|
|
892
|
+
}
|
|
893
|
+
function registerArtifactProvider(provider) {
|
|
894
|
+
const id = provider?.descriptor?.id?.trim();
|
|
895
|
+
if (!id)
|
|
896
|
+
throw new TypeError("registerArtifactProvider requires descriptor.id.");
|
|
897
|
+
artifactProviders.set(id, provider);
|
|
898
|
+
const registrations = installArtifactTools();
|
|
899
|
+
return {
|
|
900
|
+
id,
|
|
901
|
+
ready: Promise.all(registrations.map(({ ready }) => ready)).then(() => ({
|
|
902
|
+
success: true,
|
|
903
|
+
message: `Artifact provider '${id}' registered.`,
|
|
904
|
+
})),
|
|
905
|
+
unregister: () => unregisterArtifactProvider(id),
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
const registerArtifactProviders = (providers) => providers.map(registerArtifactProvider);
|
|
909
|
+
async function unregisterArtifactProvider(id) {
|
|
910
|
+
artifactProviders.delete(id);
|
|
911
|
+
if (artifactProviders.size === 0) {
|
|
912
|
+
const registrations = artifactToolRegistrations;
|
|
913
|
+
artifactToolRegistrations = [];
|
|
914
|
+
await Promise.all(registrations.map(({ unregister }) => unregister()));
|
|
915
|
+
}
|
|
916
|
+
return { success: true, message: `Artifact provider '${id}' unregistered.` };
|
|
917
|
+
}
|
|
918
|
+
const listRegisteredArtifactProviders = () => [...artifactProviders.values()].map(({ descriptor }) => descriptor);
|
|
919
|
+
async function clearArtifactProviders() {
|
|
920
|
+
artifactProviders.clear();
|
|
921
|
+
const registrations = artifactToolRegistrations;
|
|
922
|
+
artifactToolRegistrations = [];
|
|
923
|
+
await Promise.all(registrations.map(({ unregister }) => unregister()));
|
|
924
|
+
return { success: true, message: "JavaScript artifact providers cleared." };
|
|
925
|
+
}
|
|
926
|
+
function installDomTools(options = {}) {
|
|
927
|
+
domToolRegistration ??= installDomTools$1(registerTool, options);
|
|
928
|
+
return domToolRegistration;
|
|
929
|
+
}
|
|
930
|
+
async function uninstallDomTools() {
|
|
931
|
+
const registration = domToolRegistration;
|
|
932
|
+
domToolRegistration = undefined;
|
|
933
|
+
return registration ? registration.unregister() : [];
|
|
934
|
+
}
|
|
935
|
+
function startLifecycleTracking() {
|
|
936
|
+
if (lifecycleCleanup || typeof document === "undefined")
|
|
937
|
+
return;
|
|
938
|
+
const update = () => void setAppLifecycleState(document.visibilityState === "visible" ? "foreground" : "background");
|
|
939
|
+
document.addEventListener("visibilitychange", update);
|
|
940
|
+
window.addEventListener("pageshow", update);
|
|
941
|
+
window.addEventListener("pagehide", update);
|
|
942
|
+
lifecycleCleanup = () => {
|
|
943
|
+
document.removeEventListener("visibilitychange", update);
|
|
944
|
+
window.removeEventListener("pageshow", update);
|
|
945
|
+
window.removeEventListener("pagehide", update);
|
|
946
|
+
};
|
|
947
|
+
update();
|
|
948
|
+
}
|
|
949
|
+
function stopLifecycleTracking() {
|
|
950
|
+
lifecycleCleanup?.();
|
|
951
|
+
lifecycleCleanup = undefined;
|
|
952
|
+
}
|
|
953
|
+
const startAppStateTracking = startLifecycleTracking;
|
|
954
|
+
const stopAppStateTracking = stopLifecycleTracking;
|
|
955
|
+
function installErrorHandlers(options = {}) {
|
|
956
|
+
const captureErrors = options.errors ?? true;
|
|
957
|
+
const captureRejections = options.unhandledRejections ?? true;
|
|
958
|
+
const captureConsole = options.consoleErrors ?? false;
|
|
959
|
+
const onError = (eventValue) => {
|
|
960
|
+
if (!captureErrors)
|
|
961
|
+
return;
|
|
962
|
+
void event({
|
|
963
|
+
label: eventValue.message || "Unhandled JavaScript error",
|
|
964
|
+
type: "Exception",
|
|
965
|
+
details: JSON.stringify({
|
|
966
|
+
filename: eventValue.filename,
|
|
967
|
+
line: eventValue.lineno,
|
|
968
|
+
column: eventValue.colno,
|
|
969
|
+
stack: eventValue.error instanceof Error
|
|
970
|
+
? eventValue.error.stack
|
|
971
|
+
: undefined,
|
|
972
|
+
}),
|
|
973
|
+
}).catch(() => undefined);
|
|
974
|
+
};
|
|
975
|
+
const onRejection = (eventValue) => {
|
|
976
|
+
if (!captureRejections)
|
|
977
|
+
return;
|
|
978
|
+
const reason = eventValue.reason;
|
|
979
|
+
void event({
|
|
980
|
+
label: reason instanceof Error
|
|
981
|
+
? reason.message
|
|
982
|
+
: "Unhandled JavaScript rejection",
|
|
983
|
+
type: "Exception",
|
|
984
|
+
details: JSON.stringify({
|
|
985
|
+
reason: reason instanceof Error ? reason.stack : String(reason),
|
|
986
|
+
}),
|
|
987
|
+
}).catch(() => undefined);
|
|
988
|
+
};
|
|
989
|
+
window.addEventListener("error", onError);
|
|
990
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
991
|
+
const originalConsoleError = console.error;
|
|
992
|
+
if (captureConsole) {
|
|
993
|
+
console.error = (...args) => {
|
|
994
|
+
originalConsoleError(...args);
|
|
995
|
+
void event({
|
|
996
|
+
label: "console.error",
|
|
997
|
+
type: "Exception",
|
|
998
|
+
details: args.map(String).join(" "),
|
|
999
|
+
}).catch(() => undefined);
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
return () => {
|
|
1003
|
+
window.removeEventListener("error", onError);
|
|
1004
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
1005
|
+
if (captureConsole)
|
|
1006
|
+
console.error = originalConsoleError;
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
function createRouteTracker(options = {}) {
|
|
1010
|
+
const resolveName = options.resolveName ?? ((url) => url.pathname + url.search + url.hash);
|
|
1011
|
+
const record = () => void screenViewed(resolveName(new URL(location.href)), options.details);
|
|
1012
|
+
const originalPushState = history.pushState.bind(history);
|
|
1013
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1014
|
+
const onPopState = () => record();
|
|
1015
|
+
window.addEventListener("popstate", onPopState);
|
|
1016
|
+
window.addEventListener("hashchange", onPopState);
|
|
1017
|
+
if (options.observeHistory !== false) {
|
|
1018
|
+
history.pushState = (...args) => {
|
|
1019
|
+
originalPushState(...args);
|
|
1020
|
+
record();
|
|
1021
|
+
};
|
|
1022
|
+
history.replaceState = (...args) => {
|
|
1023
|
+
originalReplaceState(...args);
|
|
1024
|
+
record();
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
record();
|
|
1028
|
+
return {
|
|
1029
|
+
remove: () => {
|
|
1030
|
+
window.removeEventListener("popstate", onPopState);
|
|
1031
|
+
window.removeEventListener("hashchange", onPopState);
|
|
1032
|
+
history.pushState = originalPushState;
|
|
1033
|
+
history.replaceState = originalReplaceState;
|
|
1034
|
+
},
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
const Ansight = {
|
|
1038
|
+
initialize,
|
|
1039
|
+
initializeAndActivate,
|
|
1040
|
+
activate,
|
|
1041
|
+
deactivate,
|
|
1042
|
+
clear,
|
|
1043
|
+
registerMetricChannel,
|
|
1044
|
+
metric,
|
|
1045
|
+
recordMetric,
|
|
1046
|
+
event,
|
|
1047
|
+
recordEvent,
|
|
1048
|
+
screenViewed,
|
|
1049
|
+
trackRoute,
|
|
1050
|
+
setAppLifecycleState,
|
|
1051
|
+
connect,
|
|
1052
|
+
scanPairingQrCode,
|
|
1053
|
+
openSession,
|
|
1054
|
+
disconnect,
|
|
1055
|
+
completeSession,
|
|
1056
|
+
closeSession,
|
|
1057
|
+
savePairingConfig,
|
|
1058
|
+
clearSavedPairing,
|
|
1059
|
+
clearSavedPairingConfig,
|
|
1060
|
+
clearCachedSession,
|
|
1061
|
+
notifyHostConnectionConfigChanged,
|
|
1062
|
+
status,
|
|
1063
|
+
snapshot,
|
|
1064
|
+
hostConnectionStatus,
|
|
1065
|
+
hostConnectionCapabilities,
|
|
1066
|
+
addHostConnectionStatusListener,
|
|
1067
|
+
currentOptions,
|
|
1068
|
+
recordedMetrics,
|
|
1069
|
+
recordedEvents,
|
|
1070
|
+
sendClientLog,
|
|
1071
|
+
addLogListener,
|
|
1072
|
+
captureBuiltInTelemetrySample,
|
|
1073
|
+
isFramesPerSecondEnabled,
|
|
1074
|
+
enableFramesPerSecond,
|
|
1075
|
+
disableFramesPerSecond,
|
|
1076
|
+
captureScreenFrame,
|
|
1077
|
+
enableTouchCapture,
|
|
1078
|
+
disableTouchCapture,
|
|
1079
|
+
updateSessionProperties,
|
|
1080
|
+
updateCustomProperties,
|
|
1081
|
+
clearSessionProperties,
|
|
1082
|
+
registerCustomProperty,
|
|
1083
|
+
removeCustomProperty,
|
|
1084
|
+
clearCustomProperties,
|
|
1085
|
+
registerTool,
|
|
1086
|
+
unregisterTool,
|
|
1087
|
+
listRegisteredTools,
|
|
1088
|
+
clearRegisteredTools,
|
|
1089
|
+
registerArtifactProvider,
|
|
1090
|
+
registerArtifactProviders,
|
|
1091
|
+
unregisterArtifactProvider,
|
|
1092
|
+
listRegisteredArtifactProviders,
|
|
1093
|
+
clearArtifactProviders,
|
|
1094
|
+
installDomTools,
|
|
1095
|
+
uninstallDomTools,
|
|
1096
|
+
installErrorHandlers,
|
|
1097
|
+
createRouteTracker,
|
|
1098
|
+
startLifecycleTracking,
|
|
1099
|
+
stopLifecycleTracking,
|
|
1100
|
+
startAppStateTracking,
|
|
1101
|
+
stopAppStateTracking,
|
|
1102
|
+
createOptionsBuilder,
|
|
1103
|
+
AnsightOptionsBuilder,
|
|
1104
|
+
native: AnsightNative,
|
|
1105
|
+
platform: core.Capacitor.getPlatform(),
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
exports.AnsightNative = AnsightNative;
|
|
1109
|
+
exports.AnsightOptionsBuilder = AnsightOptionsBuilder;
|
|
1110
|
+
exports.activate = activate;
|
|
1111
|
+
exports.addHostConnectionStatusListener = addHostConnectionStatusListener;
|
|
1112
|
+
exports.addLogListener = addLogListener;
|
|
1113
|
+
exports.captureBuiltInTelemetrySample = captureBuiltInTelemetrySample;
|
|
1114
|
+
exports.captureScreenFrame = captureScreenFrame;
|
|
1115
|
+
exports.clear = clear;
|
|
1116
|
+
exports.clearArtifactProviders = clearArtifactProviders;
|
|
1117
|
+
exports.clearCachedSession = clearCachedSession;
|
|
1118
|
+
exports.clearCustomProperties = clearCustomProperties;
|
|
1119
|
+
exports.clearRegisteredTools = clearRegisteredTools;
|
|
1120
|
+
exports.clearSavedPairing = clearSavedPairing;
|
|
1121
|
+
exports.clearSavedPairingConfig = clearSavedPairingConfig;
|
|
1122
|
+
exports.clearSessionProperties = clearSessionProperties;
|
|
1123
|
+
exports.closeSession = closeSession;
|
|
1124
|
+
exports.completeSession = completeSession;
|
|
1125
|
+
exports.connect = connect;
|
|
1126
|
+
exports.createOptionsBuilder = createOptionsBuilder;
|
|
1127
|
+
exports.createRouteTracker = createRouteTracker;
|
|
1128
|
+
exports.currentOptions = currentOptions;
|
|
1129
|
+
exports.deactivate = deactivate;
|
|
1130
|
+
exports.default = Ansight;
|
|
1131
|
+
exports.disableFramesPerSecond = disableFramesPerSecond;
|
|
1132
|
+
exports.disableTouchCapture = disableTouchCapture;
|
|
1133
|
+
exports.disconnect = disconnect;
|
|
1134
|
+
exports.enableFramesPerSecond = enableFramesPerSecond;
|
|
1135
|
+
exports.enableTouchCapture = enableTouchCapture;
|
|
1136
|
+
exports.event = event;
|
|
1137
|
+
exports.hostConnectionCapabilities = hostConnectionCapabilities;
|
|
1138
|
+
exports.hostConnectionStatus = hostConnectionStatus;
|
|
1139
|
+
exports.initialize = initialize;
|
|
1140
|
+
exports.initializeAndActivate = initializeAndActivate;
|
|
1141
|
+
exports.installDomTools = installDomTools;
|
|
1142
|
+
exports.installErrorHandlers = installErrorHandlers;
|
|
1143
|
+
exports.isFramesPerSecondEnabled = isFramesPerSecondEnabled;
|
|
1144
|
+
exports.listRegisteredArtifactProviders = listRegisteredArtifactProviders;
|
|
1145
|
+
exports.listRegisteredTools = listRegisteredTools;
|
|
1146
|
+
exports.metric = metric;
|
|
1147
|
+
exports.notifyHostConnectionConfigChanged = notifyHostConnectionConfigChanged;
|
|
1148
|
+
exports.openSession = openSession;
|
|
1149
|
+
exports.recordEvent = recordEvent;
|
|
1150
|
+
exports.recordMetric = recordMetric;
|
|
1151
|
+
exports.recordedEvents = recordedEvents;
|
|
1152
|
+
exports.recordedMetrics = recordedMetrics;
|
|
1153
|
+
exports.registerArtifactProvider = registerArtifactProvider;
|
|
1154
|
+
exports.registerArtifactProviders = registerArtifactProviders;
|
|
1155
|
+
exports.registerCustomProperty = registerCustomProperty;
|
|
1156
|
+
exports.registerMetricChannel = registerMetricChannel;
|
|
1157
|
+
exports.registerTool = registerTool;
|
|
1158
|
+
exports.removeCustomProperty = removeCustomProperty;
|
|
1159
|
+
exports.savePairingConfig = savePairingConfig;
|
|
1160
|
+
exports.scanPairingQrCode = scanPairingQrCode;
|
|
1161
|
+
exports.screenViewed = screenViewed;
|
|
1162
|
+
exports.sendClientLog = sendClientLog;
|
|
1163
|
+
exports.setAppLifecycleState = setAppLifecycleState;
|
|
1164
|
+
exports.snapshot = snapshot;
|
|
1165
|
+
exports.startAppStateTracking = startAppStateTracking;
|
|
1166
|
+
exports.startLifecycleTracking = startLifecycleTracking;
|
|
1167
|
+
exports.status = status;
|
|
1168
|
+
exports.stopAppStateTracking = stopAppStateTracking;
|
|
1169
|
+
exports.stopLifecycleTracking = stopLifecycleTracking;
|
|
1170
|
+
exports.trackRoute = trackRoute;
|
|
1171
|
+
exports.uninstallDomTools = uninstallDomTools;
|
|
1172
|
+
exports.unregisterArtifactProvider = unregisterArtifactProvider;
|
|
1173
|
+
exports.unregisterTool = unregisterTool;
|
|
1174
|
+
exports.updateCustomProperties = updateCustomProperties;
|
|
1175
|
+
exports.updateSessionProperties = updateSessionProperties;
|
|
1176
|
+
//# sourceMappingURL=plugin.cjs.js.map
|