@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
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storystick Studio ↔ Preview iframe — postMessage protocol types.
|
|
3
|
+
*
|
|
4
|
+
* Authoritative reference for the protocol defined in
|
|
5
|
+
* storystick-hq/spec/preview-system.md §"Communication Protocol"
|
|
6
|
+
* storystick-hq/architecture/decisions/059-studio-shell-redesign.md §6
|
|
7
|
+
* storystick-hq/architecture/decisions/065-field-level-navigation-primitive.md §3.7
|
|
8
|
+
*
|
|
9
|
+
* Two orthogonal axes carried by the protocol itself:
|
|
10
|
+
*
|
|
11
|
+
* render-mode : 'navigation' | 'device'
|
|
12
|
+
* Controls iframe internal viewport (1280px vs device width),
|
|
13
|
+
* scale transform, pointer-events, and where overlays render
|
|
14
|
+
* (parent DOM vs in-iframe).
|
|
15
|
+
*
|
|
16
|
+
* overlay-mode : 'section' | 'field'
|
|
17
|
+
* Controls overlay granularity (slice boundary vs individual
|
|
18
|
+
* field). Independent of render-mode — pairings are defaults,
|
|
19
|
+
* not constraints.
|
|
20
|
+
*
|
|
21
|
+
* Click handling is NOT in this protocol — by design. ADR-065 owns the
|
|
22
|
+
* cross-frame navigation entry point. A child iframe posts the canonical
|
|
23
|
+
* `{ action: 'navigate', verb, value, from }` message exported from
|
|
24
|
+
* `@storystick/preview`. The Studio's field-navigation listener routes that
|
|
25
|
+
* target through the shared arrival service. PR2' does not duplicate it.
|
|
26
|
+
*
|
|
27
|
+
* Versioning convention
|
|
28
|
+
* ---------------------
|
|
29
|
+
* The protocol is a flat discriminated union on `type`. New
|
|
30
|
+
* variants extend the union; existing variants are never mutated.
|
|
31
|
+
* If a wire-level break is ever required, introduce a new top-level
|
|
32
|
+
* variant (e.g. `type: 'v2-section-bounds'`) rather than versioning
|
|
33
|
+
* the envelope. This keeps the runtime check trivially exhaustive
|
|
34
|
+
* via TypeScript's `never` narrowing.
|
|
35
|
+
*/
|
|
36
|
+
export type RenderMode = 'navigation' | 'device';
|
|
37
|
+
export type OverlayMode = 'section' | 'field';
|
|
38
|
+
/** Switch the iframe's render configuration. */
|
|
39
|
+
export interface MsgRenderMode {
|
|
40
|
+
type: 'render-mode';
|
|
41
|
+
mode: RenderMode;
|
|
42
|
+
/**
|
|
43
|
+
* ADR-119 D1/D3 — the Studio controller's instance-scoped
|
|
44
|
+
* generation counter. The SDK echoes it back verbatim on every
|
|
45
|
+
* `storystick.preview.form-contract` report so the controller can
|
|
46
|
+
* discard stale cross-doc async measurements soundly (the
|
|
47
|
+
* ratchet-class guard). Optional for legacy senders / tests; the
|
|
48
|
+
* SDK treats an absent epoch as `0`.
|
|
49
|
+
*/
|
|
50
|
+
epoch?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Experimental Studio-owned minimap projection. The customer keeps a
|
|
53
|
+
* regular 1440×900 viewport while the SDK temporarily compresses a bounded
|
|
54
|
+
* document window for Navigation paint. Absent/false preserves the existing
|
|
55
|
+
* Form contract and remains compatible with older Studio senders.
|
|
56
|
+
*/
|
|
57
|
+
windowedMinimapProjection?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Experimental provenance lifecycle mirror. This is distinct from
|
|
60
|
+
* `epoch`: `epoch` remains the ADR-119 viewport/snapshot ratchet,
|
|
61
|
+
* while `previewLifecycle` mirrors the Preview transition identity
|
|
62
|
+
* owned by Studio/ADR-143. Framework SDKs only echo/observe it.
|
|
63
|
+
*/
|
|
64
|
+
previewLifecycle?: {
|
|
65
|
+
readonly generation: number;
|
|
66
|
+
readonly sourceOfTruth: 'studio' | 'iframe' | 'system';
|
|
67
|
+
readonly commandId?: string | null;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export type StudioToIframe = MsgRenderMode | {
|
|
71
|
+
type: 'storystick.preview.windowed-minimap';
|
|
72
|
+
epoch: number;
|
|
73
|
+
windowStart: number;
|
|
74
|
+
renderSpan: number;
|
|
75
|
+
} | {
|
|
76
|
+
type: 'overlay-mode';
|
|
77
|
+
mode: OverlayMode;
|
|
78
|
+
} | {
|
|
79
|
+
type: 'highlight';
|
|
80
|
+
path: string;
|
|
81
|
+
} | {
|
|
82
|
+
type: 'scroll';
|
|
83
|
+
section: number;
|
|
84
|
+
} | {
|
|
85
|
+
type: 'device-width';
|
|
86
|
+
width: number;
|
|
87
|
+
} | {
|
|
88
|
+
type: 'storystick.preview.host-resize';
|
|
89
|
+
active: boolean;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Section bounding rects — emitted in Navigation mode by the
|
|
93
|
+
* `section-reporter` v2 runtime (ADR-112 D11). The observer
|
|
94
|
+
* triptyque (IntersectionObserver auxiliary + ResizeObserver +
|
|
95
|
+
* MutationObserver + `document.fonts.ready`) feeds a single rAF
|
|
96
|
+
* tick that publishes the full set.
|
|
97
|
+
*
|
|
98
|
+
* Coordinate space (ADR-112 D11b) — **document coordinates**, NOT
|
|
99
|
+
* viewport coordinates. `documentRect.{x,y}` is
|
|
100
|
+
* `getBoundingClientRect().{x,y} + window.scroll{X,Y}`, so the
|
|
101
|
+
* value is invariant under user scroll. Studio projects to its
|
|
102
|
+
* own visual pixels via
|
|
103
|
+
* `apps/studio/src/lib/preview-imperative-bridge.ts ::
|
|
104
|
+
* projectDocumentRectToStudio(documentRect, scrollTop, scrollLeft,
|
|
105
|
+
* scale)` — a non-optional `* scale` multiplication, since the
|
|
106
|
+
* iframe renders at logical CSS pixels and Studio displays a
|
|
107
|
+
* scaled mini-map.
|
|
108
|
+
*
|
|
109
|
+
* Wire-level rename (ADR-112 C4): field `rect` → `documentRect`.
|
|
110
|
+
* The break is intentional and loud — TypeScript fails compile on
|
|
111
|
+
* every legacy call site that wasn't migrated atomically.
|
|
112
|
+
*
|
|
113
|
+
* `DOMRect` does not survive structured-clone over postMessage in
|
|
114
|
+
* older browsers (Safari < 16). The SDK emits a plain
|
|
115
|
+
* `{ x, y, width, height }` shape that is structurally compatible
|
|
116
|
+
* with DOMRectReadOnly but JSON-safe.
|
|
117
|
+
*/
|
|
118
|
+
export interface SectionRect {
|
|
119
|
+
index: number;
|
|
120
|
+
documentRect: {
|
|
121
|
+
x: number;
|
|
122
|
+
y: number;
|
|
123
|
+
width: number;
|
|
124
|
+
height: number;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* ADR-125 D2/D3 (PR2) — a single annotated field's bounding rect. `path`
|
|
129
|
+
* is the walker-canonical field path (ADR-068 grammar) read off the
|
|
130
|
+
* element's `data-ss-field`, relative to its nearest `data-ss-doc`
|
|
131
|
+
* scope; `docId` is that scope (the originating document — propagated
|
|
132
|
+
* across resolved refs by the Proxy, so a click on a cross-doc fragment
|
|
133
|
+
* resolves to the right document). Same coordinate contract as
|
|
134
|
+
* `SectionRect` (document-relative, scroll-invariant).
|
|
135
|
+
*/
|
|
136
|
+
export interface FieldRect {
|
|
137
|
+
path: string;
|
|
138
|
+
docId: string | null;
|
|
139
|
+
documentRect: {
|
|
140
|
+
x: number;
|
|
141
|
+
y: number;
|
|
142
|
+
width: number;
|
|
143
|
+
height: number;
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* ADR-125 D2/D3 (PR2) — field-level bounding rects, emitted by the
|
|
148
|
+
* section-reporter v2 runtime in the SAME rAF-coalesced pass as
|
|
149
|
+
* `section-bounds` (ONE pipeline — not a forked one: same observer
|
|
150
|
+
* triptyque, same schedule, same `epoch` echo). The parent feeds this
|
|
151
|
+
* through the SAME generic D7 settle core + the SAME bounded fail-safe
|
|
152
|
+
* clock as section-bounds, keyed by the SAME ADR-119 controller
|
|
153
|
+
* generation. Sibling message (not a field added to `section-bounds`)
|
|
154
|
+
* purely so the section path PR1b shipped + cross-model-reviewed is
|
|
155
|
+
* byte-unchanged; the shared machinery is the anti-fork requirement,
|
|
156
|
+
* and it is shared.
|
|
157
|
+
*/
|
|
158
|
+
export interface MsgFieldBounds {
|
|
159
|
+
type: 'field-bounds';
|
|
160
|
+
/** Always `'document'` — identical posture + rationale as the
|
|
161
|
+
* `section-bounds` coordinate space. */
|
|
162
|
+
coordinateSpace: 'document';
|
|
163
|
+
fields: FieldRect[];
|
|
164
|
+
/** The `MsgRenderMode.epoch` last sent, echoed by the other geometry
|
|
165
|
+
* and form-contract messages (ADR-125 D7
|
|
166
|
+
* ratchet — a report whose epoch ≠ the live generation is
|
|
167
|
+
* discarded). */
|
|
168
|
+
epoch: number;
|
|
169
|
+
}
|
|
170
|
+
/** User completed a section drag-and-drop. */
|
|
171
|
+
export interface MsgDragEnd {
|
|
172
|
+
type: 'drag-end';
|
|
173
|
+
from: number;
|
|
174
|
+
to: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* ADR-131 §D8.1 — canonical `CoverageTier` tagged union. Single source
|
|
178
|
+
* of truth for "what does this field's coverage look like" surfaced to
|
|
179
|
+
* the Coverage Panel + Studio overlay paint projection (§D8.4).
|
|
180
|
+
*
|
|
181
|
+
* Bound tiers (`explicit`, `observed`) PAINT overlays. `unsupported`
|
|
182
|
+
* records an annotation-model gap; `pending` and `stale` remain generic
|
|
183
|
+
* ambient states for the future Coverage Panel (zero producer today).
|
|
184
|
+
*
|
|
185
|
+
* Owner decision, 2026-08-10: the measurement vocabulary was retired.
|
|
186
|
+
* Field identity is authored by SDK annotations, never inferred from DOM
|
|
187
|
+
* output. Adding a new annotation tier is additive; reintroducing a
|
|
188
|
+
* measurement tier requires an explicit owner decision.
|
|
189
|
+
*/
|
|
190
|
+
export type CoverageTier = {
|
|
191
|
+
kind: 'explicit';
|
|
192
|
+
} | {
|
|
193
|
+
kind: 'observed';
|
|
194
|
+
} | {
|
|
195
|
+
kind: 'unsupported';
|
|
196
|
+
reason: 'no-annotation-carrier' | 'annotation-not-forwarded' | 'non-dom-output';
|
|
197
|
+
} | {
|
|
198
|
+
kind: 'pending';
|
|
199
|
+
since: number;
|
|
200
|
+
} | {
|
|
201
|
+
kind: 'stale';
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* ADR-129 — one item in the atomic preview snapshot. `method` carries
|
|
205
|
+
* the live authored (`explicit`) and provenance (`observed`) paths;
|
|
206
|
+
* `tier` carries their coverage semantics. ADR-138 §5.5 + ADR-139 §2.5
|
|
207
|
+
* extend the wire further with the anchor-typed fields below
|
|
208
|
+
* (`anchorKind`, `anchorKey`, `anchoredPath`),
|
|
209
|
+
* additive optional in v1 ; producers (ADR-140 walker) populate them
|
|
210
|
+
* as the cache-write layer lands. `method` records WHICH RESOLVER
|
|
211
|
+
* PRIORITY SLOT produced this item (provenance signal for the
|
|
212
|
+
* preview-surface gate); `tier` records the COVERAGE SEMANTICS surfaced
|
|
213
|
+
* to the panel + the paint projection at §D8.4. The two unions are NOT
|
|
214
|
+
* congruent (panel-only states have no `method`); both ship.
|
|
215
|
+
*
|
|
216
|
+
* Identity is `(documentId, anchored-canonical-path)` — D1. `path` is
|
|
217
|
+
* the numeric canonical path; `fromAnchors` carries the `_key` of each
|
|
218
|
+
* keyed array hop so the Studio resolver's `substituteAnchors` consumes
|
|
219
|
+
* it with no grammar change (ADR-066 transport shape).
|
|
220
|
+
*/
|
|
221
|
+
export interface SnapshotItem {
|
|
222
|
+
kind: 'slice' | 'field';
|
|
223
|
+
/**
|
|
224
|
+
* ADR-142 P0/P1 — iframe-produced sidecar lookup key for in-iframe
|
|
225
|
+
* Preview field painting. Opaque to Studio. This is NOT the Studio
|
|
226
|
+
* paint generation key; Studio mints `paintKey` when it sends an
|
|
227
|
+
* approved overlay-map back to the iframe.
|
|
228
|
+
*/
|
|
229
|
+
snapshotItemKey?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Resolver-provenance signal (ADR-131 §D6.1):
|
|
232
|
+
* - `'explicit'` — Layer 3 `data-ss-bind` attribute (was `'binding'`).
|
|
233
|
+
* - `'observed'` — live coded-text provenance owner-map producer.
|
|
234
|
+
*/
|
|
235
|
+
method: 'explicit' | 'observed';
|
|
236
|
+
/**
|
|
237
|
+
* Field-ownership / routing identity (ADR-139 §2.5). The doc the
|
|
238
|
+
* Studio click route opens. For Tier-1 explicit `<edit.* doc="X">`
|
|
239
|
+
* this is the customer-declared owner ; for cross-doc observed entries
|
|
240
|
+
* it may differ from the host page's doc.
|
|
241
|
+
*/
|
|
242
|
+
documentId: string;
|
|
243
|
+
/**
|
|
244
|
+
* The `_key` of the owning slice (the snapshot↔island join key).
|
|
245
|
+
* PRESENT when `anchorKind === 'slice'` or absent (`'slice'`-by-
|
|
246
|
+
* construction items always set this) ; OMITTED when
|
|
247
|
+
* `anchorKind === 'doc'` or `'document-root'` per ADR-138 §5.5.
|
|
248
|
+
*
|
|
249
|
+
* The walker (ADR-140 §2.8) drives the optionality : for cross-doc /
|
|
250
|
+
* chrome items whose anchor is a `[data-ss-doc]` marker or the
|
|
251
|
+
* document root, there is no slice key, so emitting the empty string
|
|
252
|
+
* would mis-key downstream consumers ; emitting `undefined` makes
|
|
253
|
+
* the absence syntactic.
|
|
254
|
+
*/
|
|
255
|
+
sliceKey?: string;
|
|
256
|
+
/** Numeric canonical path — `sections[0]` (slice) | `sections[0].headline` (field). */
|
|
257
|
+
path: string;
|
|
258
|
+
/** ADR-066 keyed-hop anchors for `path` (the slice `_key` hop). */
|
|
259
|
+
fromAnchors: ReadonlyArray<{
|
|
260
|
+
pathPrefix: string;
|
|
261
|
+
key: string;
|
|
262
|
+
}>;
|
|
263
|
+
/**
|
|
264
|
+
* Optional mounted Studio navigation path. C4 nested zone-container
|
|
265
|
+
* overlays keep `path` as the visual ancestry (`sections[0].sidebar[1]`)
|
|
266
|
+
* while Studio mounts the widget at the mapped document field
|
|
267
|
+
* (`sidebar[1]`). When omitted, `path` is already routable.
|
|
268
|
+
*/
|
|
269
|
+
navigationPath?: string;
|
|
270
|
+
/** Keyed-hop anchors for `navigationPath`; omitted when `path` is routable. */
|
|
271
|
+
navigationAnchors?: ReadonlyArray<{
|
|
272
|
+
pathPrefix: string;
|
|
273
|
+
key: string;
|
|
274
|
+
}>;
|
|
275
|
+
/** Schema-relative field path; `''` for a `slice` item. */
|
|
276
|
+
field: string;
|
|
277
|
+
/** Document-space rect (`getBoundingClientRect` + scroll) — scroll-invariant. */
|
|
278
|
+
documentRect: {
|
|
279
|
+
x: number;
|
|
280
|
+
y: number;
|
|
281
|
+
width: number;
|
|
282
|
+
height: number;
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* ADR-131 §D6.5 — canonical coverage tier surfaced to the Coverage
|
|
286
|
+
* Panel + the §D8.4 `tierToVisualStyle(tier, devModeFlag)` paint
|
|
287
|
+
* projection. `method` (above) is the resolver-provenance signal;
|
|
288
|
+
* this is the coverage semantics. Both ship on the wire.
|
|
289
|
+
*/
|
|
290
|
+
tier: CoverageTier;
|
|
291
|
+
/**
|
|
292
|
+
* ADR-138 §5.3 + ADR-139 §2.5 — DOM-marker / paint-identity discriminator.
|
|
293
|
+
* When set, narrows how the resolver locates the anchor element:
|
|
294
|
+
* - `'slice'` — DOM lookup via `[data-ss-slice="<anchorKey>"]` ;
|
|
295
|
+
* `anchorKey` is the slice `_key`.
|
|
296
|
+
* - `'doc'` — DOM lookup via `[data-ss-doc="<anchorKey>"]` ;
|
|
297
|
+
* `anchorKey` is the doc id of the host marker.
|
|
298
|
+
* ADR-139 §2.5 relaxes the §2.6 invariant
|
|
299
|
+
* `anchorKey === documentId` ; `anchorKey` is
|
|
300
|
+
* orthogonal to `documentId` (the latter remains
|
|
301
|
+
* field-ownership / routing identity).
|
|
302
|
+
* - `'document-root'` — DOM lookup via `document.body` ; `anchorKey` is
|
|
303
|
+
* the empty string per ADR-138 §2 table.
|
|
304
|
+
*
|
|
305
|
+
* Additive optional in v1 — pre-138 items omit it ; v2+ producers
|
|
306
|
+
* (ADR-140 walker) populate.
|
|
307
|
+
*/
|
|
308
|
+
anchorKind?: 'slice' | 'doc' | 'document-root';
|
|
309
|
+
/**
|
|
310
|
+
* DOM-marker key per `anchorKind` (see above). When `anchorKind ===
|
|
311
|
+
* 'document-root'` the value is the empty string (the unique
|
|
312
|
+
* `<body>` is implicit). When `anchorKind === 'doc'` the value lives
|
|
313
|
+
* in the Studio-authoritative document set per ADR-139 §2.3 (the
|
|
314
|
+
* gate validates membership). Additive optional in v1.
|
|
315
|
+
*/
|
|
316
|
+
anchorKey?: string;
|
|
317
|
+
/**
|
|
318
|
+
* ADR-138 §5.5 — anchored path relative to the anchor element. The
|
|
319
|
+
* resolver walks from the anchor element along this path during the
|
|
320
|
+
* per-rAF DOM scan (ADR-140 territory). Additive optional in v1.
|
|
321
|
+
*/
|
|
322
|
+
anchoredPath?: string | null;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* ADR-129 D6 — the ATOMIC preview snapshot. One message per render
|
|
326
|
+
* carries everything the Studio overlay layer needs: the controller
|
|
327
|
+
* `epoch` (echoed from `MsgRenderMode`), the customer-side `renderId`
|
|
328
|
+
* (from the model island), the `pageDocId` the iframe is showing, the
|
|
329
|
+
* set of documentIds present, and every overlay `item`. `codeVersion`
|
|
330
|
+
* carries the upstream build signature and `timestamp` records the
|
|
331
|
+
* producing rAF tick.
|
|
332
|
+
*/
|
|
333
|
+
export interface MsgPreviewSnapshot {
|
|
334
|
+
type: 'storystick.preview.snapshot';
|
|
335
|
+
epoch: number;
|
|
336
|
+
renderId: string;
|
|
337
|
+
pageDocId: string;
|
|
338
|
+
/**
|
|
339
|
+
* Optional forward-capability bitmap. Studio must not send newer
|
|
340
|
+
* overlay-map item keys back to runtimes that did not explicitly
|
|
341
|
+
* advertise support for them because older SDK validators reject
|
|
342
|
+
* unknown keys with a strict allowlist.
|
|
343
|
+
*/
|
|
344
|
+
capabilities?: {
|
|
345
|
+
crossDocumentOverlayLabels?: true;
|
|
346
|
+
};
|
|
347
|
+
/**
|
|
348
|
+
* ADR-139 §2.1 + §5 — formerly `visibleDocumentIds`, renamed at the
|
|
349
|
+
* wire level (codex R2 P1#3 absorbed at the ADR layer). The field is
|
|
350
|
+
* NEVER consulted by the Studio anti-bleed gate ; ADR-139 ships a
|
|
351
|
+
* Studio-side `authoritativeSet` derivation (`useAuthoritativeDocSet`)
|
|
352
|
+
* that composes membership from four trusted sources (commandedDoc +
|
|
353
|
+
* Studio-side chrome enumeration + Studio-side page-closure walker +
|
|
354
|
+
* SDK transport tap via `previewSessions.knownDocuments`). The
|
|
355
|
+
* iframe-declared set survives only as a debug hint surfaced to the
|
|
356
|
+
* Coverage Panel + harness — the rename makes the non-authoritative
|
|
357
|
+
* role syntactic ; a future producer cannot accidentally consult it
|
|
358
|
+
* for a trust decision because the name itself denies it. Pre-launch
|
|
359
|
+
* posture per the monorepo CLAUDE.md "no legacy support" rule —
|
|
360
|
+
* pre-rename `visibleDocumentIds` is removed entirely (no deprecation
|
|
361
|
+
* period).
|
|
362
|
+
*/
|
|
363
|
+
iframeDeclaredDocumentIdsDebugHint: string[];
|
|
364
|
+
items: SnapshotItem[];
|
|
365
|
+
/**
|
|
366
|
+
* ADR-131 §D7.1a — upstream build/schema/config signature the iframe
|
|
367
|
+
* was hydrated with. Studio controller compares
|
|
368
|
+
* `snapshot.codeVersion !== controller.codeVersion` to detect a
|
|
369
|
+
* customer redeploy mid-stream (§D5.7).
|
|
370
|
+
*/
|
|
371
|
+
codeVersion: string;
|
|
372
|
+
/**
|
|
373
|
+
* ADR-131 §D3.2 — Unix millis (Date.now()) at the rAF tick that
|
|
374
|
+
* produced this snapshot. The iframe correlation-window sampler
|
|
375
|
+
* subtracts the `T_edit` postMessage receipt timestamp to feed the
|
|
376
|
+
* EMA-based adaptive correlation window.
|
|
377
|
+
*/
|
|
378
|
+
timestamp: number;
|
|
379
|
+
/**
|
|
380
|
+
* ADR-131 amendment-003 + ADR-139 §5.5 — SHA-256 hex of the live
|
|
381
|
+
* customer `routeUrl` the iframe is rendering against (post-redirect,
|
|
382
|
+
* NOT the bootstrap URL). Iframe-side `computeRouteHash` is the
|
|
383
|
+
* authoritative producer ; the Studio reads this verbatim and threads
|
|
384
|
+
* it into `useAuthoritativeDocSet` (which feeds
|
|
385
|
+
* `previewSessions.knownDocuments`). The Studio MUST NOT recompute
|
|
386
|
+
* from its own `effectiveSrc` (the iframe `src` attribute), which
|
|
387
|
+
* during the normal boot flow points at the preview-route bootstrap
|
|
388
|
+
* (`/api/storystick/preview?...redirect=...`) ; hashing the bootstrap
|
|
389
|
+
* URL would key a different `(sessionId, routeHash, codeVersion)`
|
|
390
|
+
* row than the SDK transport-tap wrote, and the gate would silently
|
|
391
|
+
* drop legitimate cross-doc overlays (codex R1 P1#2 absorbed).
|
|
392
|
+
*
|
|
393
|
+
* Optional in v1 because pre-amendment-003 runtimes never produced
|
|
394
|
+
* the field ; an absent value forces the Studio hook to pass `'skip'`
|
|
395
|
+
* to `knownDocuments`. The Studio treats `undefined` / `''` /
|
|
396
|
+
* pre-emit as "no SDK-tap data yet" (correct degradation : the gate
|
|
397
|
+
* doesn't paint cross-doc overlays until the iframe has a real route
|
|
398
|
+
* hash to report).
|
|
399
|
+
*/
|
|
400
|
+
routeHash?: string;
|
|
401
|
+
/**
|
|
402
|
+
* Live customer URL the iframe is rendering against (post-redirect,
|
|
403
|
+
* NOT the Studio iframe `src` bootstrap URL). Studio uses this as
|
|
404
|
+
* debug context and to keep route-scoped document observations aligned.
|
|
405
|
+
*/
|
|
406
|
+
routeUrl?: string;
|
|
407
|
+
}
|
|
408
|
+
export type IframeToStudio = {
|
|
409
|
+
type: 'ready';
|
|
410
|
+
} | {
|
|
411
|
+
type: 'section-bounds';
|
|
412
|
+
coordinateSpace: 'document';
|
|
413
|
+
sections: SectionRect[];
|
|
414
|
+
epoch: number;
|
|
415
|
+
} | MsgFieldBounds | {
|
|
416
|
+
type: 'section-hover';
|
|
417
|
+
index: number | null;
|
|
418
|
+
} | {
|
|
419
|
+
type: 'sections';
|
|
420
|
+
data: unknown[];
|
|
421
|
+
} | MsgDragEnd | {
|
|
422
|
+
type: 'add-section';
|
|
423
|
+
index: number;
|
|
424
|
+
} | {
|
|
425
|
+
type: 'storystick.preview.form-contract';
|
|
426
|
+
epoch: number;
|
|
427
|
+
applied: boolean;
|
|
428
|
+
pageHeight: number;
|
|
429
|
+
viewportHeight: number;
|
|
430
|
+
windowedProjection?: 'pending' | 'active' | 'unsupported';
|
|
431
|
+
windowedProjectionReason?: string;
|
|
432
|
+
windowStart?: number;
|
|
433
|
+
renderSpan?: number;
|
|
434
|
+
compression?: number;
|
|
435
|
+
} | MsgPreviewSnapshot;
|
|
436
|
+
/**
|
|
437
|
+
* Best-effort runtime guard for messages the iframe sends to the
|
|
438
|
+
* Studio. Used by the bridge to ignore unrelated postMessage events
|
|
439
|
+
* (extensions, devtools, third-party scripts) without throwing.
|
|
440
|
+
*
|
|
441
|
+
* The discriminator (`type` string) is the only thing we trust — we
|
|
442
|
+
* narrow with the union after this guard.
|
|
443
|
+
*/
|
|
444
|
+
export declare function isIframeToStudio(value: unknown): value is IframeToStudio;
|
|
445
|
+
/** Mirror guard for Studio → iframe (used iframe-side). */
|
|
446
|
+
export declare function isStudioToIframe(value: unknown): value is StudioToIframe;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storystick Studio ↔ Preview iframe — postMessage protocol types.
|
|
3
|
+
*
|
|
4
|
+
* Authoritative reference for the protocol defined in
|
|
5
|
+
* storystick-hq/spec/preview-system.md §"Communication Protocol"
|
|
6
|
+
* storystick-hq/architecture/decisions/059-studio-shell-redesign.md §6
|
|
7
|
+
* storystick-hq/architecture/decisions/065-field-level-navigation-primitive.md §3.7
|
|
8
|
+
*
|
|
9
|
+
* Two orthogonal axes carried by the protocol itself:
|
|
10
|
+
*
|
|
11
|
+
* render-mode : 'navigation' | 'device'
|
|
12
|
+
* Controls iframe internal viewport (1280px vs device width),
|
|
13
|
+
* scale transform, pointer-events, and where overlays render
|
|
14
|
+
* (parent DOM vs in-iframe).
|
|
15
|
+
*
|
|
16
|
+
* overlay-mode : 'section' | 'field'
|
|
17
|
+
* Controls overlay granularity (slice boundary vs individual
|
|
18
|
+
* field). Independent of render-mode — pairings are defaults,
|
|
19
|
+
* not constraints.
|
|
20
|
+
*
|
|
21
|
+
* Click handling is NOT in this protocol — by design. ADR-065 owns the
|
|
22
|
+
* cross-frame navigation entry point. A child iframe posts the canonical
|
|
23
|
+
* `{ action: 'navigate', verb, value, from }` message exported from
|
|
24
|
+
* `@storystick/preview`. The Studio's field-navigation listener routes that
|
|
25
|
+
* target through the shared arrival service. PR2' does not duplicate it.
|
|
26
|
+
*
|
|
27
|
+
* Versioning convention
|
|
28
|
+
* ---------------------
|
|
29
|
+
* The protocol is a flat discriminated union on `type`. New
|
|
30
|
+
* variants extend the union; existing variants are never mutated.
|
|
31
|
+
* If a wire-level break is ever required, introduce a new top-level
|
|
32
|
+
* variant (e.g. `type: 'v2-section-bounds'`) rather than versioning
|
|
33
|
+
* the envelope. This keeps the runtime check trivially exhaustive
|
|
34
|
+
* via TypeScript's `never` narrowing.
|
|
35
|
+
*/
|
|
36
|
+
// ─── Type guards ─────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Best-effort runtime guard for messages the iframe sends to the
|
|
39
|
+
* Studio. Used by the bridge to ignore unrelated postMessage events
|
|
40
|
+
* (extensions, devtools, third-party scripts) without throwing.
|
|
41
|
+
*
|
|
42
|
+
* The discriminator (`type` string) is the only thing we trust — we
|
|
43
|
+
* narrow with the union after this guard.
|
|
44
|
+
*/
|
|
45
|
+
export function isIframeToStudio(value) {
|
|
46
|
+
if (!value || typeof value !== 'object')
|
|
47
|
+
return false;
|
|
48
|
+
const v = value;
|
|
49
|
+
if (typeof v.type !== 'string')
|
|
50
|
+
return false;
|
|
51
|
+
switch (v.type) {
|
|
52
|
+
case 'ready':
|
|
53
|
+
case 'section-bounds':
|
|
54
|
+
case 'field-bounds':
|
|
55
|
+
case 'section-hover':
|
|
56
|
+
case 'sections':
|
|
57
|
+
case 'drag-end':
|
|
58
|
+
case 'add-section':
|
|
59
|
+
case 'storystick.preview.form-contract':
|
|
60
|
+
case 'storystick.preview.snapshot':
|
|
61
|
+
return true;
|
|
62
|
+
default:
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Mirror guard for Studio → iframe (used iframe-side). */
|
|
67
|
+
export function isStudioToIframe(value) {
|
|
68
|
+
if (!value || typeof value !== 'object')
|
|
69
|
+
return false;
|
|
70
|
+
const v = value;
|
|
71
|
+
if (typeof v.type !== 'string')
|
|
72
|
+
return false;
|
|
73
|
+
switch (v.type) {
|
|
74
|
+
case 'render-mode':
|
|
75
|
+
case 'storystick.preview.windowed-minimap':
|
|
76
|
+
case 'overlay-mode':
|
|
77
|
+
case 'highlight':
|
|
78
|
+
case 'scroll':
|
|
79
|
+
case 'device-width':
|
|
80
|
+
case 'storystick.preview.host-resize':
|
|
81
|
+
return true;
|
|
82
|
+
default:
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Iframe-side preview-envelope validators (ADR-087 §3.2).
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around `validatePreviewEnvelope` from
|
|
5
|
+
* `@storystick/transport-allowlist` (the foundation Lane C shipped).
|
|
6
|
+
* Adds the iframe-side context checks the foundation deliberately left out:
|
|
7
|
+
*
|
|
8
|
+
* - `sessionId` and `projectId` match the iframe's known values
|
|
9
|
+
* (they should never change mid-session).
|
|
10
|
+
* - `event.origin === parentOrigin` once the parent origin is
|
|
11
|
+
* learned (see "learn-and-lock" comment below).
|
|
12
|
+
*
|
|
13
|
+
* The foundation validator owns structure + anti-replay base
|
|
14
|
+
* (`MAX_ENVELOPE_AGE_MS`) + normative error wording. This module owns
|
|
15
|
+
* everything that needs *iframe context*: identity and the locked parent
|
|
16
|
+
* origin.
|
|
17
|
+
*
|
|
18
|
+
* Returning a discriminated `{ ok, ... }` keeps the call-site clean —
|
|
19
|
+
* the consumer handles `ok: false` by either ignoring the message
|
|
20
|
+
* (stale / mis-correlated) or transitioning to `error` (auth failed).
|
|
21
|
+
*/
|
|
22
|
+
import { type NavigateEnvelope, type PreviewOverlayClearEnvelope, type PreviewOverlayMapEnvelope, type PreviewV2RevealSourceEnvelope } from '@storystick/transport-allowlist';
|
|
23
|
+
/**
|
|
24
|
+
* Reasons a context-aware validation can fail. Strings are stable —
|
|
25
|
+
* the state machine + tests grep on them. They surface only in
|
|
26
|
+
* iframe-internal logs; NEVER over the postMessage wire (the iframe
|
|
27
|
+
* → parent direction silent on rejections).
|
|
28
|
+
*/
|
|
29
|
+
export type ValidationFailure = 'envelope-invalid' | 'wrong-message-type' | 'origin-mismatch' | 'session-id-mismatch' | 'project-id-mismatch';
|
|
30
|
+
export type ValidationResult<T> = {
|
|
31
|
+
ok: true;
|
|
32
|
+
envelope: T;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
reason: ValidationFailure;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Validate an incoming `navigate` envelope against the locked parent
|
|
39
|
+
* origin and the iframe's known sessionId / projectId. Navigate
|
|
40
|
+
* messages are unsolicited (no pending request to correlate against)
|
|
41
|
+
* — we only check origin lock + identity binding.
|
|
42
|
+
*
|
|
43
|
+
* **Pre-lock policy (codex Lane D round 1 P1 fix)** : `parentOrigin
|
|
44
|
+
* === null` means the iframe has not yet locked Studio's origin.
|
|
45
|
+
* Navigate messages received in that window are rejected
|
|
46
|
+
* unconditionally (`origin-mismatch`). Without this, any same-host
|
|
47
|
+
* script with a valid envelope shape could drive `history.pushState`
|
|
48
|
+
* on the iframe before the legitimate Studio handshake finishes.
|
|
49
|
+
* The identity broadcast is the only origin-learning path; navigation MUST
|
|
50
|
+
* wait for that lock.
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateNavigate(raw: unknown, eventOrigin: string, knownSessionId: string, knownProjectId: string, parentOrigin: string | null, now?: number): ValidationResult<NavigateEnvelope>;
|
|
53
|
+
export declare function validateOverlayMap(raw: unknown, eventOrigin: string, knownSessionId: string, knownProjectId: string, parentOrigin: string | null, now?: number): ValidationResult<PreviewOverlayMapEnvelope>;
|
|
54
|
+
export declare function validateOverlayClear(raw: unknown, eventOrigin: string, knownSessionId: string, knownProjectId: string, parentOrigin: string | null, now?: number): ValidationResult<PreviewOverlayClearEnvelope>;
|
|
55
|
+
export declare function validatePreviewV2RevealSource(raw: unknown, eventOrigin: string, knownSessionId: string, knownProjectId: string, parentOrigin: string | null, now?: number): ValidationResult<PreviewV2RevealSourceEnvelope>;
|
|
56
|
+
/**
|
|
57
|
+
* Re-export so consumers can import the foundation types from one
|
|
58
|
+
* place. Keeping the wrapper module the surface helps grepping for
|
|
59
|
+
* preview-envelope usage during audits.
|
|
60
|
+
*/
|
|
61
|
+
export type { NavigateEnvelope, PreviewOverlayClearEnvelope, PreviewOverlayMapEnvelope, };
|