@deshlo/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/build/src/GithubPlugin.d.ts +8 -0
  2. package/build/src/GithubPlugin.d.ts.map +1 -0
  3. package/build/src/GithubPlugin.js +11 -0
  4. package/build/src/OverlayGate.d.ts +6 -0
  5. package/build/src/OverlayGate.d.ts.map +1 -0
  6. package/build/src/OverlayGate.js +13 -0
  7. package/build/src/OverlayGatePanel.d.ts +5 -0
  8. package/build/src/OverlayGatePanel.d.ts.map +1 -0
  9. package/build/src/OverlayGatePanel.js +52 -0
  10. package/build/src/SourceInspector.d.ts +15 -0
  11. package/build/src/SourceInspector.d.ts.map +1 -0
  12. package/build/src/SourceInspector.js +171 -0
  13. package/build/src/adapters/vite.d.ts +15 -0
  14. package/build/src/adapters/vite.d.ts.map +1 -0
  15. package/build/src/adapters/vite.js +47 -0
  16. package/build/src/adapters/webpack.d.ts +5 -0
  17. package/build/src/adapters/webpack.d.ts.map +1 -0
  18. package/build/src/adapters/webpack.js +15 -0
  19. package/build/src/github.d.ts +3 -0
  20. package/build/src/github.d.ts.map +1 -0
  21. package/build/src/github.js +6 -0
  22. package/build/src/github.test.d.ts +2 -0
  23. package/build/src/github.test.d.ts.map +1 -0
  24. package/build/src/github.test.js +17 -0
  25. package/build/src/index.d.ts +5 -0
  26. package/build/src/index.d.ts.map +1 -0
  27. package/build/src/index.js +11 -0
  28. package/build/src/overlay/OverlayGate.d.ts +6 -0
  29. package/build/src/overlay/OverlayGate.d.ts.map +1 -0
  30. package/build/src/overlay/OverlayGate.js +13 -0
  31. package/build/src/overlay/OverlayGatePanel.d.ts +5 -0
  32. package/build/src/overlay/OverlayGatePanel.d.ts.map +1 -0
  33. package/build/src/overlay/OverlayGatePanel.js +52 -0
  34. package/build/src/overlay/SourceInspector.d.ts +15 -0
  35. package/build/src/overlay/SourceInspector.d.ts.map +1 -0
  36. package/build/src/overlay/SourceInspector.js +174 -0
  37. package/build/src/overlay/overlay-plugin-provider.d.ts +9 -0
  38. package/build/src/overlay/overlay-plugin-provider.d.ts.map +1 -0
  39. package/build/src/overlay/overlay-plugin-provider.js +14 -0
  40. package/build/src/overlay/overlay-plugin.d.ts +2 -0
  41. package/build/src/overlay/overlay-plugin.d.ts.map +1 -0
  42. package/build/src/overlay/overlay-plugin.js +7 -0
  43. package/build/src/overlay/overlay-plugin.test.d.ts +2 -0
  44. package/build/src/overlay/overlay-plugin.test.d.ts.map +1 -0
  45. package/build/src/overlay/overlay-plugin.test.js +30 -0
  46. package/build/src/overlay/source-inspector-context.d.ts +20 -0
  47. package/build/src/overlay/source-inspector-context.d.ts.map +1 -0
  48. package/build/src/overlay/source-inspector-context.js +17 -0
  49. package/build/src/overlay/submit-handler.d.ts +7 -0
  50. package/build/src/overlay/submit-handler.d.ts.map +1 -0
  51. package/build/src/overlay/submit-handler.js +20 -0
  52. package/build/src/overlay/submit-handler.test.d.ts +2 -0
  53. package/build/src/overlay/submit-handler.test.d.ts.map +1 -0
  54. package/build/src/overlay/submit-handler.test.js +52 -0
  55. package/build/src/overlay-plugin-provider.d.ts +9 -0
  56. package/build/src/overlay-plugin-provider.d.ts.map +1 -0
  57. package/build/src/overlay-plugin-provider.js +14 -0
  58. package/build/src/overlay-plugin.d.ts +2 -0
  59. package/build/src/overlay-plugin.d.ts.map +1 -0
  60. package/build/src/overlay-plugin.js +7 -0
  61. package/build/src/overlay-plugin.test.d.ts +2 -0
  62. package/build/src/overlay-plugin.test.d.ts.map +1 -0
  63. package/build/src/overlay-plugin.test.js +29 -0
  64. package/build/src/overlay.d.ts +5 -0
  65. package/build/src/overlay.d.ts.map +1 -0
  66. package/build/src/overlay.js +12 -0
  67. package/build/src/plugins/github/GithubPlugin.d.ts +8 -0
  68. package/build/src/plugins/github/GithubPlugin.d.ts.map +1 -0
  69. package/build/src/plugins/github/GithubPlugin.js +11 -0
  70. package/build/src/plugins/github/github.test.d.ts +2 -0
  71. package/build/src/plugins/github/github.test.d.ts.map +1 -0
  72. package/build/src/plugins/github/github.test.js +17 -0
  73. package/build/src/source-inspector-context.d.ts +20 -0
  74. package/build/src/source-inspector-context.d.ts.map +1 -0
  75. package/build/src/source-inspector-context.js +17 -0
  76. package/build/src/submit-handler.d.ts +7 -0
  77. package/build/src/submit-handler.d.ts.map +1 -0
  78. package/build/src/submit-handler.js +20 -0
  79. package/build/src/submit-handler.test.d.ts +2 -0
  80. package/build/src/submit-handler.test.d.ts.map +1 -0
  81. package/build/src/submit-handler.test.js +52 -0
  82. package/build/src/vite.d.ts +2 -0
  83. package/build/src/vite.d.ts.map +1 -0
  84. package/build/src/vite.js +17 -0
  85. package/build/src/webpack.d.ts +2 -0
  86. package/build/src/webpack.d.ts.map +1 -0
  87. package/build/src/webpack.js +17 -0
  88. package/package.json +59 -0
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ import { type GitHubBrowserPluginConfig } from "@fdb/plugin-github";
3
+ export interface GithubPluginProps {
4
+ config?: GitHubBrowserPluginConfig;
5
+ children: ReactNode;
6
+ }
7
+ export declare function GithubPlugin({ children, config }: GithubPluginProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=GithubPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GithubPlugin.d.ts","sourceRoot":"","sources":["../../src/GithubPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,iBAAiB,2CAInE"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.GithubPlugin = GithubPlugin;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const plugin_github_1 = require("@fdb/plugin-github");
7
+ const overlay_plugin_provider_1 = require("./overlay-plugin-provider");
8
+ function GithubPlugin({ children, config }) {
9
+ const plugin = (0, plugin_github_1.createGitHubBrowserPlugin)(config || {});
10
+ return (0, jsx_runtime_1.jsx)(overlay_plugin_provider_1.OverlayPluginProvider, { plugin: plugin, children: children });
11
+ }
@@ -0,0 +1,6 @@
1
+ import { type SourceInspectorProps } from "./SourceInspector";
2
+ import { type OverlayGatePanelProps } from "./OverlayGatePanel";
3
+ export interface OverlayGateProps extends Omit<SourceInspectorProps, "children">, OverlayGatePanelProps {
4
+ }
5
+ export default function OverlayGate({ width, ...sourceInspectorProps }: OverlayGateProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=OverlayGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayGate.d.ts","sourceRoot":"","sources":["../../src/OverlayGate.tsx"],"names":[],"mappings":"AAEA,OAAwB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAyB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAElF,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,EAC5C,qBAAqB;CAAG;AAE5B,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,oBAAoB,EAAE,EAAE,gBAAgB,2CAMvF"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ "use client";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.default = OverlayGate;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ const SourceInspector_1 = __importDefault(require("./SourceInspector"));
10
+ const OverlayGatePanel_1 = __importDefault(require("./OverlayGatePanel"));
11
+ function OverlayGate({ width, ...sourceInspectorProps }) {
12
+ return ((0, jsx_runtime_1.jsx)(SourceInspector_1.default, { ...sourceInspectorProps, children: (0, jsx_runtime_1.jsx)(OverlayGatePanel_1.default, { width: width }) }));
13
+ }
@@ -0,0 +1,5 @@
1
+ export interface OverlayGatePanelProps {
2
+ width?: number;
3
+ }
4
+ export default function OverlayGatePanel({ width }: OverlayGatePanelProps): import("react/jsx-runtime").JSX.Element | null;
5
+ //# sourceMappingURL=OverlayGatePanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayGatePanel.d.ts","sourceRoot":"","sources":["../../src/OverlayGatePanel.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,KAAW,EAAE,EAAE,qBAAqB,kDAgJ9E"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.default = OverlayGatePanel;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const source_inspector_context_1 = require("./source-inspector-context");
7
+ function OverlayGatePanel({ width = 420 }) {
8
+ const { inspectorEnabled, triggerKey, pluginId, selection, selectionWarning, proposedText, submitting, result, setProposedText, submit, } = (0, source_inspector_context_1.useSourceInspectorContext)();
9
+ if (!inspectorEnabled) {
10
+ return null;
11
+ }
12
+ const canSubmit = Boolean(selection && proposedText.trim() && !submitting);
13
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
14
+ position: "fixed",
15
+ right: 12,
16
+ bottom: 12,
17
+ zIndex: 9999,
18
+ width,
19
+ maxHeight: "80vh",
20
+ overflowY: "auto",
21
+ padding: 12,
22
+ borderRadius: 10,
23
+ border: "1px solid #f59e0b",
24
+ background: "rgba(17, 17, 17, 0.96)",
25
+ color: "#f8fafc",
26
+ fontSize: 12,
27
+ lineHeight: 1.45,
28
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 700, marginBottom: 6 }, children: "Source Inspector" }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: ["Hold ", triggerKey.toUpperCase(), " + click to select an element from source."] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: ["Plugin: ", (0, jsx_runtime_1.jsx)("code", { children: pluginId })] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: "Selection" }), selection ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { children: ["Tag: ", (0, jsx_runtime_1.jsx)("code", { children: selection.tagName })] }), (0, jsx_runtime_1.jsxs)("div", { children: ["Source: ", (0, jsx_runtime_1.jsx)("code", { children: selection.sourceLoc })] }), (0, jsx_runtime_1.jsxs)("div", { children: ["Current text: ", (0, jsx_runtime_1.jsx)("code", { children: selection.selectedText })] })] })) : ((0, jsx_runtime_1.jsx)("div", { style: { opacity: 0.85 }, children: "No valid element selected yet." }))] }), selectionWarning ? ((0, jsx_runtime_1.jsx)("div", { style: { marginBottom: 8, color: "#fca5a5" }, children: selectionWarning })) : null, selection ? ((0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: [(0, jsx_runtime_1.jsx)("label", { style: { display: "block", marginBottom: 4, fontWeight: 600 }, children: "Proposed changes" }), (0, jsx_runtime_1.jsx)("textarea", { value: proposedText, onChange: (event) => {
29
+ setProposedText(event.target.value);
30
+ }, rows: 4, style: {
31
+ width: "100%",
32
+ resize: "vertical",
33
+ padding: 8,
34
+ borderRadius: 6,
35
+ border: "1px solid #334155",
36
+ fontFamily: "inherit",
37
+ fontSize: 12,
38
+ } })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: { display: "flex", gap: 8, marginBottom: 10 }, children: (0, jsx_runtime_1.jsx)("button", { onClick: submit, disabled: !canSubmit, style: {
39
+ flex: 1,
40
+ padding: "8px 10px",
41
+ borderRadius: 6,
42
+ border: "1px solid #22c55e",
43
+ background: canSubmit ? "#22c55e" : "#475569",
44
+ color: "#111827",
45
+ fontWeight: 600,
46
+ cursor: canSubmit ? "pointer" : "not-allowed",
47
+ }, children: submitting ? "Submitting..." : "Submit changes" }) }), result ? ((0, jsx_runtime_1.jsxs)("div", { style: {
48
+ borderTop: "1px solid #334155",
49
+ paddingTop: 8,
50
+ color: result.ok ? "#86efac" : "#fca5a5",
51
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 700, marginBottom: 4 }, children: result.ok ? "Success" : "Error" }), (0, jsx_runtime_1.jsx)("div", { children: result.message }), result.links && result.links.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { style: { marginTop: 6, display: "flex", flexDirection: "column", gap: 4 }, children: result.links.map((link) => ((0, jsx_runtime_1.jsx)("a", { href: link.url, target: "_blank", rel: "noreferrer", style: { color: "#93c5fd" }, children: link.label }, `${link.label}-${link.url}`))) })) : null] })) : null] }));
52
+ }
@@ -0,0 +1,15 @@
1
+ import { type ReactNode } from "react";
2
+ import { type OverlaySelection, type OverlaySubmitHandler, type OverlaySubmitResult, type TriggerKey } from "./overlay-plugin";
3
+ export interface SourceInspectorProps {
4
+ children: ReactNode;
5
+ enabled?: boolean;
6
+ attributeName?: string;
7
+ triggerKey?: TriggerKey;
8
+ onSubmit?: OverlaySubmitHandler;
9
+ onSelectionChange?: (selection: OverlaySelection | null) => void;
10
+ onSubmitStart?: (selection: OverlaySelection) => void;
11
+ onSubmitComplete?: (result: OverlaySubmitResult, selection: OverlaySelection) => void;
12
+ onSubmitError?: (result: OverlaySubmitResult, selection: OverlaySelection) => void;
13
+ }
14
+ export default function SourceInspector({ children, enabled, attributeName, triggerKey, onSubmit, onSelectionChange, onSubmitStart, onSubmitComplete, onSubmitError, }: SourceInspectorProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=SourceInspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SourceInspector.d.ts","sourceRoot":"","sources":["../../src/SourceInspector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AA0B1B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACtD,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACtF,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACpF;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,QAAQ,EACR,OAAO,EACP,aAAsC,EACtC,UAAgC,EAChC,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,aAAa,GACd,EAAE,oBAAoB,2CA+KtB"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.default = SourceInspector;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const overlay_plugin_1 = require("./overlay-plugin");
8
+ const overlay_plugin_provider_1 = require("./overlay-plugin-provider");
9
+ const source_inspector_context_1 = require("./source-inspector-context");
10
+ const submit_handler_1 = require("./submit-handler");
11
+ const DEFAULT_ATTRIBUTE_NAME = "data-src-loc";
12
+ const DEFAULT_TRIGGER_KEY = "alt";
13
+ function isTriggerPressed(event, triggerKey) {
14
+ switch (triggerKey) {
15
+ case "alt":
16
+ return event.altKey;
17
+ case "shift":
18
+ return event.shiftKey;
19
+ case "meta":
20
+ return event.metaKey;
21
+ case "ctrl":
22
+ return event.ctrlKey;
23
+ default:
24
+ return false;
25
+ }
26
+ }
27
+ function SourceInspector({ children, enabled, attributeName = DEFAULT_ATTRIBUTE_NAME, triggerKey = DEFAULT_TRIGGER_KEY, onSubmit, onSelectionChange, onSubmitStart, onSubmitComplete, onSubmitError, }) {
28
+ const inspectorEnabled = typeof enabled === "boolean"
29
+ ? enabled
30
+ : process.env.NEXT_PUBLIC_SOURCE_INSPECTOR === "1";
31
+ const wrapperPlugin = (0, overlay_plugin_provider_1.useOverlayPlugin)();
32
+ const resolvedSubmit = (0, submit_handler_1.resolveSubmitHandler)(wrapperPlugin, onSubmit);
33
+ const [selection, setSelection] = (0, react_1.useState)(null);
34
+ const [selectionWarning, setSelectionWarning] = (0, react_1.useState)("");
35
+ const [proposedText, setProposedTextState] = (0, react_1.useState)("");
36
+ const [submitting, setSubmitting] = (0, react_1.useState)(false);
37
+ const [result, setResult] = (0, react_1.useState)(null);
38
+ const highlightedElement = (0, react_1.useRef)(null);
39
+ (0, react_1.useEffect)(() => {
40
+ onSelectionChange?.(selection);
41
+ }, [onSelectionChange, selection]);
42
+ (0, react_1.useEffect)(() => {
43
+ if (!inspectorEnabled) {
44
+ return;
45
+ }
46
+ const onClick = (event) => {
47
+ if (!isTriggerPressed(event, triggerKey)) {
48
+ return;
49
+ }
50
+ const target = event.target;
51
+ if (!(target instanceof Element)) {
52
+ return;
53
+ }
54
+ const element = target.closest(`[${attributeName}]`);
55
+ if (!element) {
56
+ return;
57
+ }
58
+ const sourceLoc = element.getAttribute(attributeName) || "";
59
+ if (!sourceLoc) {
60
+ return;
61
+ }
62
+ event.preventDefault();
63
+ event.stopPropagation();
64
+ if (highlightedElement.current) {
65
+ highlightedElement.current.style.outline = "";
66
+ }
67
+ element.style.outline = "2px solid #f59e0b";
68
+ highlightedElement.current = element;
69
+ const selectedText = (0, overlay_plugin_1.normalizeOverlayText)(element.textContent || "");
70
+ const tagName = element.tagName.toLowerCase();
71
+ setResult(null);
72
+ if (!selectedText) {
73
+ setSelection(null);
74
+ setProposedTextState("");
75
+ setSelectionWarning("Selected element has no plain text content. Select an element with direct text.");
76
+ return;
77
+ }
78
+ setSelectionWarning("");
79
+ setSelection({
80
+ sourceLoc,
81
+ tagName,
82
+ selectedText,
83
+ });
84
+ setProposedTextState(selectedText);
85
+ };
86
+ window.addEventListener("click", onClick, true);
87
+ return () => {
88
+ window.removeEventListener("click", onClick, true);
89
+ if (highlightedElement.current) {
90
+ highlightedElement.current.style.outline = "";
91
+ }
92
+ };
93
+ }, [attributeName, inspectorEnabled, triggerKey]);
94
+ function setProposedText(value) {
95
+ setProposedTextState(value);
96
+ setResult(null);
97
+ }
98
+ async function submit() {
99
+ if (!selection) {
100
+ setResult({
101
+ ok: false,
102
+ message: "Select an element with direct text first.",
103
+ });
104
+ return;
105
+ }
106
+ const trimmedProposedText = proposedText.trim();
107
+ if (!trimmedProposedText) {
108
+ setResult({
109
+ ok: false,
110
+ message: "Proposed changes cannot be empty.",
111
+ });
112
+ return;
113
+ }
114
+ const submitHandler = resolvedSubmit.submit;
115
+ if (!submitHandler) {
116
+ const missingHandlerResult = {
117
+ ok: false,
118
+ message: "PROVIDER_ERROR: No submit handler configured.",
119
+ };
120
+ setResult(missingHandlerResult);
121
+ onSubmitError?.(missingHandlerResult, selection);
122
+ return;
123
+ }
124
+ setSubmitting(true);
125
+ setResult(null);
126
+ onSubmitStart?.(selection);
127
+ const submitInput = (0, overlay_plugin_1.buildOverlaySubmitInput)(selection, trimmedProposedText);
128
+ try {
129
+ const submitResult = await submitHandler(submitInput, {
130
+ host: window.location.host,
131
+ });
132
+ setResult(submitResult);
133
+ if (submitResult.ok) {
134
+ onSubmitComplete?.(submitResult, selection);
135
+ }
136
+ else {
137
+ onSubmitError?.(submitResult, selection);
138
+ }
139
+ }
140
+ catch (error) {
141
+ const errorResult = (0, overlay_plugin_1.toOverlayErrorResult)(error);
142
+ setResult(errorResult);
143
+ onSubmitError?.(errorResult, selection);
144
+ }
145
+ finally {
146
+ setSubmitting(false);
147
+ }
148
+ }
149
+ const contextValue = (0, react_1.useMemo)(() => ({
150
+ inspectorEnabled,
151
+ triggerKey,
152
+ pluginId: resolvedSubmit.pluginId,
153
+ selection,
154
+ selectionWarning,
155
+ proposedText,
156
+ submitting,
157
+ result,
158
+ setProposedText,
159
+ submit,
160
+ }), [
161
+ inspectorEnabled,
162
+ triggerKey,
163
+ resolvedSubmit.pluginId,
164
+ selection,
165
+ selectionWarning,
166
+ proposedText,
167
+ submitting,
168
+ result,
169
+ ]);
170
+ return (0, jsx_runtime_1.jsx)(source_inspector_context_1.SourceInspectorProvider, { value: contextValue, children: children });
171
+ }
@@ -0,0 +1,15 @@
1
+ import { type SourceInspectorAdapterOptions } from "@deshlo/core";
2
+ export interface SourceInspectorViteOptions extends SourceInspectorAdapterOptions {
3
+ cwd?: string;
4
+ }
5
+ interface ViteLikePlugin {
6
+ name: string;
7
+ enforce?: "pre" | "post";
8
+ transform: (code: string, id: string) => {
9
+ code: string;
10
+ map: unknown;
11
+ } | null;
12
+ }
13
+ export declare function withSourceInspectorVite(options?: SourceInspectorViteOptions): ViteLikePlugin;
14
+ export {};
15
+ //# sourceMappingURL=vite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../../src/adapters/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,6BAA6B,EACnC,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,0BAA2B,SAAQ,6BAA6B;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACzB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CAChF;AAWD,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,0BAA+B,GACvC,cAAc,CA2ChB"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withSourceInspectorVite = withSourceInspectorVite;
4
+ const core_1 = require("@deshlo/core");
5
+ function stripQuery(id) {
6
+ const queryIndex = id.indexOf("?");
7
+ return queryIndex === -1 ? id : id.slice(0, queryIndex);
8
+ }
9
+ function isInIncludedPath(filePath, includes) {
10
+ return includes.some((basePath) => filePath === basePath || filePath.startsWith(`${basePath}/`));
11
+ }
12
+ function withSourceInspectorVite(options = {}) {
13
+ const cwd = options.cwd ?? process.cwd();
14
+ const includePaths = (0, core_1.resolveIncludePaths)(options.include, cwd);
15
+ return {
16
+ name: "source-inspector-vite",
17
+ enforce: "pre",
18
+ transform(code, id) {
19
+ if (!(0, core_1.isSourceInspectorEnabled)(options)) {
20
+ return null;
21
+ }
22
+ const filePath = stripQuery(id);
23
+ if (!/\.[jt]sx?$/.test(filePath)) {
24
+ return null;
25
+ }
26
+ if (filePath.includes("/node_modules/")) {
27
+ return null;
28
+ }
29
+ if (!isInIncludedPath(filePath, includePaths)) {
30
+ return null;
31
+ }
32
+ const result = (0, core_1.injectSourceAttributes)(code, filePath, {
33
+ attributeName: options.attributeName,
34
+ cwd,
35
+ wrapLooseTextNodes: options.wrapLooseTextNodes,
36
+ annotateLeafNodesOnly: options.annotateLeafNodesOnly,
37
+ });
38
+ if (!result.changed) {
39
+ return null;
40
+ }
41
+ return {
42
+ code: result.code,
43
+ map: result.map,
44
+ };
45
+ },
46
+ };
47
+ }
@@ -0,0 +1,5 @@
1
+ import { type SourceInspectorAdapter, type SourceInspectorAdapterOptions, type WebpackLikeConfig } from "@deshlo/core";
2
+ export declare function withSourceInspectorWebpack<TConfig extends WebpackLikeConfig>(webpackConfig: TConfig, options?: SourceInspectorAdapterOptions): TConfig;
3
+ export declare const webpackAdapter: SourceInspectorAdapter<WebpackLikeConfig>;
4
+ export type { SourceInspectorAdapter, SourceInspectorAdapterOptions, WebpackLikeConfig, } from "@deshlo/core";
5
+ //# sourceMappingURL=webpack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webpack.d.ts","sourceRoot":"","sources":["../../../src/adapters/webpack.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,EAClC,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAEtB,wBAAgB,0BAA0B,CAAC,OAAO,SAAS,iBAAiB,EAC1E,aAAa,EAAE,OAAO,EACtB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAMT;AAED,eAAO,MAAM,cAAc,EAAE,sBAAsB,CAAC,iBAAiB,CAGpE,CAAC;AAEF,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webpackAdapter = void 0;
4
+ exports.withSourceInspectorWebpack = withSourceInspectorWebpack;
5
+ const core_1 = require("@deshlo/core");
6
+ function withSourceInspectorWebpack(webpackConfig, options = {}) {
7
+ if (!(0, core_1.isSourceInspectorEnabled)(options)) {
8
+ return webpackConfig;
9
+ }
10
+ return (0, core_1.injectSourceInspectorLoader)(webpackConfig, options);
11
+ }
12
+ exports.webpackAdapter = {
13
+ id: "webpack",
14
+ apply: withSourceInspectorWebpack,
15
+ };
@@ -0,0 +1,3 @@
1
+ export { GithubPlugin, type GithubPluginProps, } from "./plugins/github/GithubPlugin";
2
+ export type { GitHubBrowserPluginConfig } from "@fdb/plugin-github";
3
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/github.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,GACvB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.GithubPlugin = void 0;
5
+ var GithubPlugin_1 = require("./plugins/github/GithubPlugin");
6
+ Object.defineProperty(exports, "GithubPlugin", { enumerable: true, get: function () { return GithubPlugin_1.GithubPlugin; } });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=github.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.test.d.ts","sourceRoot":"","sources":["../../src/github.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const vitest_1 = require("vitest");
5
+ const overlay_1 = require("./overlay");
6
+ const github_1 = require("./github");
7
+ (0, vitest_1.describe)("GithubPlugin", () => {
8
+ (0, vitest_1.it)("wraps children in OverlayPluginProvider", () => {
9
+ const element = (0, github_1.GithubPlugin)({
10
+ config: { token: "ghp_test" },
11
+ children: "child",
12
+ });
13
+ (0, vitest_1.expect)((0, react_1.isValidElement)(element)).toBe(true);
14
+ (0, vitest_1.expect)(element.type).toBe(overlay_1.OverlayPluginProvider);
15
+ (0, vitest_1.expect)(element.props.plugin.id).toBe("github-browser");
16
+ });
17
+ });
@@ -0,0 +1,5 @@
1
+ export { default as OverlayGate } from "./overlay/OverlayGate";
2
+ export type { OverlayGateProps } from "./overlay/OverlayGate";
3
+ export { OverlayPluginProvider, useOverlayPlugin, type OverlayPluginProviderProps, } from "./overlay/overlay-plugin-provider";
4
+ export type { OverlayPlugin, OverlayPluginContext, OverlayResultLink, OverlaySelection, OverlaySubmitHandler, OverlaySubmitInput, OverlaySubmitResult, TriggerKey, } from "./overlay/overlay-plugin";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,0BAA0B,GAChC,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,GACX,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useOverlayPlugin = exports.OverlayPluginProvider = exports.OverlayGate = void 0;
7
+ var OverlayGate_1 = require("./overlay/OverlayGate");
8
+ Object.defineProperty(exports, "OverlayGate", { enumerable: true, get: function () { return __importDefault(OverlayGate_1).default; } });
9
+ var overlay_plugin_provider_1 = require("./overlay/overlay-plugin-provider");
10
+ Object.defineProperty(exports, "OverlayPluginProvider", { enumerable: true, get: function () { return overlay_plugin_provider_1.OverlayPluginProvider; } });
11
+ Object.defineProperty(exports, "useOverlayPlugin", { enumerable: true, get: function () { return overlay_plugin_provider_1.useOverlayPlugin; } });
@@ -0,0 +1,6 @@
1
+ import { type SourceInspectorProps } from "./SourceInspector";
2
+ import { type OverlayGatePanelProps } from "./OverlayGatePanel";
3
+ export interface OverlayGateProps extends Omit<SourceInspectorProps, "children">, OverlayGatePanelProps {
4
+ }
5
+ export default function OverlayGate({ width, ...sourceInspectorProps }: OverlayGateProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=OverlayGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayGate.d.ts","sourceRoot":"","sources":["../../../src/overlay/OverlayGate.tsx"],"names":[],"mappings":"AAEA,OAAwB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAyB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAElF,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,EAC5C,qBAAqB;CAAG;AAE5B,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,oBAAoB,EAAE,EAAE,gBAAgB,2CAMvF"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ "use client";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.default = OverlayGate;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ const SourceInspector_1 = __importDefault(require("./SourceInspector"));
10
+ const OverlayGatePanel_1 = __importDefault(require("./OverlayGatePanel"));
11
+ function OverlayGate({ width, ...sourceInspectorProps }) {
12
+ return ((0, jsx_runtime_1.jsx)(SourceInspector_1.default, { ...sourceInspectorProps, children: (0, jsx_runtime_1.jsx)(OverlayGatePanel_1.default, { width: width }) }));
13
+ }
@@ -0,0 +1,5 @@
1
+ export interface OverlayGatePanelProps {
2
+ width?: number;
3
+ }
4
+ export default function OverlayGatePanel({ width }: OverlayGatePanelProps): import("react/jsx-runtime").JSX.Element | null;
5
+ //# sourceMappingURL=OverlayGatePanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayGatePanel.d.ts","sourceRoot":"","sources":["../../../src/overlay/OverlayGatePanel.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,KAAW,EAAE,EAAE,qBAAqB,kDAmJ9E"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.default = OverlayGatePanel;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const source_inspector_context_1 = require("./source-inspector-context");
7
+ function OverlayGatePanel({ width = 420 }) {
8
+ const { inspectorEnabled, triggerKey, pluginId, selection, selectionWarning, proposedText, submitting, result, setProposedText, submit, } = (0, source_inspector_context_1.useSourceInspectorContext)();
9
+ if (!inspectorEnabled) {
10
+ return null;
11
+ }
12
+ const canSubmit = Boolean(selection && proposedText.trim() && !submitting);
13
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
14
+ position: "fixed",
15
+ right: 12,
16
+ bottom: 12,
17
+ zIndex: 9999,
18
+ width,
19
+ maxHeight: "80vh",
20
+ overflowY: "auto",
21
+ padding: 12,
22
+ borderRadius: 10,
23
+ border: "1px solid #f59e0b",
24
+ background: "rgba(17, 17, 17, 0.96)",
25
+ color: "#f8fafc",
26
+ fontSize: 12,
27
+ lineHeight: 1.45,
28
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 700, marginBottom: 6 }, children: "Source Inspector" }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: ["Hold ", triggerKey.toUpperCase(), " + click to select an element from source."] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: ["Plugin: ", (0, jsx_runtime_1.jsx)("code", { children: pluginId })] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: "Selection" }), selection ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { children: ["Tag: ", (0, jsx_runtime_1.jsx)("code", { children: selection.tagName })] }), (0, jsx_runtime_1.jsxs)("div", { children: ["Source: ", (0, jsx_runtime_1.jsx)("code", { children: selection.sourceLoc })] }), (0, jsx_runtime_1.jsxs)("div", { children: ["Current text: ", (0, jsx_runtime_1.jsx)("code", { children: selection.selectedText })] }), (0, jsx_runtime_1.jsxs)("div", { children: ["Commit: ", (0, jsx_runtime_1.jsx)("code", { children: selection.commitSha || "unknown" })] })] })) : ((0, jsx_runtime_1.jsx)("div", { style: { opacity: 0.85 }, children: "No valid element selected yet." }))] }), selectionWarning ? ((0, jsx_runtime_1.jsx)("div", { style: { marginBottom: 8, color: "#fca5a5" }, children: selectionWarning })) : null, selection ? ((0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 8 }, children: [(0, jsx_runtime_1.jsx)("label", { style: { display: "block", marginBottom: 4, fontWeight: 600 }, children: "Proposed changes" }), (0, jsx_runtime_1.jsx)("textarea", { value: proposedText, onChange: (event) => {
29
+ setProposedText(event.target.value);
30
+ }, rows: 4, style: {
31
+ width: "100%",
32
+ resize: "vertical",
33
+ padding: 8,
34
+ borderRadius: 6,
35
+ border: "1px solid #334155",
36
+ fontFamily: "inherit",
37
+ fontSize: 12,
38
+ } })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: { display: "flex", gap: 8, marginBottom: 10 }, children: (0, jsx_runtime_1.jsx)("button", { onClick: submit, disabled: !canSubmit, style: {
39
+ flex: 1,
40
+ padding: "8px 10px",
41
+ borderRadius: 6,
42
+ border: "1px solid #22c55e",
43
+ background: canSubmit ? "#22c55e" : "#475569",
44
+ color: "#111827",
45
+ fontWeight: 600,
46
+ cursor: canSubmit ? "pointer" : "not-allowed",
47
+ }, children: submitting ? "Submitting..." : "Submit changes" }) }), result ? ((0, jsx_runtime_1.jsxs)("div", { style: {
48
+ borderTop: "1px solid #334155",
49
+ paddingTop: 8,
50
+ color: result.ok ? "#86efac" : "#fca5a5",
51
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 700, marginBottom: 4 }, children: result.ok ? "Success" : "Error" }), (0, jsx_runtime_1.jsx)("div", { children: result.message }), result.links && result.links.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { style: { marginTop: 6, display: "flex", flexDirection: "column", gap: 4 }, children: result.links.map((link) => ((0, jsx_runtime_1.jsx)("a", { href: link.url, target: "_blank", rel: "noreferrer", style: { color: "#93c5fd" }, children: link.label }, `${link.label}-${link.url}`))) })) : null] })) : null] }));
52
+ }
@@ -0,0 +1,15 @@
1
+ import { type ReactNode } from "react";
2
+ import { type OverlaySelection, type OverlaySubmitHandler, type OverlaySubmitResult, type TriggerKey } from "./overlay-plugin";
3
+ export interface SourceInspectorProps {
4
+ children: ReactNode;
5
+ enabled?: boolean;
6
+ attributeName?: string;
7
+ triggerKey?: TriggerKey;
8
+ onSubmit?: OverlaySubmitHandler;
9
+ onSelectionChange?: (selection: OverlaySelection | null) => void;
10
+ onSubmitStart?: (selection: OverlaySelection) => void;
11
+ onSubmitComplete?: (result: OverlaySubmitResult, selection: OverlaySelection) => void;
12
+ onSubmitError?: (result: OverlaySubmitResult, selection: OverlaySelection) => void;
13
+ }
14
+ export default function SourceInspector({ children, enabled, attributeName, triggerKey, onSubmit, onSelectionChange, onSubmitStart, onSubmitComplete, onSubmitError, }: SourceInspectorProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=SourceInspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SourceInspector.d.ts","sourceRoot":"","sources":["../../../src/overlay/SourceInspector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AA2B1B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACtD,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACtF,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACpF;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,QAAQ,EACR,OAAO,EACP,aAAsC,EACtC,UAAgC,EAChC,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,aAAa,GACd,EAAE,oBAAoB,2CAiLtB"}