@fluixi/devtools 0.2.0-alpha.3 → 0.2.0-alpha.4

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 (64) hide show
  1. package/dist/callsite.cjs +72 -0
  2. package/dist/callsite.mjs +51 -0
  3. package/dist/change-view.cjs +134 -0
  4. package/dist/change-view.mjs +111 -0
  5. package/dist/copy.cjs +63 -0
  6. package/dist/copy.mjs +42 -0
  7. package/dist/describe.cjs +55 -0
  8. package/dist/describe.mjs +34 -0
  9. package/dist/detail-panel.cjs +307 -0
  10. package/dist/detail-panel.mjs +284 -0
  11. package/dist/diff.cjs +225 -0
  12. package/dist/diff.mjs +202 -0
  13. package/dist/dom.cjs +204 -0
  14. package/dist/dom.mjs +183 -0
  15. package/dist/export.cjs +221 -0
  16. package/dist/export.mjs +209 -0
  17. package/dist/float.cjs +232 -0
  18. package/dist/float.mjs +211 -0
  19. package/dist/format.cjs +175 -0
  20. package/dist/format.mjs +154 -0
  21. package/dist/graph-view.cjs +893 -0
  22. package/dist/graph-view.mjs +870 -0
  23. package/dist/highlight.cjs +140 -0
  24. package/dist/highlight.mjs +119 -0
  25. package/dist/history.cjs +95 -0
  26. package/dist/history.mjs +74 -0
  27. package/dist/hook.cjs +1562 -0
  28. package/dist/hook.mjs +1553 -0
  29. package/dist/index.cjs +4552 -0
  30. package/dist/index.mjs +4544 -0
  31. package/dist/inspector.cjs +688 -0
  32. package/dist/inspector.mjs +676 -0
  33. package/dist/instrument.cjs +497 -0
  34. package/dist/instrument.mjs +487 -0
  35. package/dist/kind-filter.cjs +172 -0
  36. package/dist/kind-filter.mjs +151 -0
  37. package/dist/menu.cjs +141 -0
  38. package/dist/menu.mjs +120 -0
  39. package/dist/observe.cjs +1352 -0
  40. package/dist/observe.mjs +1345 -0
  41. package/dist/palette.cjs +52 -0
  42. package/dist/palette.mjs +31 -0
  43. package/dist/path.cjs +45 -0
  44. package/dist/path.mjs +24 -0
  45. package/dist/plugin.cjs +87 -0
  46. package/dist/plugin.mjs +66 -0
  47. package/dist/plugins/context.cjs +98 -0
  48. package/dist/plugins/context.mjs +75 -0
  49. package/dist/plugins/directives.cjs +98 -0
  50. package/dist/plugins/directives.mjs +75 -0
  51. package/dist/plugins/index.cjs +162 -0
  52. package/dist/plugins/index.mjs +140 -0
  53. package/dist/source.cjs +111 -0
  54. package/dist/source.mjs +90 -0
  55. package/dist/timeline.cjs +350 -0
  56. package/dist/timeline.mjs +327 -0
  57. package/dist/tree.cjs +574 -0
  58. package/dist/tree.mjs +551 -0
  59. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  60. package/dist/value-pane.cjs +223 -0
  61. package/dist/value-pane.mjs +200 -0
  62. package/dist/wire.cjs +109 -0
  63. package/dist/wire.mjs +89 -0
  64. package/package.json +13 -6
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/callsite.ts
21
+ var callsite_exports = {};
22
+ __export(callsite_exports, {
23
+ callSite: () => callSite,
24
+ currentCallSite: () => currentCallSite
25
+ });
26
+ module.exports = __toCommonJS(callsite_exports);
27
+ var EXTENSION = ["chrome-extension://", "moz-extension://", "safari-web-extension://", "extension://"];
28
+ var INTERNAL = [
29
+ "/packages/reactive/",
30
+ "/packages/dom/",
31
+ "/packages/core/",
32
+ "/packages/devtools/",
33
+ "/@fluixi/",
34
+ "node_modules",
35
+ "fluixi-devtools",
36
+ ...EXTENSION
37
+ ];
38
+ var REPORTING = [
39
+ "/packages/reactive/src/lib/signal/graph/",
40
+ "/packages/devtools/",
41
+ "fluixi-devtools",
42
+ // Not a fallback either: naming the agent as where a node came from is worse than nothing.
43
+ ...EXTENSION
44
+ ];
45
+ var FRAME = /(?:at\s+(?:[^(]*\()?)([^()\s]+):(\d+):(\d+)\)?$/;
46
+ var isInternal = (frame) => INTERNAL.some((part) => frame.includes(part));
47
+ function locate(frame, origin) {
48
+ const match = FRAME.exec(frame);
49
+ if (!match) return void 0;
50
+ let file = match[1];
51
+ if (origin && file.startsWith(origin)) file = file.slice(origin.length);
52
+ file = file.replace(/^\/@fs\//, "/").replace(/\?.*$/, "").replace(/^\//, "");
53
+ return file ? { file, line: Number(match[2]), column: Number(match[3]) } : void 0;
54
+ }
55
+ function callSite(stack, origin) {
56
+ if (!stack) return void 0;
57
+ let fallback;
58
+ for (const line of stack.split("\n")) {
59
+ const frame = line.trim();
60
+ if (!frame.startsWith("at ")) continue;
61
+ if (!isInternal(frame)) {
62
+ const location = locate(frame, origin);
63
+ if (location) return { location, external: false };
64
+ continue;
65
+ }
66
+ if (!fallback && !REPORTING.some((part) => frame.includes(part))) fallback = locate(frame, origin);
67
+ }
68
+ return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
69
+ }
70
+ function currentCallSite(origin) {
71
+ return callSite(new Error().stack, origin);
72
+ }
@@ -0,0 +1,51 @@
1
+ // src/callsite.ts
2
+ var EXTENSION = ["chrome-extension://", "moz-extension://", "safari-web-extension://", "extension://"];
3
+ var INTERNAL = [
4
+ "/packages/reactive/",
5
+ "/packages/dom/",
6
+ "/packages/core/",
7
+ "/packages/devtools/",
8
+ "/@fluixi/",
9
+ "node_modules",
10
+ "fluixi-devtools",
11
+ ...EXTENSION
12
+ ];
13
+ var REPORTING = [
14
+ "/packages/reactive/src/lib/signal/graph/",
15
+ "/packages/devtools/",
16
+ "fluixi-devtools",
17
+ // Not a fallback either: naming the agent as where a node came from is worse than nothing.
18
+ ...EXTENSION
19
+ ];
20
+ var FRAME = /(?:at\s+(?:[^(]*\()?)([^()\s]+):(\d+):(\d+)\)?$/;
21
+ var isInternal = (frame) => INTERNAL.some((part) => frame.includes(part));
22
+ function locate(frame, origin) {
23
+ const match = FRAME.exec(frame);
24
+ if (!match) return void 0;
25
+ let file = match[1];
26
+ if (origin && file.startsWith(origin)) file = file.slice(origin.length);
27
+ file = file.replace(/^\/@fs\//, "/").replace(/\?.*$/, "").replace(/^\//, "");
28
+ return file ? { file, line: Number(match[2]), column: Number(match[3]) } : void 0;
29
+ }
30
+ function callSite(stack, origin) {
31
+ if (!stack) return void 0;
32
+ let fallback;
33
+ for (const line of stack.split("\n")) {
34
+ const frame = line.trim();
35
+ if (!frame.startsWith("at ")) continue;
36
+ if (!isInternal(frame)) {
37
+ const location = locate(frame, origin);
38
+ if (location) return { location, external: false };
39
+ continue;
40
+ }
41
+ if (!fallback && !REPORTING.some((part) => frame.includes(part))) fallback = locate(frame, origin);
42
+ }
43
+ return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
44
+ }
45
+ function currentCallSite(origin) {
46
+ return callSite(new Error().stack, origin);
47
+ }
48
+ export {
49
+ callSite,
50
+ currentCallSite
51
+ };
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/change-view.ts
21
+ var change_view_exports = {};
22
+ __export(change_view_exports, {
23
+ CHANGE_CSS: () => CHANGE_CSS,
24
+ changeRows: () => changeRows,
25
+ handleCopyClick: () => handleCopyClick
26
+ });
27
+ module.exports = __toCommonJS(change_view_exports);
28
+
29
+ // src/copy.ts
30
+ function confirmOn(button, said = "copied") {
31
+ if (!button) return;
32
+ const was = button.textContent;
33
+ button.textContent = said;
34
+ setTimeout(() => {
35
+ button.textContent = was;
36
+ }, 1200);
37
+ }
38
+ function fallback(text, button) {
39
+ try {
40
+ const doc = button?.ownerDocument ?? document;
41
+ const area = doc.createElement("textarea");
42
+ area.value = text;
43
+ area.setAttribute("readonly", "");
44
+ area.style.position = "fixed";
45
+ area.style.opacity = "0";
46
+ doc.body.appendChild(area);
47
+ area.select();
48
+ doc.execCommand("copy");
49
+ area.remove();
50
+ confirmOn(button);
51
+ return true;
52
+ } catch {
53
+ return false;
54
+ }
55
+ }
56
+ async function copyText(text, button) {
57
+ const clipboard = globalThis.navigator?.clipboard;
58
+ if (clipboard?.writeText) {
59
+ try {
60
+ await clipboard.writeText(text);
61
+ confirmOn(button);
62
+ return true;
63
+ } catch {
64
+ }
65
+ }
66
+ return fallback(text, button);
67
+ }
68
+
69
+ // src/change-view.ts
70
+ var escape = (text) => text.replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
71
+ var SIGN = { added: "+", removed: "−", changed: "~" };
72
+ function pretty(json) {
73
+ if (!json) return void 0;
74
+ try {
75
+ return JSON.stringify(JSON.parse(json), null, 2);
76
+ } catch {
77
+ return void 0;
78
+ }
79
+ }
80
+ function sideOf(text, json, cls) {
81
+ const block = pretty(json);
82
+ if (!block) return `<span class="ch-${cls}">${escape(text ?? "")}</span>`;
83
+ return `<div class="ch-block ch-${cls}"><button type="button" class="ch-copy" title="Copy" data-copy="${escape(block)}">copy</button><pre class="ch-json">${escape(block)}</pre></div>`;
84
+ }
85
+ function changeRows(change, limit = Infinity) {
86
+ if (!change?.entries?.length) return "";
87
+ const shown = change.entries.slice(0, limit);
88
+ const hidden = change.entries.length - shown.length + (change.more ?? 0);
89
+ const rows = shown.map((entry) => {
90
+ const from = sideOf(entry.from, entry.fromJson, "from");
91
+ const to = sideOf(entry.to, entry.toJson, "to");
92
+ const sides = entry.op === "changed" ? `${from}<span class="ch-arrow">→</span>${to}` : entry.op === "added" ? to : from;
93
+ const stacked = entry.fromJson || entry.toJson ? " ch-stacked" : "";
94
+ return `<div class="ch-row ch-${entry.op}${stacked}"><span class="ch-sign">${SIGN[entry.op] ?? "·"}</span><span class="ch-key">${escape(entry.key)}</span><span class="ch-sides">${sides}</span></div>`;
95
+ }).join("");
96
+ const size = change.length ? `<div class="ch-size">${change.length.from} → ${change.length.to} items</div>` : "";
97
+ return `<div class="ch-list">${size}${rows}${hidden > 0 ? `<div class="ch-more">and ${hidden} more</div>` : ""}</div>`;
98
+ }
99
+ function handleCopyClick(event) {
100
+ const button = event.target?.closest?.(".ch-copy");
101
+ if (!button) return false;
102
+ void copyText(button.dataset.copy ?? "", button);
103
+ return true;
104
+ }
105
+ var CHANGE_CSS = `
106
+ .ch-list { margin-top: 4px; font-family: ui-monospace, monospace; font-size: 11px; }
107
+ .ch-size { color: var(--fx-muted, #8a90a2); margin-bottom: 2px; }
108
+ .ch-row { display: flex; gap: 6px; align-items: baseline; padding: 1px 0; }
109
+ .ch-row.ch-stacked { align-items: flex-start; padding: 3px 0; }
110
+ .ch-sign { flex: none; width: 9px; text-align: center; }
111
+ .ch-added .ch-sign { color: var(--state, #34d399); }
112
+ .ch-removed .ch-sign { color: var(--fx-write, #fb7185); }
113
+ .ch-changed .ch-sign { color: var(--effect, #fbbf24); }
114
+ .ch-key { flex: none; color: var(--fx-muted, #8a90a2); }
115
+ .ch-sides { min-width: 0; flex: 1; overflow-wrap: anywhere; }
116
+ .ch-stacked .ch-sides { display: flex; flex-direction: column; gap: 2px; }
117
+ .ch-from { color: var(--fx-muted, #8a90a2); }
118
+ .ch-row:not(.ch-stacked) .ch-from { text-decoration: line-through; }
119
+ .ch-arrow { color: var(--fx-muted, #8a90a2); margin: 0 4px; }
120
+ .ch-to { color: var(--fx-label, #e7e9ee); }
121
+ .ch-more { color: var(--fx-muted, #8a90a2); margin-top: 2px; }
122
+ /* In the corner: an object can be tall, and a button under it is a scroll away. */
123
+ .ch-block { position: relative; border-radius: 4px; border: 1px solid var(--fx-line, #ffffff14); }
124
+ .ch-block.ch-from { opacity: .72; }
125
+ .ch-json { margin: 0; padding: 5px 7px; overflow-x: auto; white-space: pre; font: inherit; }
126
+ .ch-copy {
127
+ position: absolute; top: 3px; right: 3px; padding: 1px 6px; cursor: pointer;
128
+ font: inherit; font-size: 9.5px; opacity: 0; transition: opacity .12s;
129
+ border: 1px solid var(--fx-line, #ffffff26); border-radius: 3px;
130
+ background: var(--fx-panel, #14161c); color: var(--fx-muted, #8a90a2);
131
+ }
132
+ .ch-block:hover .ch-copy, .ch-copy:focus { opacity: 1; }
133
+ .ch-copy:hover { color: var(--fx-label, #e7e9ee); }
134
+ `;
@@ -0,0 +1,111 @@
1
+ // src/copy.ts
2
+ function confirmOn(button, said = "copied") {
3
+ if (!button) return;
4
+ const was = button.textContent;
5
+ button.textContent = said;
6
+ setTimeout(() => {
7
+ button.textContent = was;
8
+ }, 1200);
9
+ }
10
+ function fallback(text, button) {
11
+ try {
12
+ const doc = button?.ownerDocument ?? document;
13
+ const area = doc.createElement("textarea");
14
+ area.value = text;
15
+ area.setAttribute("readonly", "");
16
+ area.style.position = "fixed";
17
+ area.style.opacity = "0";
18
+ doc.body.appendChild(area);
19
+ area.select();
20
+ doc.execCommand("copy");
21
+ area.remove();
22
+ confirmOn(button);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+ async function copyText(text, button) {
29
+ const clipboard = globalThis.navigator?.clipboard;
30
+ if (clipboard?.writeText) {
31
+ try {
32
+ await clipboard.writeText(text);
33
+ confirmOn(button);
34
+ return true;
35
+ } catch {
36
+ }
37
+ }
38
+ return fallback(text, button);
39
+ }
40
+
41
+ // src/change-view.ts
42
+ var escape = (text) => text.replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
43
+ var SIGN = { added: "+", removed: "−", changed: "~" };
44
+ function pretty(json) {
45
+ if (!json) return void 0;
46
+ try {
47
+ return JSON.stringify(JSON.parse(json), null, 2);
48
+ } catch {
49
+ return void 0;
50
+ }
51
+ }
52
+ function sideOf(text, json, cls) {
53
+ const block = pretty(json);
54
+ if (!block) return `<span class="ch-${cls}">${escape(text ?? "")}</span>`;
55
+ return `<div class="ch-block ch-${cls}"><button type="button" class="ch-copy" title="Copy" data-copy="${escape(block)}">copy</button><pre class="ch-json">${escape(block)}</pre></div>`;
56
+ }
57
+ function changeRows(change, limit = Infinity) {
58
+ if (!change?.entries?.length) return "";
59
+ const shown = change.entries.slice(0, limit);
60
+ const hidden = change.entries.length - shown.length + (change.more ?? 0);
61
+ const rows = shown.map((entry) => {
62
+ const from = sideOf(entry.from, entry.fromJson, "from");
63
+ const to = sideOf(entry.to, entry.toJson, "to");
64
+ const sides = entry.op === "changed" ? `${from}<span class="ch-arrow">→</span>${to}` : entry.op === "added" ? to : from;
65
+ const stacked = entry.fromJson || entry.toJson ? " ch-stacked" : "";
66
+ return `<div class="ch-row ch-${entry.op}${stacked}"><span class="ch-sign">${SIGN[entry.op] ?? "·"}</span><span class="ch-key">${escape(entry.key)}</span><span class="ch-sides">${sides}</span></div>`;
67
+ }).join("");
68
+ const size = change.length ? `<div class="ch-size">${change.length.from} → ${change.length.to} items</div>` : "";
69
+ return `<div class="ch-list">${size}${rows}${hidden > 0 ? `<div class="ch-more">and ${hidden} more</div>` : ""}</div>`;
70
+ }
71
+ function handleCopyClick(event) {
72
+ const button = event.target?.closest?.(".ch-copy");
73
+ if (!button) return false;
74
+ void copyText(button.dataset.copy ?? "", button);
75
+ return true;
76
+ }
77
+ var CHANGE_CSS = `
78
+ .ch-list { margin-top: 4px; font-family: ui-monospace, monospace; font-size: 11px; }
79
+ .ch-size { color: var(--fx-muted, #8a90a2); margin-bottom: 2px; }
80
+ .ch-row { display: flex; gap: 6px; align-items: baseline; padding: 1px 0; }
81
+ .ch-row.ch-stacked { align-items: flex-start; padding: 3px 0; }
82
+ .ch-sign { flex: none; width: 9px; text-align: center; }
83
+ .ch-added .ch-sign { color: var(--state, #34d399); }
84
+ .ch-removed .ch-sign { color: var(--fx-write, #fb7185); }
85
+ .ch-changed .ch-sign { color: var(--effect, #fbbf24); }
86
+ .ch-key { flex: none; color: var(--fx-muted, #8a90a2); }
87
+ .ch-sides { min-width: 0; flex: 1; overflow-wrap: anywhere; }
88
+ .ch-stacked .ch-sides { display: flex; flex-direction: column; gap: 2px; }
89
+ .ch-from { color: var(--fx-muted, #8a90a2); }
90
+ .ch-row:not(.ch-stacked) .ch-from { text-decoration: line-through; }
91
+ .ch-arrow { color: var(--fx-muted, #8a90a2); margin: 0 4px; }
92
+ .ch-to { color: var(--fx-label, #e7e9ee); }
93
+ .ch-more { color: var(--fx-muted, #8a90a2); margin-top: 2px; }
94
+ /* In the corner: an object can be tall, and a button under it is a scroll away. */
95
+ .ch-block { position: relative; border-radius: 4px; border: 1px solid var(--fx-line, #ffffff14); }
96
+ .ch-block.ch-from { opacity: .72; }
97
+ .ch-json { margin: 0; padding: 5px 7px; overflow-x: auto; white-space: pre; font: inherit; }
98
+ .ch-copy {
99
+ position: absolute; top: 3px; right: 3px; padding: 1px 6px; cursor: pointer;
100
+ font: inherit; font-size: 9.5px; opacity: 0; transition: opacity .12s;
101
+ border: 1px solid var(--fx-line, #ffffff26); border-radius: 3px;
102
+ background: var(--fx-panel, #14161c); color: var(--fx-muted, #8a90a2);
103
+ }
104
+ .ch-block:hover .ch-copy, .ch-copy:focus { opacity: 1; }
105
+ .ch-copy:hover { color: var(--fx-label, #e7e9ee); }
106
+ `;
107
+ export {
108
+ CHANGE_CSS,
109
+ changeRows,
110
+ handleCopyClick
111
+ };
package/dist/copy.cjs ADDED
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/copy.ts
21
+ var copy_exports = {};
22
+ __export(copy_exports, {
23
+ copyText: () => copyText
24
+ });
25
+ module.exports = __toCommonJS(copy_exports);
26
+ function confirmOn(button, said = "copied") {
27
+ if (!button) return;
28
+ const was = button.textContent;
29
+ button.textContent = said;
30
+ setTimeout(() => {
31
+ button.textContent = was;
32
+ }, 1200);
33
+ }
34
+ function fallback(text, button) {
35
+ try {
36
+ const doc = button?.ownerDocument ?? document;
37
+ const area = doc.createElement("textarea");
38
+ area.value = text;
39
+ area.setAttribute("readonly", "");
40
+ area.style.position = "fixed";
41
+ area.style.opacity = "0";
42
+ doc.body.appendChild(area);
43
+ area.select();
44
+ doc.execCommand("copy");
45
+ area.remove();
46
+ confirmOn(button);
47
+ return true;
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+ async function copyText(text, button) {
53
+ const clipboard = globalThis.navigator?.clipboard;
54
+ if (clipboard?.writeText) {
55
+ try {
56
+ await clipboard.writeText(text);
57
+ confirmOn(button);
58
+ return true;
59
+ } catch {
60
+ }
61
+ }
62
+ return fallback(text, button);
63
+ }
package/dist/copy.mjs ADDED
@@ -0,0 +1,42 @@
1
+ // src/copy.ts
2
+ function confirmOn(button, said = "copied") {
3
+ if (!button) return;
4
+ const was = button.textContent;
5
+ button.textContent = said;
6
+ setTimeout(() => {
7
+ button.textContent = was;
8
+ }, 1200);
9
+ }
10
+ function fallback(text, button) {
11
+ try {
12
+ const doc = button?.ownerDocument ?? document;
13
+ const area = doc.createElement("textarea");
14
+ area.value = text;
15
+ area.setAttribute("readonly", "");
16
+ area.style.position = "fixed";
17
+ area.style.opacity = "0";
18
+ doc.body.appendChild(area);
19
+ area.select();
20
+ doc.execCommand("copy");
21
+ area.remove();
22
+ confirmOn(button);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+ async function copyText(text, button) {
29
+ const clipboard = globalThis.navigator?.clipboard;
30
+ if (clipboard?.writeText) {
31
+ try {
32
+ await clipboard.writeText(text);
33
+ confirmOn(button);
34
+ return true;
35
+ } catch {
36
+ }
37
+ }
38
+ return fallback(text, button);
39
+ }
40
+ export {
41
+ copyText
42
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/describe.ts
21
+ var describe_exports = {};
22
+ __export(describe_exports, {
23
+ describeNode: () => describeNode
24
+ });
25
+ module.exports = __toCommonJS(describe_exports);
26
+ var MAX_CLASSES = 2;
27
+ function textOwner(node) {
28
+ const parent = node.parentElement;
29
+ return parent ? `text in ${describeElement(parent)}` : "text";
30
+ }
31
+ function describeElement(el) {
32
+ const tag = el.tagName.toLowerCase();
33
+ const id = el.id ? `#${el.id}` : "";
34
+ const raw = typeof el.className === "string" ? el.className : el.getAttribute("class") ?? "";
35
+ const classes = raw.split(/\s+/).filter(Boolean).slice(0, MAX_CLASSES).map((c) => `.${c}`).join("");
36
+ return `${tag}${id}${classes}`;
37
+ }
38
+ function describeNode(target) {
39
+ const node = target;
40
+ if (!node || typeof node.nodeType !== "number") return "detached";
41
+ switch (node.nodeType) {
42
+ case 1:
43
+ return describeElement(node);
44
+ case 3:
45
+ return textOwner(node);
46
+ case 8: {
47
+ const parent = node.parentElement;
48
+ return parent ? `slot in ${describeElement(parent)}` : "slot";
49
+ }
50
+ case 11:
51
+ return "fragment";
52
+ default:
53
+ return node.nodeName?.toLowerCase() ?? "node";
54
+ }
55
+ }
@@ -0,0 +1,34 @@
1
+ // src/describe.ts
2
+ var MAX_CLASSES = 2;
3
+ function textOwner(node) {
4
+ const parent = node.parentElement;
5
+ return parent ? `text in ${describeElement(parent)}` : "text";
6
+ }
7
+ function describeElement(el) {
8
+ const tag = el.tagName.toLowerCase();
9
+ const id = el.id ? `#${el.id}` : "";
10
+ const raw = typeof el.className === "string" ? el.className : el.getAttribute("class") ?? "";
11
+ const classes = raw.split(/\s+/).filter(Boolean).slice(0, MAX_CLASSES).map((c) => `.${c}`).join("");
12
+ return `${tag}${id}${classes}`;
13
+ }
14
+ function describeNode(target) {
15
+ const node = target;
16
+ if (!node || typeof node.nodeType !== "number") return "detached";
17
+ switch (node.nodeType) {
18
+ case 1:
19
+ return describeElement(node);
20
+ case 3:
21
+ return textOwner(node);
22
+ case 8: {
23
+ const parent = node.parentElement;
24
+ return parent ? `slot in ${describeElement(parent)}` : "slot";
25
+ }
26
+ case 11:
27
+ return "fragment";
28
+ default:
29
+ return node.nodeName?.toLowerCase() ?? "node";
30
+ }
31
+ }
32
+ export {
33
+ describeNode
34
+ };