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

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 (91) hide show
  1. package/dist/callsite.cjs +72 -0
  2. package/dist/callsite.d.ts +1 -1
  3. package/dist/callsite.js +1 -1
  4. package/dist/callsite.mjs +51 -0
  5. package/dist/change-view.cjs +134 -0
  6. package/dist/change-view.js +2 -2
  7. package/dist/change-view.mjs +111 -0
  8. package/dist/copy.cjs +63 -0
  9. package/dist/copy.mjs +42 -0
  10. package/dist/describe.cjs +55 -0
  11. package/dist/describe.js +2 -2
  12. package/dist/describe.mjs +34 -0
  13. package/dist/detail-panel.cjs +307 -0
  14. package/dist/detail-panel.d.ts +1 -1
  15. package/dist/detail-panel.d.ts.map +1 -1
  16. package/dist/detail-panel.js +1 -1
  17. package/dist/detail-panel.mjs +284 -0
  18. package/dist/diff.cjs +225 -0
  19. package/dist/diff.js +1 -1
  20. package/dist/diff.mjs +202 -0
  21. package/dist/dom.cjs +204 -0
  22. package/dist/dom.mjs +183 -0
  23. package/dist/export.cjs +221 -0
  24. package/dist/export.d.ts +2 -2
  25. package/dist/export.d.ts.map +1 -1
  26. package/dist/export.js +1 -1
  27. package/dist/export.mjs +209 -0
  28. package/dist/float.cjs +232 -0
  29. package/dist/float.d.ts +1 -1
  30. package/dist/float.js +3 -3
  31. package/dist/float.mjs +211 -0
  32. package/dist/format.cjs +175 -0
  33. package/dist/format.js +3 -3
  34. package/dist/format.mjs +154 -0
  35. package/dist/graph-view.cjs +893 -0
  36. package/dist/graph-view.mjs +870 -0
  37. package/dist/highlight.cjs +140 -0
  38. package/dist/highlight.mjs +119 -0
  39. package/dist/history.cjs +95 -0
  40. package/dist/history.d.ts +2 -2
  41. package/dist/history.js +2 -2
  42. package/dist/history.mjs +74 -0
  43. package/dist/hook.cjs +1562 -0
  44. package/dist/hook.d.ts +3 -3
  45. package/dist/hook.js +6 -6
  46. package/dist/hook.mjs +1553 -0
  47. package/dist/index.cjs +4552 -0
  48. package/dist/index.mjs +4544 -0
  49. package/dist/inspector.cjs +688 -0
  50. package/dist/inspector.d.ts +2 -2
  51. package/dist/inspector.js +7 -7
  52. package/dist/inspector.mjs +676 -0
  53. package/dist/instrument.cjs +497 -0
  54. package/dist/instrument.mjs +487 -0
  55. package/dist/kind-filter.cjs +172 -0
  56. package/dist/kind-filter.d.ts +2 -2
  57. package/dist/kind-filter.js +1 -1
  58. package/dist/kind-filter.mjs +151 -0
  59. package/dist/menu.cjs +141 -0
  60. package/dist/menu.mjs +120 -0
  61. package/dist/observe.cjs +1352 -0
  62. package/dist/observe.mjs +1345 -0
  63. package/dist/palette.cjs +52 -0
  64. package/dist/palette.mjs +31 -0
  65. package/dist/path.cjs +45 -0
  66. package/dist/path.d.ts +2 -2
  67. package/dist/path.js +2 -2
  68. package/dist/path.mjs +24 -0
  69. package/dist/plugin.cjs +87 -0
  70. package/dist/plugin.mjs +66 -0
  71. package/dist/plugins/context.cjs +98 -0
  72. package/dist/plugins/context.mjs +75 -0
  73. package/dist/plugins/directives.cjs +98 -0
  74. package/dist/plugins/directives.mjs +75 -0
  75. package/dist/plugins/index.cjs +162 -0
  76. package/dist/plugins/index.mjs +140 -0
  77. package/dist/source.cjs +111 -0
  78. package/dist/source.d.ts +2 -2
  79. package/dist/source.js +4 -4
  80. package/dist/source.mjs +90 -0
  81. package/dist/timeline.cjs +350 -0
  82. package/dist/timeline.js +3 -3
  83. package/dist/timeline.mjs +327 -0
  84. package/dist/tree.cjs +574 -0
  85. package/dist/tree.mjs +551 -0
  86. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  87. package/dist/value-pane.cjs +223 -0
  88. package/dist/value-pane.mjs +200 -0
  89. package/dist/wire.cjs +109 -0
  90. package/dist/wire.mjs +89 -0
  91. package/package.json +19 -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
+ }
@@ -3,7 +3,7 @@ import type { ReactiveSourceLocation } from './source.js';
3
3
  * Where a node came from, and whether that is the application or something it depends on.
4
4
  *
5
5
  * The application's own frame is the useful one, but a node made while a package was loading
6
- * has no application frame above it at all a router's revalidation counter, made when its
6
+ * has no application frame above it at all: a router's revalidation counter, made when its
7
7
  * module is evaluated. Falling back to the package's own frame is what stops that node being
8
8
  * a card with no name, no origin and no explanation.
9
9
  */
package/dist/callsite.js CHANGED
@@ -49,7 +49,7 @@ function locate(frame, origin) {
49
49
  * Where a node came from, and whether that is the application or something it depends on.
50
50
  *
51
51
  * The application's own frame is the useful one, but a node made while a package was loading
52
- * has no application frame above it at all a router's revalidation counter, made when its
52
+ * has no application frame above it at all: a router's revalidation counter, made when its
53
53
  * module is evaluated. Falling back to the package's own frame is what stops that node being
54
54
  * a card with no name, no origin and no explanation.
55
55
  */
@@ -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
+ `;
@@ -1,4 +1,4 @@
1
- // A diff, drawn. Shared between the timeline's open row and the panel that opens from it
1
+ // A diff, drawn. Shared between the timeline's open row and the panel that opens from it ,
2
2
  // same rows, cut to a handful in the sidebar and shown in full when there is room.
3
3
  //
4
4
  // An object is drawn as an object: `{id: 1, text: "go"}` on one line is what the cards
@@ -14,7 +14,7 @@ function pretty(json) {
14
14
  return JSON.stringify(JSON.parse(json), null, 2);
15
15
  }
16
16
  catch {
17
- // It came from JSON.stringify, so this should not happen but a malformed payload is
17
+ // It came from JSON.stringify, so this should not happen, but a malformed payload is
18
18
  // not worth losing the row over.
19
19
  return undefined;
20
20
  }
@@ -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
+ }
package/dist/describe.js CHANGED
@@ -3,10 +3,10 @@
3
3
  // The element is described at the moment it is reported and the reference dropped: holding
4
4
  // one would keep a removed subtree alive for as long as the panel is open.
5
5
  //
6
- // Enough to find it on the page tag, id, a class or two without being a selector.
6
+ // Enough to find it on the page: tag, id, a class or two, without being a selector.
7
7
  /** More than this is a selector, not a label. */
8
8
  const MAX_CLASSES = 2;
9
- /** `text in li` the element it sits in is what locates it. */
9
+ /** `text in li`: the element it sits in is what locates it. */
10
10
  function textOwner(node) {
11
11
  const parent = node.parentElement;
12
12
  return parent ? `text in ${describeElement(parent)}` : 'text';
@@ -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
+ };