nudge-ui 0.2.3 → 0.2.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.
- package/dist/cli/agentCommand.js +4 -28
- package/dist/client.mjs +870 -212
- package/dist/hosts/next/wrapper.js +1 -7
- package/dist/hosts/projectBridge.js +3 -17
- package/dist/inspector/agent/McpConnectionDialog.js +7 -3
- package/dist/inspector/agent/activity.d.ts +1 -1
- package/dist/inspector/agent/activity.js +3 -2
- package/dist/inspector/agent/client.d.ts +2 -2
- package/dist/inspector/agent/client.js +28 -29
- package/dist/inspector/agent/connectionStatus.d.ts +3 -1
- package/dist/inspector/agent/connectionStatus.js +25 -0
- package/dist/inspector/agent/httpTransport.js +31 -147
- package/dist/inspector/agent/protocol.d.ts +1 -1
- package/dist/inspector/agent/protocol.js +1 -1
- package/dist/inspector/agent/verification.d.ts +5 -7
- package/dist/inspector/agent/verification.js +67 -20
- package/dist/inspector/boot.d.ts +3 -0
- package/dist/inspector/boot.js +297 -0
- package/dist/inspector/canvas/AgentActivityOverlay.d.ts +2 -1
- package/dist/inspector/canvas/AgentActivityOverlay.js +6 -3
- package/dist/inspector/canvas/CanvasCard.js +23 -12
- package/dist/inspector/canvas/CanvasElementOverlay.js +97 -128
- package/dist/inspector/canvas/CanvasToolbar.js +2 -1
- package/dist/inspector/canvas/CanvasWorkspace.js +119 -162
- package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
- package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
- package/dist/inspector/canvas/PageCard.d.ts +10 -0
- package/dist/inspector/canvas/PageCard.js +51 -0
- package/dist/inspector/canvas/SketchToolOptions.d.ts +5 -0
- package/dist/inspector/canvas/SketchToolOptions.js +86 -0
- package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
- package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
- package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +21 -0
- package/dist/inspector/canvas/ToolOptionsDrawer.js +77 -0
- package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -2
- package/dist/inspector/canvas/assets/eraser.svg +28 -0
- package/dist/inspector/canvas/assets/pen.svg +25 -0
- package/dist/inspector/canvas/canvasFrame.d.ts +16 -0
- package/dist/inspector/canvas/canvasFrame.js +10 -0
- package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
- package/dist/inspector/canvas/canvasGestures.js +0 -6
- package/dist/inspector/canvas/canvasStore.d.ts +6 -0
- package/dist/inspector/canvas/canvasStore.js +36 -1
- package/dist/inspector/canvas/frameConnection.d.ts +48 -0
- package/dist/inspector/canvas/frameConnection.js +73 -0
- package/dist/inspector/canvas/frameProtocol.d.ts +18 -1
- package/dist/inspector/canvas/frameProtocol.js +36 -0
- package/dist/inspector/canvas/frameScrollbarStyles.d.ts +3 -0
- package/dist/inspector/canvas/frameScrollbarStyles.js +21 -0
- package/dist/inspector/canvas/pageSurface.d.ts +11 -0
- package/dist/inspector/canvas/pageSurface.js +34 -0
- package/dist/inspector/canvas/projection.d.ts +19 -9
- package/dist/inspector/canvas/projection.js +58 -31
- package/dist/inspector/canvas/rendererBootstrap.js +4 -1
- package/dist/inspector/canvas/rendererElementSelector.js +9 -1
- package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
- package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
- package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
- package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
- package/dist/inspector/canvas/rendererStylesheet.js +15 -0
- package/dist/inspector/canvas/sessionStore.d.ts +2 -2
- package/dist/inspector/canvas/sessionStore.js +12 -9
- package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
- package/dist/inspector/canvas/staleChangeDetector.js +10 -22
- package/dist/inspector/changes/codecs.d.ts +2 -0
- package/dist/inspector/changes/codecs.js +27 -3
- package/dist/inspector/changes/draftPreview.d.ts +12 -0
- package/dist/inspector/changes/draftPreview.js +133 -0
- package/dist/inspector/changes/editModel.d.ts +18 -0
- package/dist/inspector/changes/editModel.js +16 -3
- package/dist/inspector/changes/managedStyleProjection.js +2 -1
- package/dist/inspector/changes/previewDiagnostics.js +1 -1
- package/dist/inspector/changes/types.d.ts +18 -1
- package/dist/inspector/comments/CommentsOverlay.js +18 -16
- package/dist/inspector/comments/element.js +10 -3
- package/dist/inspector/comments/store.js +3 -2
- package/dist/inspector/comments/verification.js +1 -1
- package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
- package/dist/inspector/componentSemantics/adapterRegistry.d.ts +6 -1
- package/dist/inspector/componentSemantics/adapterRegistry.js +23 -1
- package/dist/inspector/componentSemantics/changeAction.js +1 -1
- package/dist/inspector/componentSemantics/reactRuntime.d.ts +2 -1
- package/dist/inspector/componentSemantics/reactRuntime.js +38 -0
- package/dist/inspector/componentSemantics/runtimeBridge.d.ts +4 -2
- package/dist/inspector/componentSemantics/runtimeBridge.js +17 -0
- package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
- package/dist/inspector/componentSemantics/textBinding.js +4 -45
- package/dist/inspector/componentSemantics/types.d.ts +11 -0
- package/dist/inspector/drafts/draftStore.d.ts +109 -0
- package/dist/inspector/drafts/draftStore.js +451 -0
- package/dist/inspector/drafts/model.d.ts +9 -1
- package/dist/inspector/drafts/model.js +5 -1
- package/dist/inspector/drafts/store.d.ts +53 -15
- package/dist/inspector/drafts/store.js +143 -169
- package/dist/inspector/index.d.ts +2 -4
- package/dist/inspector/index.js +2 -264
- package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
- package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
- package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
- package/dist/inspector/inspection/bridge.d.ts +1 -1
- package/dist/inspector/inspection/bridge.js +2 -1
- package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
- package/dist/inspector/inspection/browserCssInspection.js +28 -6
- package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
- package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
- package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
- package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
- package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
- package/dist/inspector/iterations/capture.d.ts +2 -1
- package/dist/inspector/iterations/capture.js +2 -1
- package/dist/inspector/iterations/client.d.ts +2 -1
- package/dist/inspector/iterations/coordinator.d.ts +4 -3
- package/dist/inspector/iterations/coordinator.js +5 -3
- package/dist/inspector/iterations/prompt.js +9 -8
- package/dist/inspector/overlay/interactionStyles.js +17 -0
- package/dist/inspector/pageInspector.d.ts +42 -0
- package/dist/inspector/pageInspector.js +342 -0
- package/dist/inspector/projection/draftProjection.d.ts +10 -2
- package/dist/inspector/projection/draftProjection.js +9 -1
- package/dist/inspector/projection/managedStylesheet.js +24 -4
- package/dist/inspector/projection/renderedInstance.d.ts +15 -2
- package/dist/inspector/projection/renderedInstance.js +60 -7
- package/dist/inspector/projection/structuralProjection.d.ts +0 -9
- package/dist/inspector/projection/structuralProjection.js +16 -46
- package/dist/inspector/projection/textProjection.d.ts +8 -2
- package/dist/inspector/projection/textProjection.js +77 -24
- package/dist/inspector/prompt/clipboardHandoff.d.ts +14 -0
- package/dist/inspector/prompt/clipboardHandoff.js +47 -16
- package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
- package/dist/inspector/prompt/generatePrompt.js +248 -148
- package/dist/inspector/prompt/promptDocument.d.ts +3 -0
- package/dist/inspector/prompt/promptDocument.js +8 -0
- package/dist/inspector/prompt/promptSettings.js +7 -5
- package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
- package/dist/inspector/runtime/inspectorStorage.js +42 -0
- package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
- package/dist/inspector/runtime/ownedStylesheets.js +72 -0
- package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
- package/dist/inspector/runtime/runtimeConfig.js +10 -1
- package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
- package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
- package/dist/inspector/selection/editScope.d.ts +1 -0
- package/dist/inspector/selection/editScope.js +13 -2
- package/dist/inspector/selection/sourceSite.d.ts +12 -0
- package/dist/inspector/selection/sourceSite.js +28 -0
- package/dist/inspector/shell/AgentStatusButton.js +2 -2
- package/dist/inspector/shell/AppShell.js +6 -2
- package/dist/inspector/shell/ChangesLog.js +27 -9
- package/dist/inspector/shell/CopyPromptButton.js +74 -26
- package/dist/inspector/shell/EmptyState.js +3 -3
- package/dist/inspector/shell/InspectorShell.d.ts +0 -3
- package/dist/inspector/shell/InspectorShell.js +21 -13
- package/dist/inspector/shell/PeekOriginalButton.js +3 -3
- package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
- package/dist/inspector/shell/interactionStatePreview.js +112 -0
- package/dist/inspector/shell/originalPreview.d.ts +3 -2
- package/dist/inspector/shell/originalPreview.js +10 -37
- package/dist/inspector/shell/stateValue.js +2 -3
- package/dist/inspector/sketch/SketchEditor.js +5 -4
- package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
- package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
- package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
- package/dist/inspector/sketch/SketchOverlay.js +139 -263
- package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
- package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
- package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
- package/dist/inspector/sketch/SketchThumbnail.js +18 -0
- package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
- package/dist/inspector/sketch/SketchWorkspace.js +69 -34
- package/dist/inspector/sketch/capture.js +19 -3
- package/dist/inspector/sketch/copySketch.d.ts +10 -0
- package/dist/inspector/sketch/copySketch.js +52 -0
- package/dist/inspector/sketch/drawingTools.d.ts +17 -0
- package/dist/inspector/sketch/drawingTools.js +47 -0
- package/dist/inspector/sketch/frameHeading.d.ts +9 -0
- package/dist/inspector/sketch/frameHeading.js +30 -0
- package/dist/inspector/sketch/freehand.js +3 -3
- package/dist/inspector/sketch/geometry.d.ts +6 -0
- package/dist/inspector/sketch/geometry.js +19 -0
- package/dist/inspector/sketch/history.d.ts +30 -0
- package/dist/inspector/sketch/history.js +58 -0
- package/dist/inspector/sketch/interaction.d.ts +1 -3
- package/dist/inspector/sketch/interaction.js +6 -9
- package/dist/inspector/sketch/model.d.ts +35 -1
- package/dist/inspector/sketch/model.js +116 -61
- package/dist/inspector/sketch/persistence.d.ts +14 -0
- package/dist/inspector/sketch/persistence.js +63 -7
- package/dist/inspector/sketch/raster.d.ts +6 -2
- package/dist/inspector/sketch/raster.js +43 -17
- package/dist/inspector/sketch/store.d.ts +1 -1
- package/dist/inspector/sketch/store.js +1 -1
- package/dist/inspector/sketch/videoFrames.d.ts +6 -0
- package/dist/inspector/sketch/videoFrames.js +81 -0
- package/dist/inspector/styleEditors/BackgroundEditor.js +3 -2
- package/dist/inspector/styleEditors/BorderEditor.js +30 -130
- package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
- package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
- package/dist/inspector/styleEditors/LayoutSection.js +2 -2
- package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
- package/dist/inspector/styleEditors/borderModel.js +114 -0
- package/dist/inspector/styleEditors/layoutValue.js +2 -3
- package/dist/inspector/tokens/TokenField.js +40 -7
- package/dist/inspector/tokens/TokensPanel.js +2 -1
- package/dist/inspector/tokens/editActions.d.ts +3 -3
- package/dist/inspector/tokens/editActions.js +15 -3
- package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
- package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
- package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
- package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
- package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
- package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
- package/dist/inspector/tokens/resolution.d.ts +6 -3
- package/dist/inspector/tokens/resolution.js +91 -112
- package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
- package/dist/inspector/tokens/tokenEdits.js +1 -1
- package/dist/inspector/ui/InlineStyleWarning.js +2 -2
- package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
- package/dist/inspector/ui/InspectorStyle.js +26 -0
- package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
- package/dist/inspector/ui/PopoverListbox.js +3 -3
- package/dist/inspector/ui/Toast.d.ts +14 -0
- package/dist/inspector/ui/Toast.js +30 -0
- package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
- package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
- package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
- package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
- package/dist/inspector/ui/customCursors.d.ts +5 -0
- package/dist/inspector/ui/customCursors.js +32 -6
- package/dist/inspector/ui/styles.js +12 -10
- package/dist/inspector/workspace/commands.js +1 -2
- package/dist/inspector/workspace/controller.js +1 -2
- package/dist/inspector/workspace/handoff.js +3 -2
- package/dist/inspector/workspace/sentItems.d.ts +16 -0
- package/dist/inspector/workspace/sentItems.js +33 -0
- package/dist/inspector/workspace/timeline.d.ts +24 -10
- package/dist/inspector/workspace/timeline.js +118 -96
- package/dist/internal/agent-protocol.d.ts +50 -13
- package/dist/internal/agent-protocol.js +145 -19
- package/dist/nudge-ui.mjs +81 -65
- package/dist/project/mcpPackage.d.ts +8 -0
- package/dist/project/mcpPackage.js +60 -0
- package/package.json +13 -3
- package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
- package/dist/inspector/canvas/measurementProjection.js +0 -16
- package/dist/inspector/changes/changesLog.d.ts +0 -47
- package/dist/inspector/changes/changesLog.js +0 -247
- package/dist/inspector/changes/draftChanges.d.ts +0 -56
- package/dist/inspector/changes/draftChanges.js +0 -300
- package/dist/inspector/conformance/projection.d.ts +0 -2
- package/dist/inspector/conformance/projection.js +0 -3
- package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
- package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
- package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
- package/dist/inspector/overlay/InspectorOverlay.js +0 -332
- package/dist/inspector/overlay/elementSelector.d.ts +0 -1
- package/dist/inspector/overlay/elementSelector.js +0 -111
- package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
- package/dist/inspector/sketch/SketchChanges.js +0 -72
- package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
- package/dist/inspector/sketch/SketchEntryButton.js +0 -11
- package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
- package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { inspectorStorage } from "../runtime/inspectorStorage.js";
|
|
1
2
|
import { useSyncExternalStore } from "react";
|
|
2
3
|
import { isRenderedInstanceRef } from "../changes/editModel.js";
|
|
3
4
|
import { useCanvasCards, useFocusedCardId, useSelectedCardId } from "../canvas/canvasStore.js";
|
|
@@ -29,7 +30,7 @@ export function getComments() {
|
|
|
29
30
|
loadedKey = key;
|
|
30
31
|
loadedDemo = demo;
|
|
31
32
|
try {
|
|
32
|
-
const saved = demo ? [] : JSON.parse(
|
|
33
|
+
const saved = demo ? [] : JSON.parse(inspectorStorage()?.getItem(key) ?? "[]");
|
|
33
34
|
comments = Array.isArray(saved) ? saved.filter(isComment) : [];
|
|
34
35
|
}
|
|
35
36
|
catch {
|
|
@@ -51,7 +52,7 @@ function publish(next) {
|
|
|
51
52
|
comments = next;
|
|
52
53
|
if (getNudgeUiRuntimeConfig().demo !== true) {
|
|
53
54
|
try {
|
|
54
|
-
|
|
55
|
+
inspectorStorage()?.setItem(storageKey(), JSON.stringify(next));
|
|
55
56
|
}
|
|
56
57
|
catch { }
|
|
57
58
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getDraftChanges } from "../
|
|
1
|
+
import { getDraftChanges } from "../drafts/store.js";
|
|
2
2
|
import { documentTarget, targetKey } from "../drafts/model.js";
|
|
3
3
|
import { isCanvasProjectionRevisionCurrent, projectDraftToDocument } from "../canvas/projection.js";
|
|
4
4
|
import { commentFingerprint, commentViewport, resolveCommentElement } from "./element.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { isComponentChange
|
|
2
|
+
import { isComponentChange } from "../changes/types.js";
|
|
3
|
+
import { useChanges } from "../drafts/store.js";
|
|
3
4
|
import { FieldRow } from "../ui/FieldRow.js";
|
|
4
5
|
import { Select } from "../ui/Select.js";
|
|
5
6
|
import { SegmentedControl } from "../ui/SegmentedControl.js";
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type { ComponentOverride, ComponentRuntimeAdapter, EditableComponentTarget, RuntimeComponentTarget } from "./types.js";
|
|
1
|
+
import type { ComponentOverride, ComponentRootInvocation, ComponentRuntimeAdapter, EditableComponentTarget, RuntimeComponentTarget } from "./types.js";
|
|
2
2
|
/** Register a framework adapter without coupling semantic resolution to React. */
|
|
3
3
|
export declare function registerComponentRuntimeAdapter(adapter: ComponentRuntimeAdapter): () => void;
|
|
4
4
|
export declare function inspectComponentTargets(element: HTMLElement): RuntimeComponentTarget[];
|
|
5
|
+
/**
|
|
6
|
+
* Returns the invocations, nearest first, whose entire rendered output is this
|
|
7
|
+
* element. Null means no enabled runtime could read the element's ancestry.
|
|
8
|
+
*/
|
|
9
|
+
export declare function inspectRootInvocations(element: HTMLElement): ComponentRootInvocation[] | null;
|
|
5
10
|
/**
|
|
6
11
|
* Resolve multiplicity through the owning runtime Adapter. The inspector does
|
|
7
12
|
* not infer it from DOM order or retain a React fiber as durable identity.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
|
|
2
|
-
import { copyComponentOverrides, copyRuntimeTarget, getHostRuntimeAdapters, registerHostRuntimeAdapter, replaceHostRuntimeAdapterOverrides, } from "./runtimeBridge.js";
|
|
2
|
+
import { copyComponentOverrides, copyRootInvocations, copyRuntimeTarget, getHostRuntimeAdapters, registerHostRuntimeAdapter, replaceHostRuntimeAdapterOverrides, } from "./runtimeBridge.js";
|
|
3
3
|
const diagnosedAdapters = new WeakSet();
|
|
4
4
|
function enabledRuntimeAdapters(ownerGlobal) {
|
|
5
5
|
if (!getNudgeUiRuntimeConfig().capabilities.componentSemantics)
|
|
@@ -42,6 +42,28 @@ export function inspectComponentTargets(element) {
|
|
|
42
42
|
}
|
|
43
43
|
return targets;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns the invocations, nearest first, whose entire rendered output is this
|
|
47
|
+
* element. Null means no enabled runtime could read the element's ancestry.
|
|
48
|
+
*/
|
|
49
|
+
export function inspectRootInvocations(element) {
|
|
50
|
+
let invocations = null;
|
|
51
|
+
const ownerGlobal = element.ownerDocument.defaultView ?? globalThis;
|
|
52
|
+
for (const adapter of enabledRuntimeAdapters(ownerGlobal)) {
|
|
53
|
+
if (!adapter.rootInvocations)
|
|
54
|
+
continue;
|
|
55
|
+
try {
|
|
56
|
+
const inspected = adapter.rootInvocations(element);
|
|
57
|
+
if (inspected === null || inspected === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
invocations = [...(invocations ?? []), ...copyRootInvocations(inspected)];
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
diagnoseAdapter(adapter, error instanceof Error ? error.message : String(error));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return invocations;
|
|
66
|
+
}
|
|
45
67
|
function diagnoseAdapter(adapter, detail) {
|
|
46
68
|
if (diagnosedAdapters.has(adapter))
|
|
47
69
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { appendChange } from "../
|
|
1
|
+
import { appendChange } from "../drafts/store.js";
|
|
2
2
|
import { createComponentPropChange } from "./changeModel.js";
|
|
3
3
|
export { createComponentPropChange } from "./changeModel.js";
|
|
4
4
|
export function setComponentProp(target, prop, value) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type ReactElement } from "react";
|
|
2
|
-
import type { ComponentInvocationMeta, ComponentOverride, ComponentRuntimeAdapter, RuntimeComponentTarget } from "./types.js";
|
|
2
|
+
import type { ComponentInvocationMeta, ComponentOverride, ComponentRootInvocation, ComponentRuntimeAdapter, RuntimeComponentTarget } from "./types.js";
|
|
3
3
|
/** Returns null when this runtime has no mounted boundary for the callsite. */
|
|
4
4
|
export declare function getReactCallsiteMultiplicity(callsiteId: string): number | null;
|
|
5
5
|
/** Test/runtime teardown hook; canonical changes never depend on this state. */
|
|
6
6
|
export declare function resetReactComponentRuntime(): void;
|
|
7
7
|
export declare function instrumentReactComponent(element: ReactElement<Record<string, unknown>>, meta: ComponentInvocationMeta): ReactElement;
|
|
8
8
|
export declare function inspectReactComponentTargets(element: HTMLElement): RuntimeComponentTarget[];
|
|
9
|
+
export declare function inspectReactRootInvocations(element: HTMLElement): ComponentRootInvocation[] | null;
|
|
9
10
|
export declare function replaceReactComponentOverrides(overrides: ComponentOverride[]): void;
|
|
10
11
|
export declare const reactComponentRuntimeAdapter: ComponentRuntimeAdapter;
|
|
@@ -4,6 +4,9 @@ import { getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
|
|
|
4
4
|
const BOUNDARY_MARKER = Symbol.for("nudge-ui.react-component-boundary");
|
|
5
5
|
const EMPTY_OVERRIDE = Object.freeze({});
|
|
6
6
|
const REACT_MAJOR_VERSION = Number.parseInt(reactVersion, 10);
|
|
7
|
+
/** React work tags for host output that has no string element type. */
|
|
8
|
+
const HOST_PORTAL_TAG = 4;
|
|
9
|
+
const HOST_TEXT_TAG = 6;
|
|
7
10
|
let overridesByCallsite = new Map();
|
|
8
11
|
const listeners = new Set();
|
|
9
12
|
/**
|
|
@@ -161,6 +164,40 @@ export function inspectReactComponentTargets(element) {
|
|
|
161
164
|
}
|
|
162
165
|
return targets;
|
|
163
166
|
}
|
|
167
|
+
function isHostOutput(fiber) {
|
|
168
|
+
return typeof fiber.type === "string" || fiber.tag === HOST_TEXT_TAG || fiber.tag === HOST_PORTAL_TAG;
|
|
169
|
+
}
|
|
170
|
+
/** Counts top-level host outputs below a fiber, stopping once there are two. */
|
|
171
|
+
function hostOutputCount(fiber) {
|
|
172
|
+
let count = 0;
|
|
173
|
+
const visit = (parent) => {
|
|
174
|
+
for (let child = parent.child ?? null; child && count < 2; child = child.sibling ?? null) {
|
|
175
|
+
if (isHostOutput(child))
|
|
176
|
+
count += 1;
|
|
177
|
+
else
|
|
178
|
+
visit(child);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
visit(fiber);
|
|
182
|
+
return count;
|
|
183
|
+
}
|
|
184
|
+
export function inspectReactRootInvocations(element) {
|
|
185
|
+
if (!getNudgeUiRuntimeConfig().capabilities.componentSemantics)
|
|
186
|
+
return null;
|
|
187
|
+
const host = findFiber(element);
|
|
188
|
+
if (!host)
|
|
189
|
+
return null;
|
|
190
|
+
const invocations = [];
|
|
191
|
+
for (let fiber = host.return ?? null; fiber && !isHostOutput(fiber); fiber = fiber.return ?? null) {
|
|
192
|
+
if (!isBoundaryType(fiber.type) || !fiber.memoizedProps?.meta)
|
|
193
|
+
continue;
|
|
194
|
+
if (hostOutputCount(fiber) !== 1)
|
|
195
|
+
break;
|
|
196
|
+
const { callsiteId, componentName } = fiber.memoizedProps.meta;
|
|
197
|
+
invocations.push({ callsiteId, componentName });
|
|
198
|
+
}
|
|
199
|
+
return invocations;
|
|
200
|
+
}
|
|
164
201
|
export function replaceReactComponentOverrides(overrides) {
|
|
165
202
|
if (!getNudgeUiRuntimeConfig().capabilities.componentSemantics)
|
|
166
203
|
return;
|
|
@@ -182,5 +219,6 @@ export const reactComponentRuntimeAdapter = {
|
|
|
182
219
|
inspect: inspectReactComponentTargets,
|
|
183
220
|
replaceOverrides: replaceReactComponentOverrides,
|
|
184
221
|
getCallsiteMultiplicity: getReactCallsiteMultiplicity,
|
|
222
|
+
rootInvocations: inspectReactRootInvocations,
|
|
185
223
|
};
|
|
186
224
|
registerHostRuntimeAdapter(reactComponentRuntimeAdapter);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ComponentOverride, ComponentRuntimeAdapter, RuntimeComponentTarget } from "./types.js";
|
|
2
|
-
export type { ComponentFramework, ComponentInvocationMeta, ComponentOverride, ComponentRuntimeAdapter, RuntimeComponentTarget, } from "./types.js";
|
|
1
|
+
import type { ComponentOverride, ComponentRootInvocation, ComponentRuntimeAdapter, RuntimeComponentTarget } from "./types.js";
|
|
2
|
+
export type { ComponentFramework, ComponentInvocationMeta, ComponentOverride, ComponentRootInvocation, ComponentRuntimeAdapter, RuntimeComponentTarget, } from "./types.js";
|
|
3
3
|
/** Version of the page-global host runtime Adapter Interface. */
|
|
4
4
|
export declare const NUDGE_UI_HOST_RUNTIME_VERSION = 1;
|
|
5
5
|
/**
|
|
@@ -21,5 +21,7 @@ export declare function replaceHostRuntimeAdapterOverrides(overrides: readonly C
|
|
|
21
21
|
* the host/client seam.
|
|
22
22
|
*/
|
|
23
23
|
export declare function copyRuntimeTarget(target: RuntimeComponentTarget): RuntimeComponentTarget;
|
|
24
|
+
/** Copies a host Adapter's root invocations into plain protocol data. */
|
|
25
|
+
export declare function copyRootInvocations(invocations: readonly ComponentRootInvocation[]): ComponentRootInvocation[];
|
|
24
26
|
/** Copies override commands before dispatching them into a host Adapter. */
|
|
25
27
|
export declare function copyComponentOverrides(overrides: readonly ComponentOverride[]): ComponentOverride[];
|
|
@@ -104,6 +104,23 @@ export function copyRuntimeTarget(target) {
|
|
|
104
104
|
...(target.mountedCount === undefined ? {} : { mountedCount: target.mountedCount }),
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
+
/** Copies a host Adapter's root invocations into plain protocol data. */
|
|
108
|
+
export function copyRootInvocations(invocations) {
|
|
109
|
+
if (!Array.isArray(invocations)) {
|
|
110
|
+
throw new TypeError("Nudge UI received invalid root invocations from a host Adapter.");
|
|
111
|
+
}
|
|
112
|
+
return invocations.map((invocation) => {
|
|
113
|
+
if (invocation === null
|
|
114
|
+
|| typeof invocation !== "object"
|
|
115
|
+
|| typeof invocation.callsiteId !== "string"
|
|
116
|
+
|| invocation.callsiteId.length === 0
|
|
117
|
+
|| typeof invocation.componentName !== "string"
|
|
118
|
+
|| invocation.componentName.length === 0) {
|
|
119
|
+
throw new TypeError("Nudge UI received an invalid root invocation from a host Adapter.");
|
|
120
|
+
}
|
|
121
|
+
return { callsiteId: invocation.callsiteId, componentName: invocation.componentName };
|
|
122
|
+
});
|
|
123
|
+
}
|
|
107
124
|
/** Copies override commands before dispatching them into a host Adapter. */
|
|
108
125
|
export function copyComponentOverrides(overrides) {
|
|
109
126
|
return overrides.map((override) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ComponentChangeTarget, EditableComponentTarget } from "./types.js";
|
|
2
|
-
import type { TextProjectionTarget } from "../
|
|
3
|
-
import type { TextBindingEvidence, TextProjectionScope } from "../inline-text/textChangeBoundary.js";
|
|
2
|
+
import type { TextBindingEvidence, TextProjectionScope, TextProjectionTarget } from "../changes/editModel.js";
|
|
4
3
|
/** The order used when more than one visible prop has the same value. */
|
|
5
4
|
export declare const VISIBLE_TEXT_PROP_PRIORITY: readonly ["children", "label", "text", "caption", "description", "title"];
|
|
6
5
|
export type TextEditRejectionReason = "no-text" | "no-binding" | "ambiguous-binding" | "editing-active" | "unsafe-target";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { callsiteMultiplicity, editableComponentTargets, inspectComponentTargets, } from "./adapterRegistry.js";
|
|
2
|
-
import { captureTextProjectionTarget, resolveTextProjectionTextNode, textProjectionSelector, } from "../projection/textProjection.js";
|
|
2
|
+
import { captureTextProjectionTarget, hasSafeMixedDescendants, isInApplicationEditingHost, isUnsafeTextHost, resolveTextProjectionTextNode, textProjectionSelector, } from "../projection/textProjection.js";
|
|
3
3
|
/** The order used when more than one visible prop has the same value. */
|
|
4
4
|
export const VISIBLE_TEXT_PROP_PRIORITY = [
|
|
5
5
|
"children",
|
|
@@ -17,24 +17,6 @@ const STRUCTURAL_TEXT_PROPS = new Set([
|
|
|
17
17
|
"role",
|
|
18
18
|
"style",
|
|
19
19
|
]);
|
|
20
|
-
const UNSAFE_TEXT_TAGS = new Set(["SCRIPT", "STYLE", "TEXTAREA", "OPTION"]);
|
|
21
|
-
const UNSAFE_MIXED_DESCENDANT_TAGS = new Set([
|
|
22
|
-
...UNSAFE_TEXT_TAGS,
|
|
23
|
-
"INPUT",
|
|
24
|
-
"SELECT",
|
|
25
|
-
"BUTTON",
|
|
26
|
-
"A",
|
|
27
|
-
"B",
|
|
28
|
-
"STRONG",
|
|
29
|
-
"I",
|
|
30
|
-
"EM",
|
|
31
|
-
"U",
|
|
32
|
-
"MARK",
|
|
33
|
-
"CODE",
|
|
34
|
-
"S",
|
|
35
|
-
"DEL",
|
|
36
|
-
"INS",
|
|
37
|
-
]);
|
|
38
20
|
function isStructuralTextProp(name) {
|
|
39
21
|
return STRUCTURAL_TEXT_PROPS.has(name)
|
|
40
22
|
|| name.startsWith("data")
|
|
@@ -62,9 +44,6 @@ function isApplicationEditingTextNode(element, textNode) {
|
|
|
62
44
|
&& editingHost.getAttribute("contenteditable") !== "false"
|
|
63
45
|
&& (editingHost === element || element.contains(editingHost) || editingHost.contains(element));
|
|
64
46
|
}
|
|
65
|
-
function isUnsafeSemanticHost(element) {
|
|
66
|
-
return UNSAFE_TEXT_TAGS.has(element.tagName);
|
|
67
|
-
}
|
|
68
47
|
function isVisibleTextProp(name) {
|
|
69
48
|
return VISIBLE_TEXT_PROP_PRIORITY.some((candidate) => candidate === name);
|
|
70
49
|
}
|
|
@@ -107,33 +86,13 @@ function textNodesFor(element) {
|
|
|
107
86
|
return nodes;
|
|
108
87
|
}
|
|
109
88
|
function isSafeRenderedTextHost(element, textNode) {
|
|
110
|
-
if (
|
|
111
|
-
return false;
|
|
112
|
-
const editingHost = element.closest("[contenteditable]");
|
|
113
|
-
if (editingHost
|
|
114
|
-
&& editingHost.getAttribute("data-inline-editor") !== "true"
|
|
115
|
-
&& editingHost.getAttribute("contenteditable") !== "false")
|
|
89
|
+
if (isUnsafeTextHost(element) || isInApplicationEditingHost(element))
|
|
116
90
|
return false;
|
|
117
91
|
if (element.children.length === 0) {
|
|
118
92
|
const directTextNodes = Array.from(element.childNodes).filter((node) => node.nodeType === 3);
|
|
119
93
|
return directTextNodes.length === 1 && directTextNodes[0] === textNode;
|
|
120
94
|
}
|
|
121
|
-
|
|
122
|
-
return false;
|
|
123
|
-
// A line break is layout structure, not rich text content. When the exact
|
|
124
|
-
// text node is captured, wrapping that node leaves the <br> in place and
|
|
125
|
-
// preserves both lines. Other inline formatting remains rejected because
|
|
126
|
-
// replacing text inside it would silently flatten authored markup.
|
|
127
|
-
for (const descendant of Array.from(element.querySelectorAll("*"))) {
|
|
128
|
-
if (UNSAFE_MIXED_DESCENDANT_TAGS.has(descendant.tagName))
|
|
129
|
-
return false;
|
|
130
|
-
const descendantEditingHost = descendant.closest("[contenteditable]");
|
|
131
|
-
if (descendantEditingHost
|
|
132
|
-
&& descendantEditingHost.getAttribute("data-inline-editor") !== "true"
|
|
133
|
-
&& descendantEditingHost.getAttribute("contenteditable") !== "false")
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
return true;
|
|
95
|
+
return element.contains(textNode) && hasSafeMixedDescendants(element);
|
|
137
96
|
}
|
|
138
97
|
function textNodeAtPoint(element, point) {
|
|
139
98
|
const nodes = textNodesFor(element);
|
|
@@ -383,7 +342,7 @@ export function resolveTextBinding(element, point) {
|
|
|
383
342
|
// markup is intentionally not included: a confident semantic component
|
|
384
343
|
// binding may still own a nested text node, while rendered fallback keeps
|
|
385
344
|
// its stricter direct-leaf requirement.
|
|
386
|
-
if (
|
|
345
|
+
if (isUnsafeTextHost(element)) {
|
|
387
346
|
return {
|
|
388
347
|
kind: "rejected",
|
|
389
348
|
reason: "unsafe-target",
|
|
@@ -61,6 +61,11 @@ export interface RuntimeComponentTarget {
|
|
|
61
61
|
/** Adapter-reported mounted invocation count for this callsite. */
|
|
62
62
|
mountedCount?: number;
|
|
63
63
|
}
|
|
64
|
+
/** A component invocation whose entire rendered output is one DOM element. */
|
|
65
|
+
export interface ComponentRootInvocation {
|
|
66
|
+
callsiteId: string;
|
|
67
|
+
componentName: string;
|
|
68
|
+
}
|
|
64
69
|
export interface ComponentPropContract {
|
|
65
70
|
name: string;
|
|
66
71
|
control: "select" | "boolean" | "text";
|
|
@@ -93,4 +98,10 @@ export interface ComponentRuntimeAdapter {
|
|
|
93
98
|
* fail closed instead of broadening a semantic override.
|
|
94
99
|
*/
|
|
95
100
|
getCallsiteMultiplicity?(callsiteId: string): number | null | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Return, nearest first, the invocations whose entire rendered output is
|
|
103
|
+
* this element. A runtime that cannot read the element's ancestry must
|
|
104
|
+
* return null so structural identity fails closed.
|
|
105
|
+
*/
|
|
106
|
+
rootInvocations?(element: HTMLElement): ComponentRootInvocation[] | null;
|
|
96
107
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { type ChangeRecord } from "../changes/types.js";
|
|
2
|
+
import type { StructuralChange } from "../changes/structuralTypes.js";
|
|
3
|
+
import type { SketchDocument } from "../sketch/model.js";
|
|
4
|
+
import type { Timeline } from "../workspace/timeline.js";
|
|
5
|
+
import { type Draft, type DraftContents, type DraftSnapshot } from "./model.js";
|
|
6
|
+
export interface DraftChangesSnapshot extends DraftContents {
|
|
7
|
+
readonly draftId: string;
|
|
8
|
+
readonly revision: number;
|
|
9
|
+
readonly canUndo: boolean;
|
|
10
|
+
readonly canRedo: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** A canonical write result. `blocked` means the lease or a save lock refused the write. */
|
|
13
|
+
export type CommitResult = "applied" | "unchanged" | "blocked";
|
|
14
|
+
/** Why the active draft's preview must be rebuilt. */
|
|
15
|
+
export type DraftProjectionEvent =
|
|
16
|
+
/** The active draft's contents changed through an edit, revert, undo, or redo. */
|
|
17
|
+
{
|
|
18
|
+
readonly kind: "edit";
|
|
19
|
+
readonly verificationTargets?: ReadonlyMap<string, HTMLElement | null>;
|
|
20
|
+
}
|
|
21
|
+
/** Source verification removed these records from the active draft. */
|
|
22
|
+
| {
|
|
23
|
+
readonly kind: "reconcile";
|
|
24
|
+
readonly structuralIds: ReadonlySet<string>;
|
|
25
|
+
}
|
|
26
|
+
/** Another draft became active, or drafts were loaded. */
|
|
27
|
+
| {
|
|
28
|
+
readonly kind: "switch";
|
|
29
|
+
}
|
|
30
|
+
/** The active draft was cleared; every earlier preview diagnostic is void. */
|
|
31
|
+
| {
|
|
32
|
+
readonly kind: "reset";
|
|
33
|
+
};
|
|
34
|
+
export type DraftDiscardTarget = {
|
|
35
|
+
readonly kind: "selector";
|
|
36
|
+
readonly selector: string;
|
|
37
|
+
} | {
|
|
38
|
+
readonly kind: "instance-override";
|
|
39
|
+
readonly id: string;
|
|
40
|
+
};
|
|
41
|
+
export interface DraftStorage {
|
|
42
|
+
read(key: string): string | null;
|
|
43
|
+
write(key: string, value: string): void;
|
|
44
|
+
remove(key: string): void;
|
|
45
|
+
}
|
|
46
|
+
export interface DraftSketchSource {
|
|
47
|
+
getSnapshot(): {
|
|
48
|
+
readonly ready: boolean;
|
|
49
|
+
readonly documents: readonly SketchDocument[];
|
|
50
|
+
};
|
|
51
|
+
subscribe(listener: () => void): () => void;
|
|
52
|
+
}
|
|
53
|
+
export interface DraftStoreSeams {
|
|
54
|
+
/** Whether this tab holds the workspace write lease. */
|
|
55
|
+
canWrite(): boolean;
|
|
56
|
+
readonly timeline: Timeline;
|
|
57
|
+
readonly storage: DraftStorage;
|
|
58
|
+
readonly sketches: DraftSketchSource;
|
|
59
|
+
/** Rebuilds the active draft's preview. Called after subscribers see the new snapshot. */
|
|
60
|
+
project(snapshot: DraftChangesSnapshot, event: DraftProjectionEvent): void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The Workspace's drafts. A draft's identity is its target key (ADR-0030):
|
|
64
|
+
* every frame that shows one page or iteration edits the same draft. Every
|
|
65
|
+
* write is lease-gated, every change to the active draft is projected, and
|
|
66
|
+
* reconciliation removes only verified records, including from history.
|
|
67
|
+
*/
|
|
68
|
+
export interface DraftStore {
|
|
69
|
+
getActive(): DraftChangesSnapshot;
|
|
70
|
+
/** Fires for any draft content change, active-draft switch, or history change. */
|
|
71
|
+
subscribeActive(listener: () => void): () => void;
|
|
72
|
+
get(id: string): DraftChangesSnapshot;
|
|
73
|
+
ids(): readonly string[];
|
|
74
|
+
getDraft(id: string): Draft | null;
|
|
75
|
+
getSnapshot(): DraftSnapshot;
|
|
76
|
+
subscribe(listener: () => void): () => void;
|
|
77
|
+
canEdit(id?: string): boolean;
|
|
78
|
+
isLocked(id?: string): boolean;
|
|
79
|
+
/** Blocks writes to one draft until the returned release runs. */
|
|
80
|
+
lock(id: string): () => void;
|
|
81
|
+
/** Makes a draft active; `reveal` brings its frame back when history replays an edit. */
|
|
82
|
+
activate(id: string, reveal?: () => void): void;
|
|
83
|
+
commitChanges(incoming: readonly ChangeRecord[], verificationTargets?: ReadonlyMap<string, HTMLElement | null>): CommitResult;
|
|
84
|
+
revertChange(change: ChangeRecord): boolean;
|
|
85
|
+
discardChanges(target: DraftDiscardTarget): boolean;
|
|
86
|
+
commitStructuralChange(change: StructuralChange): boolean;
|
|
87
|
+
revertStructuralChange(changeId: string): boolean;
|
|
88
|
+
/** Replaces the active draft as one undoable edit. */
|
|
89
|
+
commitContents(next: DraftContents): boolean;
|
|
90
|
+
undo(): boolean;
|
|
91
|
+
redo(): boolean;
|
|
92
|
+
/** Removes source-verified records so no undo step can resurrect them. */
|
|
93
|
+
reconcile(id: string, verifiedKeys: ReadonlySet<string>, verifiedStructuralIds: ReadonlySet<string>): number;
|
|
94
|
+
clear(id: string, expectedRevision?: number): boolean;
|
|
95
|
+
clearActive(): boolean;
|
|
96
|
+
/** Drops a draft whose content no longer exists, such as a deleted iteration. */
|
|
97
|
+
forget(id: string): void;
|
|
98
|
+
sketchOwner(document: SketchDocument): string | null;
|
|
99
|
+
assignSketch(draftId: string, sketchId: string): void;
|
|
100
|
+
/** Replaces every in-memory draft with the stored drafts, so a tab that takes over never writes stale edits. */
|
|
101
|
+
load(projectId: string, options?: {
|
|
102
|
+
persistent?: boolean;
|
|
103
|
+
}): void;
|
|
104
|
+
persist(): void;
|
|
105
|
+
/** Discards stored and in-memory drafts for the current project. */
|
|
106
|
+
discardAll(): void;
|
|
107
|
+
reset(): void;
|
|
108
|
+
}
|
|
109
|
+
export declare function createDraftStore(seams: DraftStoreSeams): DraftStore;
|