@storystick/preview 0.0.0-stage → 0.2.0-rc.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.
- package/LICENSE +112 -0
- package/PUBLIC-API.md +55 -0
- package/README.md +42 -2
- package/dist/.source-hash +1 -0
- package/dist/authoring/runtime-contract.d.ts +89 -0
- package/dist/authoring/runtime-contract.js +28 -0
- package/dist/channel-taxonomy.d.ts +17 -0
- package/dist/channel-taxonomy.js +46 -0
- package/dist/context-command.d.ts +18 -0
- package/dist/context-command.js +38 -0
- package/dist/dev/suspicious-codeword-detector.d.ts +15 -0
- package/dist/dev/suspicious-codeword-detector.js +220 -0
- package/dist/dev/suspicious-codeword-detector.noop.d.ts +3 -0
- package/dist/dev/suspicious-codeword-detector.noop.js +4 -0
- package/dist/framework/browser-context.d.ts +2 -0
- package/dist/framework/browser-context.js +2 -0
- package/dist/framework/generation-refresh.d.ts +23 -0
- package/dist/framework/generation-refresh.js +82 -0
- package/dist/framework/generation-signal.d.ts +8 -0
- package/dist/framework/generation-signal.js +17 -0
- package/dist/framework/projection-generation-watch.d.ts +5 -0
- package/dist/framework/projection-generation-watch.js +53 -0
- package/dist/framework/render-receipt.d.ts +8 -0
- package/dist/framework/render-receipt.js +10 -0
- package/dist/framework/runtime-adapter-store.d.ts +30 -0
- package/dist/framework/runtime-adapter-store.js +81 -0
- package/dist/grant-coordinator.d.ts +53 -0
- package/dist/grant-coordinator.js +329 -0
- package/dist/grant-lifecycle.d.ts +52 -0
- package/dist/grant-lifecycle.js +74 -0
- package/dist/identity/__test-adapter.d.ts +34 -0
- package/dist/identity/__test-adapter.js +59 -0
- package/dist/identity/browser-context-gate.d.ts +4 -0
- package/dist/identity/browser-context-gate.js +22 -0
- package/dist/identity/browser-context.d.ts +13 -0
- package/dist/identity/browser-context.js +22 -0
- package/dist/identity/carriers/postmessage.d.ts +84 -0
- package/dist/identity/carriers/postmessage.js +177 -0
- package/dist/identity/carriers/storage-state.d.ts +41 -0
- package/dist/identity/carriers/storage-state.js +99 -0
- package/dist/identity/carriers/storage.d.ts +39 -0
- package/dist/identity/carriers/storage.js +182 -0
- package/dist/identity/carriers/url.d.ts +19 -0
- package/dist/identity/carriers/url.js +38 -0
- package/dist/identity/identity-state-machine.d.ts +70 -0
- package/dist/identity/identity-state-machine.js +244 -0
- package/dist/identity/identity-types.d.ts +192 -0
- package/dist/identity/identity-types.js +22 -0
- package/dist/identity/index.d.ts +18 -0
- package/dist/identity/index.js +16 -0
- package/dist/identity/preview-cookie.d.ts +9 -0
- package/dist/identity/preview-cookie.js +12 -0
- package/dist/identity/preview-draft.d.ts +6 -0
- package/dist/identity/preview-draft.js +25 -0
- package/dist/identity/preview-identity.d.ts +28 -0
- package/dist/identity/preview-identity.js +84 -0
- package/dist/identity/preview-scope.d.ts +28 -0
- package/dist/identity/preview-scope.js +47 -0
- package/dist/identity/resolver.d.ts +110 -0
- package/dist/identity/resolver.js +334 -0
- package/dist/identity/session-query.d.ts +4 -0
- package/dist/identity/session-query.js +19 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +788 -0
- package/dist/interaction-mode.d.ts +58 -0
- package/dist/interaction-mode.js +93 -0
- package/dist/nav-handler.d.ts +95 -0
- package/dist/nav-handler.js +84 -0
- package/dist/overlay-label.d.ts +79 -0
- package/dist/overlay-label.js +73 -0
- package/dist/provenance/anchor-map.d.ts +95 -0
- package/dist/provenance/anchor-map.js +177 -0
- package/dist/provenance/carrier-plan.d.ts +51 -0
- package/dist/provenance/carrier-plan.js +90 -0
- package/dist/provenance/coded-text.d.ts +20 -0
- package/dist/provenance/coded-text.js +302 -0
- package/dist/provenance/direct-edit-locator.d.ts +29 -0
- package/dist/provenance/direct-edit-locator.js +218 -0
- package/dist/provenance/editable-leaf.d.ts +134 -0
- package/dist/provenance/editable-leaf.js +483 -0
- package/dist/provenance/editor-target.d.ts +29 -0
- package/dist/provenance/editor-target.js +46 -0
- package/dist/provenance/field-leaf-walker.d.ts +21 -0
- package/dist/provenance/field-leaf-walker.js +98 -0
- package/dist/provenance/frame-dependencies.d.ts +212 -0
- package/dist/provenance/frame-dependencies.js +550 -0
- package/dist/provenance/index.d.ts +26 -0
- package/dist/provenance/index.js +26 -0
- package/dist/provenance/local-events.d.ts +1 -0
- package/dist/provenance/local-events.js +1 -0
- package/dist/provenance/markers.d.ts +21 -0
- package/dist/provenance/markers.js +70 -0
- package/dist/provenance/multi-frame-anchor-map.d.ts +54 -0
- package/dist/provenance/multi-frame-anchor-map.js +109 -0
- package/dist/provenance/normalize.d.ts +2 -0
- package/dist/provenance/normalize.js +19 -0
- package/dist/provenance/overlay-focus-echo.d.ts +17 -0
- package/dist/provenance/overlay-focus-echo.js +16 -0
- package/dist/provenance/overlay-projection.d.ts +65 -0
- package/dist/provenance/overlay-projection.js +201 -0
- package/dist/provenance/owner-map.d.ts +55 -0
- package/dist/provenance/owner-map.js +239 -0
- package/dist/provenance/read-carrier.d.ts +22 -0
- package/dist/provenance/read-carrier.js +92 -0
- package/dist/provenance/recorder.d.ts +38 -0
- package/dist/provenance/recorder.js +82 -0
- package/dist/provenance/render-context.d.ts +106 -0
- package/dist/provenance/render-context.js +338 -0
- package/dist/provenance/reveal-contract.d.ts +44 -0
- package/dist/provenance/reveal-contract.js +1 -0
- package/dist/provenance/richtext-slice-embed-address.d.ts +20 -0
- package/dist/provenance/richtext-slice-embed-address.js +35 -0
- package/dist/provenance/runtime-script.d.ts +1 -0
- package/dist/provenance/runtime-script.js +2217 -0
- package/dist/provenance/sidecar-store.d.ts +63 -0
- package/dist/provenance/sidecar-store.js +151 -0
- package/dist/provenance/sidecar.d.ts +34 -0
- package/dist/provenance/sidecar.js +227 -0
- package/dist/provenance/slice-model.d.ts +28 -0
- package/dist/provenance/slice-model.js +86 -0
- package/dist/provenance/source-identity.d.ts +3 -0
- package/dist/provenance/source-identity.js +7 -0
- package/dist/provenance/source-map-materializer.d.ts +76 -0
- package/dist/provenance/source-map-materializer.js +286 -0
- package/dist/provenance/source-registry.d.ts +103 -0
- package/dist/provenance/source-registry.js +562 -0
- package/dist/provenance/transformed-output-gate.d.ts +161 -0
- package/dist/provenance/transformed-output-gate.js +171 -0
- package/dist/provenance/types.d.ts +102 -0
- package/dist/provenance/types.js +1 -0
- package/dist/refresh-policy.d.ts +11 -0
- package/dist/refresh-policy.js +14 -0
- package/dist/reveal-target.d.ts +8 -0
- package/dist/reveal-target.js +47 -0
- package/dist/route-paths.d.ts +11 -0
- package/dist/route-paths.js +14 -0
- package/dist/router-subscriber.d.ts +92 -0
- package/dist/router-subscriber.js +44 -0
- package/dist/runtime/anchor-types.d.ts +5 -0
- package/dist/runtime/anchor-types.js +1 -0
- package/dist/runtime/authority-store.d.ts +31 -0
- package/dist/runtime/authority-store.js +56 -0
- package/dist/runtime/boot.d.ts +52 -0
- package/dist/runtime/boot.js +379 -0
- package/dist/runtime/content-refresh.d.ts +30 -0
- package/dist/runtime/content-refresh.js +68 -0
- package/dist/runtime/emit-runtime-error.d.ts +51 -0
- package/dist/runtime/emit-runtime-error.js +64 -0
- package/dist/runtime/field-proxy.d.ts +112 -0
- package/dist/runtime/field-proxy.js +471 -0
- package/dist/runtime/form-contract-reporter.d.ts +99 -0
- package/dist/runtime/form-contract-reporter.js +391 -0
- package/dist/runtime/invalidation-adapter.d.ts +17 -0
- package/dist/runtime/invalidation-adapter.js +42 -0
- package/dist/runtime/live-query-overlay.d.ts +39 -0
- package/dist/runtime/live-query-overlay.js +345 -0
- package/dist/runtime/momentary-navigate.d.ts +16 -0
- package/dist/runtime/momentary-navigate.js +106 -0
- package/dist/runtime/observation-scheduler.d.ts +15 -0
- package/dist/runtime/observation-scheduler.js +42 -0
- package/dist/runtime/perf-metrics.d.ts +28 -0
- package/dist/runtime/perf-metrics.js +90 -0
- package/dist/runtime/preview-interaction-policy.d.ts +1 -0
- package/dist/runtime/preview-interaction-policy.js +103 -0
- package/dist/runtime/preview-overlay-painter.d.ts +27 -0
- package/dist/runtime/preview-overlay-painter.js +1732 -0
- package/dist/runtime/preview-overlay-sidecar.d.ts +26 -0
- package/dist/runtime/preview-overlay-sidecar.js +45 -0
- package/dist/runtime/preview-perspective-alignment.d.ts +15 -0
- package/dist/runtime/preview-perspective-alignment.js +40 -0
- package/dist/runtime/preview-perspective-intent-state.d.ts +23 -0
- package/dist/runtime/preview-perspective-intent-state.js +5 -0
- package/dist/runtime/preview-transition-state.d.ts +142 -0
- package/dist/runtime/preview-transition-state.js +257 -0
- package/dist/runtime/render-mode-state.d.ts +51 -0
- package/dist/runtime/render-mode-state.js +76 -0
- package/dist/runtime/request-id.d.ts +4 -0
- package/dist/runtime/request-id.js +8 -0
- package/dist/runtime/resolve-schema-field.d.ts +99 -0
- package/dist/runtime/resolve-schema-field.js +356 -0
- package/dist/runtime/runtime-error-dispatch.d.ts +23 -0
- package/dist/runtime/runtime-error-dispatch.js +75 -0
- package/dist/runtime/schema-store.d.ts +121 -0
- package/dist/runtime/schema-store.js +667 -0
- package/dist/runtime/snapshot-assembly.d.ts +104 -0
- package/dist/runtime/snapshot-assembly.js +553 -0
- package/dist/runtime/snapshot-reporter.d.ts +55 -0
- package/dist/runtime/snapshot-reporter.js +375 -0
- package/dist/runtime/standalone-overlay-controller.d.ts +33 -0
- package/dist/runtime/standalone-overlay-controller.js +281 -0
- package/dist/runtime/store.d.ts +307 -0
- package/dist/runtime/store.js +1026 -0
- package/dist/runtime/windowed-minimap-projection.d.ts +28 -0
- package/dist/runtime/windowed-minimap-projection.js +189 -0
- package/dist/runtime/workspace-shortcuts.d.ts +30 -0
- package/dist/runtime/workspace-shortcuts.js +188 -0
- package/dist/sdk-error-copy.d.ts +48 -0
- package/dist/sdk-error-copy.js +182 -0
- package/dist/select-cursor.d.ts +2 -0
- package/dist/select-cursor.js +23 -0
- package/dist/server/admission-cookie.d.ts +38 -0
- package/dist/server/admission-cookie.js +122 -0
- package/dist/server/control-client.d.ts +29 -0
- package/dist/server/control-client.js +22 -0
- package/dist/server/control-errors.d.ts +22 -0
- package/dist/server/control-errors.js +165 -0
- package/dist/server/draft-route.d.ts +12 -0
- package/dist/server/draft-route.js +45 -0
- package/dist/server/extract-token.d.ts +30 -0
- package/dist/server/extract-token.js +98 -0
- package/dist/server/grant.d.ts +128 -0
- package/dist/server/grant.js +395 -0
- package/dist/server/ordinary-read-provenance.d.ts +11 -0
- package/dist/server/ordinary-read-provenance.js +124 -0
- package/dist/server/preview-read-metadata.d.ts +10 -0
- package/dist/server/preview-read-metadata.js +27 -0
- package/dist/server/provenance-frame-builder.d.ts +53 -0
- package/dist/server/provenance-frame-builder.js +102 -0
- package/dist/server/provenance-runtime.d.ts +70 -0
- package/dist/server/provenance-runtime.js +46 -0
- package/dist/server/read-context-command.d.ts +11 -0
- package/dist/server/read-context-command.js +53 -0
- package/dist/server/read-identity.d.ts +3 -0
- package/dist/server/read-identity.js +63 -0
- package/dist/server/read-lifecycle.d.ts +17 -0
- package/dist/server/read-lifecycle.js +52 -0
- package/dist/server/render-frame-provenance.d.ts +133 -0
- package/dist/server/render-frame-provenance.js +676 -0
- package/dist/server/render-id.d.ts +15 -0
- package/dist/server/render-id.js +22 -0
- package/dist/server/route-document-provenance.d.ts +77 -0
- package/dist/server/route-document-provenance.js +1327 -0
- package/dist/server/route-session-cookie.d.ts +33 -0
- package/dist/server/route-session-cookie.js +54 -0
- package/dist/session-projections.d.ts +33 -0
- package/dist/session-projections.js +43 -0
- package/dist/session-subscriber.d.ts +124 -0
- package/dist/session-subscriber.js +79 -0
- package/dist/sha256-fallback.d.ts +30 -0
- package/dist/sha256-fallback.js +126 -0
- package/dist/types.d.ts +446 -0
- package/dist/types.js +85 -0
- package/dist/validators.d.ts +61 -0
- package/dist/validators.js +110 -0
- package/package.json +206 -3
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Iframe-side `interaction-mode` state (ADR-108 D2 + D7).
|
|
3
|
+
*
|
|
4
|
+
* Module-level state mirror of the Studio's authoritative
|
|
5
|
+
* `interactionMode`. Studio is the writer (via the imperative
|
|
6
|
+
* `bridge.setInteractionMode(mode)` method), the SDK is the reader
|
|
7
|
+
* (the click interceptors inside `@storystick/preview`'s overlay
|
|
8
|
+
* runtime + the customer's own gating if desired).
|
|
9
|
+
*
|
|
10
|
+
* Two modes:
|
|
11
|
+
* - `'edit'` (default): iframe-local overlay click interceptors
|
|
12
|
+
* `preventDefault()` on approved field targets and emit
|
|
13
|
+
* `storystick.preview.overlay-click` so Studio validates the
|
|
14
|
+
* `paintKey` before routing to the editor.
|
|
15
|
+
* - `'browse'`: SDK click interceptors let the click bubble untouched
|
|
16
|
+
* so the customer's `<a>` natively navigates. The reverse `location`
|
|
17
|
+
* channel still flows so Studio mirrors the iframe's URL via
|
|
18
|
+
* reverse doc lookup (D5).
|
|
19
|
+
*
|
|
20
|
+
* Realm-level (no React, no component/session ownership). Multiple SDK
|
|
21
|
+
* entrypoints can be bundled into separate physical module graphs in the same
|
|
22
|
+
* iframe. They must still observe one mode and one listener set, so browser
|
|
23
|
+
* state lives on the Window under a global-symbol key. Click interceptors live
|
|
24
|
+
* inside framework-agnostic overlay runtime; they read the mode through
|
|
25
|
+
* `getInteractionMode()` at click time.
|
|
26
|
+
*/
|
|
27
|
+
export type InteractionMode = 'edit' | 'browse';
|
|
28
|
+
/**
|
|
29
|
+
* Read the current interaction mode. Click interceptors call this
|
|
30
|
+
* synchronously inside their handlers; the result is the mode the
|
|
31
|
+
* Studio last sent via `interaction-mode` envelope.
|
|
32
|
+
*
|
|
33
|
+
* Default is `'edit'` until Studio explicitly emits a mode. This
|
|
34
|
+
* matches today's behaviour pre-ADR-108 (everything is edit-mode by
|
|
35
|
+
* default) so existing customers see no behaviour change without an
|
|
36
|
+
* explicit toggle.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getInteractionMode(): InteractionMode;
|
|
39
|
+
/**
|
|
40
|
+
* Set the interaction mode. Invoked by `activate()`'s message
|
|
41
|
+
* listener after it validates an incoming `interaction-mode`
|
|
42
|
+
* envelope. Idempotent re-asserts deliberately notify subscribers: the
|
|
43
|
+
* in-memory value can outlive the runtime-owned stylesheet across iframe/head
|
|
44
|
+
* lifecycle changes, so each authoritative replay is also a reconciliation
|
|
45
|
+
* signal.
|
|
46
|
+
*
|
|
47
|
+
* Exposed (rather than module-private) so tests can drive the mode
|
|
48
|
+
* directly without going through the full envelope path; also so a
|
|
49
|
+
* future Studio dev-tool / hostile-actor mitigation can call it
|
|
50
|
+
* defensively.
|
|
51
|
+
*/
|
|
52
|
+
export declare function setInteractionMode(mode: InteractionMode): void;
|
|
53
|
+
export declare function subscribeInteractionMode(listener: (mode: InteractionMode) => void): () => void;
|
|
54
|
+
/**
|
|
55
|
+
* Test-only reset. Vitest modules are isolated per file but cases
|
|
56
|
+
* within a single file would otherwise share state.
|
|
57
|
+
*/
|
|
58
|
+
export declare function _resetInteractionModeForTests(): void;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Iframe-side `interaction-mode` state (ADR-108 D2 + D7).
|
|
3
|
+
*
|
|
4
|
+
* Module-level state mirror of the Studio's authoritative
|
|
5
|
+
* `interactionMode`. Studio is the writer (via the imperative
|
|
6
|
+
* `bridge.setInteractionMode(mode)` method), the SDK is the reader
|
|
7
|
+
* (the click interceptors inside `@storystick/preview`'s overlay
|
|
8
|
+
* runtime + the customer's own gating if desired).
|
|
9
|
+
*
|
|
10
|
+
* Two modes:
|
|
11
|
+
* - `'edit'` (default): iframe-local overlay click interceptors
|
|
12
|
+
* `preventDefault()` on approved field targets and emit
|
|
13
|
+
* `storystick.preview.overlay-click` so Studio validates the
|
|
14
|
+
* `paintKey` before routing to the editor.
|
|
15
|
+
* - `'browse'`: SDK click interceptors let the click bubble untouched
|
|
16
|
+
* so the customer's `<a>` natively navigates. The reverse `location`
|
|
17
|
+
* channel still flows so Studio mirrors the iframe's URL via
|
|
18
|
+
* reverse doc lookup (D5).
|
|
19
|
+
*
|
|
20
|
+
* Realm-level (no React, no component/session ownership). Multiple SDK
|
|
21
|
+
* entrypoints can be bundled into separate physical module graphs in the same
|
|
22
|
+
* iframe. They must still observe one mode and one listener set, so browser
|
|
23
|
+
* state lives on the Window under a global-symbol key. Click interceptors live
|
|
24
|
+
* inside framework-agnostic overlay runtime; they read the mode through
|
|
25
|
+
* `getInteractionMode()` at click time.
|
|
26
|
+
*/
|
|
27
|
+
const INTERACTION_MODE_STATE_KEY = Symbol.for('storystick.preview.interaction-mode-state.v1');
|
|
28
|
+
const serverState = createInteractionModeState();
|
|
29
|
+
function createInteractionModeState() {
|
|
30
|
+
return {
|
|
31
|
+
currentMode: 'edit',
|
|
32
|
+
listeners: new Set(),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getInteractionModeState() {
|
|
36
|
+
if (typeof window === 'undefined')
|
|
37
|
+
return serverState;
|
|
38
|
+
const existing = Reflect.get(window, INTERACTION_MODE_STATE_KEY);
|
|
39
|
+
if (existing !== undefined)
|
|
40
|
+
return existing;
|
|
41
|
+
const state = createInteractionModeState();
|
|
42
|
+
Reflect.set(window, INTERACTION_MODE_STATE_KEY, state);
|
|
43
|
+
return state;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Read the current interaction mode. Click interceptors call this
|
|
47
|
+
* synchronously inside their handlers; the result is the mode the
|
|
48
|
+
* Studio last sent via `interaction-mode` envelope.
|
|
49
|
+
*
|
|
50
|
+
* Default is `'edit'` until Studio explicitly emits a mode. This
|
|
51
|
+
* matches today's behaviour pre-ADR-108 (everything is edit-mode by
|
|
52
|
+
* default) so existing customers see no behaviour change without an
|
|
53
|
+
* explicit toggle.
|
|
54
|
+
*/
|
|
55
|
+
export function getInteractionMode() {
|
|
56
|
+
return getInteractionModeState().currentMode;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the interaction mode. Invoked by `activate()`'s message
|
|
60
|
+
* listener after it validates an incoming `interaction-mode`
|
|
61
|
+
* envelope. Idempotent re-asserts deliberately notify subscribers: the
|
|
62
|
+
* in-memory value can outlive the runtime-owned stylesheet across iframe/head
|
|
63
|
+
* lifecycle changes, so each authoritative replay is also a reconciliation
|
|
64
|
+
* signal.
|
|
65
|
+
*
|
|
66
|
+
* Exposed (rather than module-private) so tests can drive the mode
|
|
67
|
+
* directly without going through the full envelope path; also so a
|
|
68
|
+
* future Studio dev-tool / hostile-actor mitigation can call it
|
|
69
|
+
* defensively.
|
|
70
|
+
*/
|
|
71
|
+
export function setInteractionMode(mode) {
|
|
72
|
+
const state = getInteractionModeState();
|
|
73
|
+
state.currentMode = mode;
|
|
74
|
+
for (const listener of [...state.listeners]) {
|
|
75
|
+
listener(mode);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function subscribeInteractionMode(listener) {
|
|
79
|
+
const state = getInteractionModeState();
|
|
80
|
+
state.listeners.add(listener);
|
|
81
|
+
return () => {
|
|
82
|
+
state.listeners.delete(listener);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Test-only reset. Vitest modules are isolated per file but cases
|
|
87
|
+
* within a single file would otherwise share state.
|
|
88
|
+
*/
|
|
89
|
+
export function _resetInteractionModeForTests() {
|
|
90
|
+
const state = getInteractionModeState();
|
|
91
|
+
state.currentMode = 'edit';
|
|
92
|
+
state.listeners.clear();
|
|
93
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-frame navigation hook (ADR-087 §3.2).
|
|
3
|
+
*
|
|
4
|
+
* Studio → iframe `storystick.preview.navigate` postMessage drives
|
|
5
|
+
* SPA-internal navigation when the editor switches docs / changes
|
|
6
|
+
* the pathname / picks a variant with a different pathname. The
|
|
7
|
+
* handling is **best-effort CSR** (codex round 3 finding C9, ADR
|
|
8
|
+
* §3.2 honest claim) — Lane D' will provide framework adapters
|
|
9
|
+
* (Next, Astro, Vanilla). Lane D defines the contract.
|
|
10
|
+
*
|
|
11
|
+
* Two pieces :
|
|
12
|
+
*
|
|
13
|
+
* 1. `setNavigateHandler(fn)` — consumer registers a callback. The
|
|
14
|
+
* framework adapters call this in their provider integration
|
|
15
|
+
* with `(pathname) => router.push(pathname)`. The default is a
|
|
16
|
+
* no-op so the iframe doesn't crash if no adapter is loaded.
|
|
17
|
+
*
|
|
18
|
+
* 2. `getNavigateHandler()` — internal getter for the iframe-side
|
|
19
|
+
* `message` listener (in `index.ts` orchestrator). The listener
|
|
20
|
+
* validates the envelope through `validateNavigate` and only
|
|
21
|
+
* invokes the handler with a sanitized pathname.
|
|
22
|
+
*
|
|
23
|
+
* `pathname` validation is enforced upstream (in
|
|
24
|
+
* `validatePreviewEnvelope` from the foundation Lane C — same-origin
|
|
25
|
+
* absolute paths only, no `javascript:` / `//cross-origin` / scheme
|
|
26
|
+
* switches). The handler receives a value already cleared by that
|
|
27
|
+
* validator.
|
|
28
|
+
*/
|
|
29
|
+
import type { PreviewScopeSelection, PreviewContextCommandFence } from '@storystick/transport-allowlist';
|
|
30
|
+
/**
|
|
31
|
+
* Optional metadata forwarded to the handler from the envelope payload.
|
|
32
|
+
*
|
|
33
|
+
* ADR-111 — `refresh` signals to framework adapters that the navigate
|
|
34
|
+
* accompanies a change in root-layout preview state (typically
|
|
35
|
+
* `draftDocumentId`). App Router adapters refresh the client Router Cache
|
|
36
|
+
* after the destination commits; they must not start `router.replace()` and
|
|
37
|
+
* `router.refresh()` as concurrent Flight transitions. Pages Router adapters
|
|
38
|
+
* ignore the flag (no cached layout to invalidate).
|
|
39
|
+
*
|
|
40
|
+
* Generic name on purpose — the contract is "layout preview state has
|
|
41
|
+
* changed." Future fields affecting `resolvePreviewDraft()` reuse the
|
|
42
|
+
* same flag without a handler signature bump.
|
|
43
|
+
*/
|
|
44
|
+
export interface NavigateHandlerOptions {
|
|
45
|
+
history?: 'push' | 'replace';
|
|
46
|
+
refresh?: boolean;
|
|
47
|
+
scope: PreviewScopeSelection;
|
|
48
|
+
commandId?: string;
|
|
49
|
+
contextCommand?: PreviewContextCommandFence;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Handler signature. The pathname is guaranteed to be an absolute
|
|
53
|
+
* same-origin path starting with `/` (validated by the foundation
|
|
54
|
+
* envelope validator, see Lane C foundation round 3 fix).
|
|
55
|
+
*
|
|
56
|
+
* `options` is optional for backward compatibility — handlers
|
|
57
|
+
* registered before ADR-111 keep their `(pathname) => …` signature and
|
|
58
|
+
* the new field is simply ignored by them. Adapters that want to react
|
|
59
|
+
* to `refresh: true` add it explicitly.
|
|
60
|
+
*/
|
|
61
|
+
export type NavigateHandler = (pathname: string, options?: NavigateHandlerOptions) => void;
|
|
62
|
+
export interface ReloadHandlerOptions {
|
|
63
|
+
commandId: string;
|
|
64
|
+
}
|
|
65
|
+
export type ReloadMode = 'soft' | 'hard';
|
|
66
|
+
export type ReloadHandler = (mode: ReloadMode, options: ReloadHandlerOptions) => void;
|
|
67
|
+
interface PreviewNavigationHandlerCell {
|
|
68
|
+
navigate: NavigateHandler;
|
|
69
|
+
reload: ReloadHandler;
|
|
70
|
+
}
|
|
71
|
+
declare global {
|
|
72
|
+
var __storystick_preview_navigation_handlers__: PreviewNavigationHandlerCell | undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Register a navigation handler. Replaces any previously registered
|
|
76
|
+
* handler — the framework adapter that wires up first wins, but a
|
|
77
|
+
* later override (e.g. customer's own router) takes precedence.
|
|
78
|
+
*
|
|
79
|
+
* Pass `null` to reset to the default no-op (useful for tests +
|
|
80
|
+
* Provider unmount cleanup).
|
|
81
|
+
*/
|
|
82
|
+
export declare function setNavigateHandler(fn: NavigateHandler | null): void;
|
|
83
|
+
/** Internal accessor — used by the orchestrator's message listener. */
|
|
84
|
+
export declare function getNavigateHandler(): NavigateHandler;
|
|
85
|
+
/** True once a framework adapter has replaced the default no-op handler. */
|
|
86
|
+
export declare function hasNavigateHandler(): boolean;
|
|
87
|
+
export declare function setReloadHandler(fn: ReloadHandler | null): void;
|
|
88
|
+
export declare function getReloadHandler(): ReloadHandler;
|
|
89
|
+
/**
|
|
90
|
+
* Test-only reset. Vitest modules are isolated per file, but a
|
|
91
|
+
* single test file with multiple `setNavigateHandler` calls would
|
|
92
|
+
* otherwise share state across cases.
|
|
93
|
+
*/
|
|
94
|
+
export declare function _resetNavigateHandlerForTests(): void;
|
|
95
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-frame navigation hook (ADR-087 §3.2).
|
|
3
|
+
*
|
|
4
|
+
* Studio → iframe `storystick.preview.navigate` postMessage drives
|
|
5
|
+
* SPA-internal navigation when the editor switches docs / changes
|
|
6
|
+
* the pathname / picks a variant with a different pathname. The
|
|
7
|
+
* handling is **best-effort CSR** (codex round 3 finding C9, ADR
|
|
8
|
+
* §3.2 honest claim) — Lane D' will provide framework adapters
|
|
9
|
+
* (Next, Astro, Vanilla). Lane D defines the contract.
|
|
10
|
+
*
|
|
11
|
+
* Two pieces :
|
|
12
|
+
*
|
|
13
|
+
* 1. `setNavigateHandler(fn)` — consumer registers a callback. The
|
|
14
|
+
* framework adapters call this in their provider integration
|
|
15
|
+
* with `(pathname) => router.push(pathname)`. The default is a
|
|
16
|
+
* no-op so the iframe doesn't crash if no adapter is loaded.
|
|
17
|
+
*
|
|
18
|
+
* 2. `getNavigateHandler()` — internal getter for the iframe-side
|
|
19
|
+
* `message` listener (in `index.ts` orchestrator). The listener
|
|
20
|
+
* validates the envelope through `validateNavigate` and only
|
|
21
|
+
* invokes the handler with a sanitized pathname.
|
|
22
|
+
*
|
|
23
|
+
* `pathname` validation is enforced upstream (in
|
|
24
|
+
* `validatePreviewEnvelope` from the foundation Lane C — same-origin
|
|
25
|
+
* absolute paths only, no `javascript:` / `//cross-origin` / scheme
|
|
26
|
+
* switches). The handler receives a value already cleared by that
|
|
27
|
+
* validator.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Default no-op. The framework adapters override via
|
|
31
|
+
* `setNavigateHandler`. Without an adapter, the iframe simply does
|
|
32
|
+
* not navigate when Studio asks — the published preview content
|
|
33
|
+
* stays on the current page. The honest claim is "best-effort" so
|
|
34
|
+
* a silent ignore is acceptable when no router is wired.
|
|
35
|
+
*/
|
|
36
|
+
const NOOP = () => {
|
|
37
|
+
/* default = no-op */
|
|
38
|
+
};
|
|
39
|
+
const RELOAD_NOOP = () => {
|
|
40
|
+
/* default = no-op */
|
|
41
|
+
};
|
|
42
|
+
function handlerCell() {
|
|
43
|
+
const existing = globalThis.__storystick_preview_navigation_handlers__;
|
|
44
|
+
if (existing)
|
|
45
|
+
return existing;
|
|
46
|
+
const created = { navigate: NOOP, reload: RELOAD_NOOP };
|
|
47
|
+
globalThis.__storystick_preview_navigation_handlers__ = created;
|
|
48
|
+
return created;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Register a navigation handler. Replaces any previously registered
|
|
52
|
+
* handler — the framework adapter that wires up first wins, but a
|
|
53
|
+
* later override (e.g. customer's own router) takes precedence.
|
|
54
|
+
*
|
|
55
|
+
* Pass `null` to reset to the default no-op (useful for tests +
|
|
56
|
+
* Provider unmount cleanup).
|
|
57
|
+
*/
|
|
58
|
+
export function setNavigateHandler(fn) {
|
|
59
|
+
handlerCell().navigate = fn ?? NOOP;
|
|
60
|
+
}
|
|
61
|
+
/** Internal accessor — used by the orchestrator's message listener. */
|
|
62
|
+
export function getNavigateHandler() {
|
|
63
|
+
return handlerCell().navigate;
|
|
64
|
+
}
|
|
65
|
+
/** True once a framework adapter has replaced the default no-op handler. */
|
|
66
|
+
export function hasNavigateHandler() {
|
|
67
|
+
return handlerCell().navigate !== NOOP;
|
|
68
|
+
}
|
|
69
|
+
export function setReloadHandler(fn) {
|
|
70
|
+
handlerCell().reload = fn ?? RELOAD_NOOP;
|
|
71
|
+
}
|
|
72
|
+
export function getReloadHandler() {
|
|
73
|
+
return handlerCell().reload;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Test-only reset. Vitest modules are isolated per file, but a
|
|
77
|
+
* single test file with multiple `setNavigateHandler` calls would
|
|
78
|
+
* otherwise share state across cases.
|
|
79
|
+
*/
|
|
80
|
+
export function _resetNavigateHandlerForTests() {
|
|
81
|
+
const cell = handlerCell();
|
|
82
|
+
cell.navigate = NOOP;
|
|
83
|
+
cell.reload = RELOAD_NOOP;
|
|
84
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared visual primitive for non-interactive preview overlay labels.
|
|
3
|
+
*
|
|
4
|
+
* Studio renders slice labels in its React overlay while the preview runtime
|
|
5
|
+
* renders field labels directly in the customer iframe. They intentionally
|
|
6
|
+
* share these visual tokens so both surfaces remain one interaction system.
|
|
7
|
+
*/
|
|
8
|
+
export declare const PREVIEW_OVERLAY_LABEL_GAP_PX = 4;
|
|
9
|
+
export declare const PREVIEW_OVERLAY_LABEL_HEIGHT_PX = 20;
|
|
10
|
+
export type PreviewOverlayTone = 'default' | 'model';
|
|
11
|
+
export declare const PREVIEW_OVERLAY_VISUAL_STYLES: {
|
|
12
|
+
readonly default: {
|
|
13
|
+
readonly color: "oklch(0.614 0.194 257 / 0.9)";
|
|
14
|
+
readonly revealColor: "oklch(0.614 0.194 257 / 0.95)";
|
|
15
|
+
};
|
|
16
|
+
readonly model: {
|
|
17
|
+
readonly color: "oklch(0.635 0.19 322 / 0.9)";
|
|
18
|
+
readonly revealColor: "oklch(0.635 0.19 322 / 0.95)";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare const PREVIEW_OVERLAY_LABEL_VISUAL_STYLES: {
|
|
22
|
+
readonly default: {
|
|
23
|
+
readonly background: "oklch(0.46 0.12 257 / 0.96)";
|
|
24
|
+
readonly borderRadius: "999px";
|
|
25
|
+
readonly padding: "3px 8px";
|
|
26
|
+
readonly font: "500 11px/14px system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif";
|
|
27
|
+
readonly color: "white";
|
|
28
|
+
readonly boxShadow: "0 0 0 1px oklch(1 0 0 / 0.72)";
|
|
29
|
+
};
|
|
30
|
+
readonly model: {
|
|
31
|
+
readonly background: "oklch(0.46 0.11 322 / 0.96)";
|
|
32
|
+
readonly borderRadius: "999px";
|
|
33
|
+
readonly padding: "3px 8px";
|
|
34
|
+
readonly font: "500 11px/14px system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif";
|
|
35
|
+
readonly color: "white";
|
|
36
|
+
readonly boxShadow: "0 0 0 1px oklch(1 0 0 / 0.72)";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare function previewOverlayVisualStyle(tone: PreviewOverlayTone): {
|
|
40
|
+
readonly color: "oklch(0.614 0.194 257 / 0.9)";
|
|
41
|
+
readonly revealColor: "oklch(0.614 0.194 257 / 0.95)";
|
|
42
|
+
} | {
|
|
43
|
+
readonly color: "oklch(0.635 0.19 322 / 0.9)";
|
|
44
|
+
readonly revealColor: "oklch(0.635 0.19 322 / 0.95)";
|
|
45
|
+
};
|
|
46
|
+
export declare function previewOverlayLabelVisualStyle(tone: PreviewOverlayTone): {
|
|
47
|
+
readonly background: "oklch(0.46 0.12 257 / 0.96)";
|
|
48
|
+
readonly borderRadius: "999px";
|
|
49
|
+
readonly padding: "3px 8px";
|
|
50
|
+
readonly font: "500 11px/14px system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif";
|
|
51
|
+
readonly color: "white";
|
|
52
|
+
readonly boxShadow: "0 0 0 1px oklch(1 0 0 / 0.72)";
|
|
53
|
+
} | {
|
|
54
|
+
readonly background: "oklch(0.46 0.11 322 / 0.96)";
|
|
55
|
+
readonly borderRadius: "999px";
|
|
56
|
+
readonly padding: "3px 8px";
|
|
57
|
+
readonly font: "500 11px/14px system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif";
|
|
58
|
+
readonly color: "white";
|
|
59
|
+
readonly boxShadow: "0 0 0 1px oklch(1 0 0 / 0.72)";
|
|
60
|
+
};
|
|
61
|
+
export interface PreviewOverlayLabelHorizontalPositionInput {
|
|
62
|
+
targetLeft: number;
|
|
63
|
+
targetWidth: number;
|
|
64
|
+
labelWidth: number;
|
|
65
|
+
viewportWidth: number;
|
|
66
|
+
gap?: number;
|
|
67
|
+
}
|
|
68
|
+
export interface PreviewOverlayLabelHorizontalPosition {
|
|
69
|
+
left: number;
|
|
70
|
+
anchor: 'left' | 'right';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Prefer the target's right edge while the label fits inside it. A label wider
|
|
74
|
+
* than its target instead grows from the target's left edge, unless that would
|
|
75
|
+
* leave the viewport. The final clamp is the safety net for edge targets and
|
|
76
|
+
* labels wider than the available viewport.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolvePreviewOverlayLabelHorizontalPosition({ targetLeft, targetWidth, labelWidth, viewportWidth, gap, }: PreviewOverlayLabelHorizontalPositionInput): PreviewOverlayLabelHorizontalPosition;
|
|
79
|
+
export declare function applyPreviewOverlayLabelVisualStyle(element: HTMLElement, tone?: PreviewOverlayTone): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared visual primitive for non-interactive preview overlay labels.
|
|
3
|
+
*
|
|
4
|
+
* Studio renders slice labels in its React overlay while the preview runtime
|
|
5
|
+
* renders field labels directly in the customer iframe. They intentionally
|
|
6
|
+
* share these visual tokens so both surfaces remain one interaction system.
|
|
7
|
+
*/
|
|
8
|
+
export const PREVIEW_OVERLAY_LABEL_GAP_PX = 4;
|
|
9
|
+
export const PREVIEW_OVERLAY_LABEL_HEIGHT_PX = 20;
|
|
10
|
+
export const PREVIEW_OVERLAY_VISUAL_STYLES = {
|
|
11
|
+
default: {
|
|
12
|
+
color: 'oklch(0.614 0.194 257 / 0.9)',
|
|
13
|
+
revealColor: 'oklch(0.614 0.194 257 / 0.95)',
|
|
14
|
+
},
|
|
15
|
+
model: {
|
|
16
|
+
color: 'oklch(0.635 0.19 322 / 0.9)',
|
|
17
|
+
revealColor: 'oklch(0.635 0.19 322 / 0.95)',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
const PREVIEW_OVERLAY_LABEL_BASE_STYLE = {
|
|
21
|
+
borderRadius: '999px',
|
|
22
|
+
padding: '3px 8px',
|
|
23
|
+
font: '500 11px/14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
24
|
+
color: 'white',
|
|
25
|
+
boxShadow: '0 0 0 1px oklch(1 0 0 / 0.72)',
|
|
26
|
+
};
|
|
27
|
+
export const PREVIEW_OVERLAY_LABEL_VISUAL_STYLES = {
|
|
28
|
+
default: {
|
|
29
|
+
...PREVIEW_OVERLAY_LABEL_BASE_STYLE,
|
|
30
|
+
background: 'oklch(0.46 0.12 257 / 0.96)',
|
|
31
|
+
},
|
|
32
|
+
model: {
|
|
33
|
+
...PREVIEW_OVERLAY_LABEL_BASE_STYLE,
|
|
34
|
+
background: 'oklch(0.46 0.11 322 / 0.96)',
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export function previewOverlayVisualStyle(tone) {
|
|
38
|
+
return PREVIEW_OVERLAY_VISUAL_STYLES[tone];
|
|
39
|
+
}
|
|
40
|
+
export function previewOverlayLabelVisualStyle(tone) {
|
|
41
|
+
return PREVIEW_OVERLAY_LABEL_VISUAL_STYLES[tone];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Prefer the target's right edge while the label fits inside it. A label wider
|
|
45
|
+
* than its target instead grows from the target's left edge, unless that would
|
|
46
|
+
* leave the viewport. The final clamp is the safety net for edge targets and
|
|
47
|
+
* labels wider than the available viewport.
|
|
48
|
+
*/
|
|
49
|
+
export function resolvePreviewOverlayLabelHorizontalPosition({ targetLeft, targetWidth, labelWidth, viewportWidth, gap = PREVIEW_OVERLAY_LABEL_GAP_PX, }) {
|
|
50
|
+
const safeLabelWidth = Math.max(0, labelWidth);
|
|
51
|
+
const viewportRight = Math.max(gap, viewportWidth - gap);
|
|
52
|
+
const leftAnchoredPosition = targetLeft;
|
|
53
|
+
const rightAnchoredPosition = targetLeft + targetWidth - safeLabelWidth;
|
|
54
|
+
const leftAnchorFits = leftAnchoredPosition >= gap &&
|
|
55
|
+
leftAnchoredPosition + safeLabelWidth <= viewportRight;
|
|
56
|
+
const preferLeft = safeLabelWidth > targetWidth && leftAnchorFits;
|
|
57
|
+
const anchor = preferLeft ? 'left' : 'right';
|
|
58
|
+
const idealLeft = preferLeft ? leftAnchoredPosition : rightAnchoredPosition;
|
|
59
|
+
const maxLeft = Math.max(gap, viewportRight - safeLabelWidth);
|
|
60
|
+
return {
|
|
61
|
+
left: Math.min(Math.max(idealLeft, gap), maxLeft),
|
|
62
|
+
anchor,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function applyPreviewOverlayLabelVisualStyle(element, tone = 'default') {
|
|
66
|
+
const style = previewOverlayLabelVisualStyle(tone);
|
|
67
|
+
element.style.borderRadius = style.borderRadius;
|
|
68
|
+
element.style.padding = style.padding;
|
|
69
|
+
element.style.font = style.font;
|
|
70
|
+
element.style.color = style.color;
|
|
71
|
+
element.style.background = style.background;
|
|
72
|
+
element.style.boxShadow = style.boxShadow;
|
|
73
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type PreviewReadScopeEcho } from '@storystick/client/internal';
|
|
2
|
+
import type { PreviewReadContext } from '@storystick/types/preview-query-targeting';
|
|
3
|
+
import type { PublicProvenanceSidecar } from './sidecar.js';
|
|
4
|
+
import type { DirectEditLocator } from './direct-edit-locator.js';
|
|
5
|
+
import type { MarkerRecord } from './types.js';
|
|
6
|
+
import type { PreviewFrameDependencySet } from './frame-dependencies.js';
|
|
7
|
+
export interface AnchorInput {
|
|
8
|
+
readonly markerId: string;
|
|
9
|
+
/** Preview-only identity of one concrete paint target, including memory-backed coded text. */
|
|
10
|
+
readonly paintId?: string;
|
|
11
|
+
readonly tagName: string;
|
|
12
|
+
readonly text: string;
|
|
13
|
+
readonly connected: boolean;
|
|
14
|
+
readonly carrier?: 'attribute' | 'coded-text';
|
|
15
|
+
readonly documentRect?: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export type PreviewLifecycleSourceOfTruth = 'studio' | 'iframe' | 'system';
|
|
23
|
+
export interface PreviewRenderIdentity {
|
|
24
|
+
readonly generation: number;
|
|
25
|
+
readonly sourceOfTruth: PreviewLifecycleSourceOfTruth;
|
|
26
|
+
readonly commandId?: string;
|
|
27
|
+
readonly sessionId?: string;
|
|
28
|
+
readonly pathname?: string;
|
|
29
|
+
readonly routeHash?: string;
|
|
30
|
+
readonly codeVersion?: string;
|
|
31
|
+
readonly renderId?: string;
|
|
32
|
+
readonly variantId?: string | null;
|
|
33
|
+
readonly readContext?: PreviewReadContext;
|
|
34
|
+
readonly routeLocale?: string | null;
|
|
35
|
+
}
|
|
36
|
+
/** Exact local paint projection of the canonical render identity. */
|
|
37
|
+
export type PreviewPaintRenderIdentity = PreviewRenderIdentity & Required<Pick<PreviewRenderIdentity, 'sessionId' | 'pathname' | 'routeHash' | 'codeVersion' | 'renderId' | 'variantId'>>;
|
|
38
|
+
export type PreviewPaintRenderIdentityMismatch = 'session-id' | 'generation' | 'source-of-truth' | 'command-id' | 'pathname' | 'route-hash' | 'code-version' | 'render-id' | 'variant-id' | 'read-context' | 'route-locale';
|
|
39
|
+
export declare function previewPaintRenderIdentityEquals(left: PreviewPaintRenderIdentity, right: PreviewPaintRenderIdentity): boolean;
|
|
40
|
+
export declare function previewPaintRenderIdentityMismatch(left: PreviewPaintRenderIdentity, right: PreviewPaintRenderIdentity): PreviewPaintRenderIdentityMismatch | null;
|
|
41
|
+
export interface AnchorMap {
|
|
42
|
+
readonly sessionId: string;
|
|
43
|
+
readonly generation: number;
|
|
44
|
+
readonly sourceOfTruth: PreviewLifecycleSourceOfTruth;
|
|
45
|
+
readonly commandId?: string;
|
|
46
|
+
readonly pathname: string;
|
|
47
|
+
readonly routeHash: string;
|
|
48
|
+
readonly codeVersion: string;
|
|
49
|
+
readonly variantId: string | null;
|
|
50
|
+
readonly previewScope?: PreviewReadScopeEcho;
|
|
51
|
+
readonly renderId: string;
|
|
52
|
+
readonly renderNonce?: string;
|
|
53
|
+
readonly emissionRevision?: number;
|
|
54
|
+
readonly dependencySet?: PreviewFrameDependencySet;
|
|
55
|
+
readonly phase: string;
|
|
56
|
+
readonly pending: boolean;
|
|
57
|
+
readonly anchors: readonly AnchorInput[];
|
|
58
|
+
/** Public marker-to-owner addresses delivered with this exact render. */
|
|
59
|
+
readonly editLocators?: readonly DirectEditMarkerLocator[];
|
|
60
|
+
readonly sidecarMarkerIds: readonly string[];
|
|
61
|
+
readonly invalidMarkerIds: readonly string[];
|
|
62
|
+
/** Opaque sidecar marker ids absent from the rendered DOM, non-fatal. */
|
|
63
|
+
readonly unpaintedMarkerIds: readonly string[];
|
|
64
|
+
readonly missingMarkerIds: readonly string[];
|
|
65
|
+
readonly ambiguousMarkerIds: readonly string[];
|
|
66
|
+
readonly contentMismatchMarkerIds: readonly string[];
|
|
67
|
+
readonly fatalContentMismatchMarkerIds?: readonly string[];
|
|
68
|
+
readonly paintDiagnostics?: AnchorPaintDiagnostics;
|
|
69
|
+
readonly valid: boolean;
|
|
70
|
+
}
|
|
71
|
+
export interface DirectEditMarkerLocator {
|
|
72
|
+
readonly markerId: string;
|
|
73
|
+
readonly locator: DirectEditLocator;
|
|
74
|
+
readonly modality: MarkerRecord['modality'];
|
|
75
|
+
readonly presence?: MarkerRecord['presence'];
|
|
76
|
+
}
|
|
77
|
+
export interface AnchorPaintDiagnostics {
|
|
78
|
+
readonly codedTextOnlyNotPaintable: readonly string[];
|
|
79
|
+
readonly domTargetPainted: readonly string[];
|
|
80
|
+
}
|
|
81
|
+
export interface BuildAnchorMapInput {
|
|
82
|
+
readonly sessionId: string;
|
|
83
|
+
readonly generation: number;
|
|
84
|
+
readonly sourceOfTruth: PreviewLifecycleSourceOfTruth;
|
|
85
|
+
readonly commandId?: string;
|
|
86
|
+
readonly pathname: string;
|
|
87
|
+
readonly routeHash: string;
|
|
88
|
+
readonly codeVersion: string;
|
|
89
|
+
readonly variantId?: string | null;
|
|
90
|
+
readonly sidecar: PublicProvenanceSidecar;
|
|
91
|
+
readonly anchors: readonly AnchorInput[];
|
|
92
|
+
readonly phase: string;
|
|
93
|
+
readonly pending?: boolean;
|
|
94
|
+
}
|
|
95
|
+
export declare function buildAnchorMap(input: BuildAnchorMapInput): AnchorMap;
|