@forgecart/designer-runtime 1.0.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/README.md +166 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/loader-cjs/package.json +3 -0
- package/dist/loader-cjs/turbo-loader.d.ts +13 -0
- package/dist/loader-cjs/turbo-loader.js +190 -0
- package/dist/loader-cjs/turbo-loader.js.map +1 -0
- package/dist/protocol/element-reference-formatter.d.ts +28 -0
- package/dist/protocol/element-reference-formatter.js +60 -0
- package/dist/protocol/element-reference-formatter.js.map +1 -0
- package/dist/protocol/element.types.d.ts +75 -0
- package/dist/protocol/element.types.js +7 -0
- package/dist/protocol/element.types.js.map +1 -0
- package/dist/protocol/index.d.ts +5 -0
- package/dist/protocol/index.js +6 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/message-codec.d.ts +50 -0
- package/dist/protocol/message-codec.js +209 -0
- package/dist/protocol/message-codec.js.map +1 -0
- package/dist/protocol/message.types.d.ts +122 -0
- package/dist/protocol/message.types.js +2 -0
- package/dist/protocol/message.types.js.map +1 -0
- package/dist/protocol/protocol.constant.d.ts +30 -0
- package/dist/protocol/protocol.constant.js +31 -0
- package/dist/protocol/protocol.constant.js.map +1 -0
- package/dist/runtime/descriptor/element-descriptor-extractor.d.ts +38 -0
- package/dist/runtime/descriptor/element-descriptor-extractor.js +190 -0
- package/dist/runtime/descriptor/element-descriptor-extractor.js.map +1 -0
- package/dist/runtime/designer-runtime.d.ts +85 -0
- package/dist/runtime/designer-runtime.js +321 -0
- package/dist/runtime/designer-runtime.js.map +1 -0
- package/dist/runtime/guest-messenger.d.ts +37 -0
- package/dist/runtime/guest-messenger.js +41 -0
- package/dist/runtime/guest-messenger.js.map +1 -0
- package/dist/runtime/handshake-gate.d.ts +35 -0
- package/dist/runtime/handshake-gate.js +81 -0
- package/dist/runtime/handshake-gate.js.map +1 -0
- package/dist/runtime/highlight/highlight-overlay.d.ts +25 -0
- package/dist/runtime/highlight/highlight-overlay.js +80 -0
- package/dist/runtime/highlight/highlight-overlay.js.map +1 -0
- package/dist/runtime/region/dom-hit-tester.d.ts +28 -0
- package/dist/runtime/region/dom-hit-tester.js +45 -0
- package/dist/runtime/region/dom-hit-tester.js.map +1 -0
- package/dist/runtime/region/element-filter.d.ts +60 -0
- package/dist/runtime/region/element-filter.js +146 -0
- package/dist/runtime/region/element-filter.js.map +1 -0
- package/dist/runtime/region/region-sampler.d.ts +41 -0
- package/dist/runtime/region/region-sampler.js +100 -0
- package/dist/runtime/region/region-sampler.js.map +1 -0
- package/dist/runtime/region/spray-region-resolver.d.ts +53 -0
- package/dist/runtime/region/spray-region-resolver.js +113 -0
- package/dist/runtime/region/spray-region-resolver.js.map +1 -0
- package/dist/util/geometry.util.d.ts +29 -0
- package/dist/util/geometry.util.js +68 -0
- package/dist/util/geometry.util.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { GuestMessage, HostMessage } from './message.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Structural decoder for the wire protocol. Both sides receive arbitrary
|
|
4
|
+
* `message` events (payment SDKs, analytics pixels, HMR sockets), so every
|
|
5
|
+
* payload is treated as `unknown` and validated field by field — no casts.
|
|
6
|
+
* Anything that fails validation parses to null; the caller decides whether
|
|
7
|
+
* that is silence (foreign traffic) or an INVALID_MESSAGE error (namespaced
|
|
8
|
+
* traffic with a malformed payload).
|
|
9
|
+
*/
|
|
10
|
+
export declare class MessageCodec {
|
|
11
|
+
private readonly hostValidators;
|
|
12
|
+
private readonly guestValidators;
|
|
13
|
+
/** Parses a host→guest payload; null for foreign or malformed traffic. */
|
|
14
|
+
parseHostMessage(data: unknown): HostMessage | null;
|
|
15
|
+
/** Parses a guest→host payload; null for foreign or malformed traffic. */
|
|
16
|
+
parseGuestMessage(data: unknown): GuestMessage | null;
|
|
17
|
+
/**
|
|
18
|
+
* True when the payload claims our namespace, regardless of validity.
|
|
19
|
+
* Lets the runtime distinguish "foreign traffic — stay silent" from
|
|
20
|
+
* "namespaced but malformed — answer with INVALID_MESSAGE".
|
|
21
|
+
*/
|
|
22
|
+
hasProtocolNamespace(data: unknown): boolean;
|
|
23
|
+
private isHostMessage;
|
|
24
|
+
private isGuestMessage;
|
|
25
|
+
private isEnvelopedRecord;
|
|
26
|
+
private isRecord;
|
|
27
|
+
private isString;
|
|
28
|
+
private isStringOrNull;
|
|
29
|
+
private isNonEmptyString;
|
|
30
|
+
private isFiniteNumber;
|
|
31
|
+
private isPositiveNumber;
|
|
32
|
+
private isOptionalPositiveNumber;
|
|
33
|
+
private isStringArray;
|
|
34
|
+
private isPoint;
|
|
35
|
+
private isPointArray;
|
|
36
|
+
private isViewport;
|
|
37
|
+
private isRect;
|
|
38
|
+
private isCapabilities;
|
|
39
|
+
private isBoundsEntryArray;
|
|
40
|
+
private isBoundsEntry;
|
|
41
|
+
private isElementDescriptorArray;
|
|
42
|
+
private isElementDescriptor;
|
|
43
|
+
private hasDescriptorIdentity;
|
|
44
|
+
private hasDescriptorContent;
|
|
45
|
+
private hasDescriptorGeometry;
|
|
46
|
+
private isDomPath;
|
|
47
|
+
private isDomPathSegment;
|
|
48
|
+
private isSourceRefOrNull;
|
|
49
|
+
private isStringRecord;
|
|
50
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { PROTOCOL_NAMESPACE, PROTOCOL_VERSION } from './protocol.constant.js';
|
|
2
|
+
const RUNTIME_ERROR_CODES = new Set([
|
|
3
|
+
'INVALID_MESSAGE',
|
|
4
|
+
'NOT_ACTIVE',
|
|
5
|
+
'REGION_TOO_LARGE',
|
|
6
|
+
'UNKNOWN_REF',
|
|
7
|
+
'INTERNAL',
|
|
8
|
+
]);
|
|
9
|
+
/**
|
|
10
|
+
* Structural decoder for the wire protocol. Both sides receive arbitrary
|
|
11
|
+
* `message` events (payment SDKs, analytics pixels, HMR sockets), so every
|
|
12
|
+
* payload is treated as `unknown` and validated field by field — no casts.
|
|
13
|
+
* Anything that fails validation parses to null; the caller decides whether
|
|
14
|
+
* that is silence (foreign traffic) or an INVALID_MESSAGE error (namespaced
|
|
15
|
+
* traffic with a malformed payload).
|
|
16
|
+
*/
|
|
17
|
+
export class MessageCodec {
|
|
18
|
+
hostValidators = new Map([
|
|
19
|
+
['HELLO', (m) => this.isNonEmptyString(m.nonce) && this.isFiniteNumber(m.protocolVersion)],
|
|
20
|
+
['ACTIVATE', () => true],
|
|
21
|
+
['DEACTIVATE', () => true],
|
|
22
|
+
['PING', () => true],
|
|
23
|
+
[
|
|
24
|
+
'REGION_SELECT',
|
|
25
|
+
(m) => this.isNonEmptyString(m.requestId) &&
|
|
26
|
+
this.isPointArray(m.stroke) &&
|
|
27
|
+
this.isPositiveNumber(m.radius) &&
|
|
28
|
+
this.isOptionalPositiveNumber(m.maxElements),
|
|
29
|
+
],
|
|
30
|
+
['HIGHLIGHT_SET', (m) => this.isStringArray(m.refIds)],
|
|
31
|
+
['HIGHLIGHT_CLEAR', () => true],
|
|
32
|
+
[
|
|
33
|
+
'ELEMENT_BOUNDS_QUERY',
|
|
34
|
+
(m) => this.isNonEmptyString(m.requestId) && this.isStringArray(m.refIds),
|
|
35
|
+
],
|
|
36
|
+
]);
|
|
37
|
+
guestValidators = new Map([
|
|
38
|
+
['READY', () => true],
|
|
39
|
+
[
|
|
40
|
+
'HELLO_ACK',
|
|
41
|
+
(m) => this.isCapabilities(m.capabilities) &&
|
|
42
|
+
this.isString(m.url) &&
|
|
43
|
+
this.isViewport(m.viewport),
|
|
44
|
+
],
|
|
45
|
+
['ACTIVATED', () => true],
|
|
46
|
+
['DEACTIVATED', () => true],
|
|
47
|
+
['PONG', (m) => this.isString(m.url) && this.isPoint(m.scroll)],
|
|
48
|
+
[
|
|
49
|
+
'REGION_RESOLVED',
|
|
50
|
+
(m) => this.isNonEmptyString(m.requestId) &&
|
|
51
|
+
this.isElementDescriptorArray(m.elements) &&
|
|
52
|
+
this.isRect(m.regionBounds) &&
|
|
53
|
+
typeof m.truncated === 'boolean',
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
'ELEMENT_BOUNDS',
|
|
57
|
+
(m) => this.isNonEmptyString(m.requestId) && this.isBoundsEntryArray(m.entries),
|
|
58
|
+
],
|
|
59
|
+
['SCROLL', (m) => this.isPoint(m.scroll)],
|
|
60
|
+
['RESIZE', (m) => this.isViewport(m.viewport)],
|
|
61
|
+
['NAVIGATED', (m) => this.isString(m.url)],
|
|
62
|
+
[
|
|
63
|
+
'ERROR',
|
|
64
|
+
(m) => this.isString(m.code) &&
|
|
65
|
+
RUNTIME_ERROR_CODES.has(m.code) &&
|
|
66
|
+
this.isStringOrNull(m.requestId) &&
|
|
67
|
+
this.isStringOrNull(m.detail),
|
|
68
|
+
],
|
|
69
|
+
]);
|
|
70
|
+
/** Parses a host→guest payload; null for foreign or malformed traffic. */
|
|
71
|
+
parseHostMessage(data) {
|
|
72
|
+
return this.isHostMessage(data) ? data : null;
|
|
73
|
+
}
|
|
74
|
+
/** Parses a guest→host payload; null for foreign or malformed traffic. */
|
|
75
|
+
parseGuestMessage(data) {
|
|
76
|
+
return this.isGuestMessage(data) ? data : null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* True when the payload claims our namespace, regardless of validity.
|
|
80
|
+
* Lets the runtime distinguish "foreign traffic — stay silent" from
|
|
81
|
+
* "namespaced but malformed — answer with INVALID_MESSAGE".
|
|
82
|
+
*/
|
|
83
|
+
hasProtocolNamespace(data) {
|
|
84
|
+
return this.isRecord(data) && data.ns === PROTOCOL_NAMESPACE;
|
|
85
|
+
}
|
|
86
|
+
isHostMessage(data) {
|
|
87
|
+
if (!this.isEnvelopedRecord(data))
|
|
88
|
+
return false;
|
|
89
|
+
return this.hostValidators.get(data.type)?.(data) ?? false;
|
|
90
|
+
}
|
|
91
|
+
isGuestMessage(data) {
|
|
92
|
+
if (!this.isEnvelopedRecord(data))
|
|
93
|
+
return false;
|
|
94
|
+
return this.guestValidators.get(data.type)?.(data) ?? false;
|
|
95
|
+
}
|
|
96
|
+
isEnvelopedRecord(data) {
|
|
97
|
+
if (!this.isRecord(data))
|
|
98
|
+
return false;
|
|
99
|
+
if (data.ns !== PROTOCOL_NAMESPACE || data.v !== PROTOCOL_VERSION)
|
|
100
|
+
return false;
|
|
101
|
+
return this.isNonEmptyString(data.type);
|
|
102
|
+
}
|
|
103
|
+
isRecord(value) {
|
|
104
|
+
return typeof value === 'object' && value !== null;
|
|
105
|
+
}
|
|
106
|
+
isString(value) {
|
|
107
|
+
return typeof value === 'string';
|
|
108
|
+
}
|
|
109
|
+
isStringOrNull(value) {
|
|
110
|
+
return value === null || typeof value === 'string';
|
|
111
|
+
}
|
|
112
|
+
isNonEmptyString(value) {
|
|
113
|
+
return typeof value === 'string' && value.length > 0;
|
|
114
|
+
}
|
|
115
|
+
isFiniteNumber(value) {
|
|
116
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
117
|
+
}
|
|
118
|
+
isPositiveNumber(value) {
|
|
119
|
+
return this.isFiniteNumber(value) && value > 0;
|
|
120
|
+
}
|
|
121
|
+
isOptionalPositiveNumber(value) {
|
|
122
|
+
return value === undefined || this.isPositiveNumber(value);
|
|
123
|
+
}
|
|
124
|
+
isStringArray(value) {
|
|
125
|
+
return Array.isArray(value) && value.every((item) => this.isString(item));
|
|
126
|
+
}
|
|
127
|
+
isPoint(value) {
|
|
128
|
+
return this.isRecord(value) && this.isFiniteNumber(value.x) && this.isFiniteNumber(value.y);
|
|
129
|
+
}
|
|
130
|
+
isPointArray(value) {
|
|
131
|
+
return Array.isArray(value) && value.every((item) => this.isPoint(item));
|
|
132
|
+
}
|
|
133
|
+
isViewport(value) {
|
|
134
|
+
return (this.isRecord(value) &&
|
|
135
|
+
this.isFiniteNumber(value.width) &&
|
|
136
|
+
this.isFiniteNumber(value.height));
|
|
137
|
+
}
|
|
138
|
+
isRect(value) {
|
|
139
|
+
if (!this.isRecord(value))
|
|
140
|
+
return false;
|
|
141
|
+
return (this.isFiniteNumber(value.x) &&
|
|
142
|
+
this.isFiniteNumber(value.y) &&
|
|
143
|
+
this.isFiniteNumber(value.width) &&
|
|
144
|
+
this.isFiniteNumber(value.height));
|
|
145
|
+
}
|
|
146
|
+
isCapabilities(value) {
|
|
147
|
+
return (this.isRecord(value) &&
|
|
148
|
+
typeof value.stamping === 'boolean' &&
|
|
149
|
+
typeof value.highlight === 'boolean');
|
|
150
|
+
}
|
|
151
|
+
isBoundsEntryArray(value) {
|
|
152
|
+
return Array.isArray(value) && value.every((item) => this.isBoundsEntry(item));
|
|
153
|
+
}
|
|
154
|
+
isBoundsEntry(value) {
|
|
155
|
+
if (!this.isRecord(value))
|
|
156
|
+
return false;
|
|
157
|
+
return this.isNonEmptyString(value.refId) && (value.bounds === null || this.isRect(value.bounds));
|
|
158
|
+
}
|
|
159
|
+
isElementDescriptorArray(value) {
|
|
160
|
+
return Array.isArray(value) && value.every((item) => this.isElementDescriptor(item));
|
|
161
|
+
}
|
|
162
|
+
isElementDescriptor(value) {
|
|
163
|
+
if (!this.isRecord(value))
|
|
164
|
+
return false;
|
|
165
|
+
return (this.hasDescriptorIdentity(value) &&
|
|
166
|
+
this.hasDescriptorContent(value) &&
|
|
167
|
+
this.hasDescriptorGeometry(value));
|
|
168
|
+
}
|
|
169
|
+
hasDescriptorIdentity(value) {
|
|
170
|
+
return (this.isNonEmptyString(value.refId) &&
|
|
171
|
+
this.isNonEmptyString(value.tagName) &&
|
|
172
|
+
this.isStringOrNull(value.id) &&
|
|
173
|
+
this.isStringArray(value.classList));
|
|
174
|
+
}
|
|
175
|
+
hasDescriptorContent(value) {
|
|
176
|
+
return (this.isDomPath(value.domPath) &&
|
|
177
|
+
this.isSourceRefOrNull(value.source) &&
|
|
178
|
+
this.isStringOrNull(value.text) &&
|
|
179
|
+
this.isStringOrNull(value.role) &&
|
|
180
|
+
this.isStringRecord(value.attributes));
|
|
181
|
+
}
|
|
182
|
+
hasDescriptorGeometry(value) {
|
|
183
|
+
return (this.isRect(value.bounds) &&
|
|
184
|
+
this.isFiniteNumber(value.coverage) &&
|
|
185
|
+
this.isFiniteNumber(value.childCount));
|
|
186
|
+
}
|
|
187
|
+
isDomPath(value) {
|
|
188
|
+
return Array.isArray(value) && value.every((item) => this.isDomPathSegment(item));
|
|
189
|
+
}
|
|
190
|
+
isDomPathSegment(value) {
|
|
191
|
+
if (!this.isRecord(value))
|
|
192
|
+
return false;
|
|
193
|
+
return this.isNonEmptyString(value.tag) && this.isFiniteNumber(value.nthOfType);
|
|
194
|
+
}
|
|
195
|
+
isSourceRefOrNull(value) {
|
|
196
|
+
if (value === null)
|
|
197
|
+
return true;
|
|
198
|
+
if (!this.isRecord(value))
|
|
199
|
+
return false;
|
|
200
|
+
return (this.isNonEmptyString(value.file) &&
|
|
201
|
+
this.isFiniteNumber(value.line) &&
|
|
202
|
+
this.isFiniteNumber(value.column) &&
|
|
203
|
+
this.isStringOrNull(value.componentName));
|
|
204
|
+
}
|
|
205
|
+
isStringRecord(value) {
|
|
206
|
+
return this.isRecord(value) && Object.values(value).every((item) => this.isString(item));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=message-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-codec.js","sourceRoot":"","sources":["../../src/protocol/message-codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { ElementBoundsEntry, ElementDescriptor, GuestCapabilities, Point, Rect, ScrollPosition, Viewport } from './element.types.js';
|
|
2
|
+
import type { PROTOCOL_NAMESPACE, PROTOCOL_VERSION } from './protocol.constant.js';
|
|
3
|
+
/**
|
|
4
|
+
* Protocol error codes carried by guest ERROR messages. This is a wire-level
|
|
5
|
+
* string union by design: the runtime is a published browser package with no
|
|
6
|
+
* access to the backend `ErrorCode` enum, and the host resolves these codes
|
|
7
|
+
* into its own UX (retry, re-handshake, toast) — they never reach GraphQL.
|
|
8
|
+
*/
|
|
9
|
+
export type RuntimeErrorCode = 'INVALID_MESSAGE' | 'NOT_ACTIVE' | 'REGION_TOO_LARGE' | 'UNKNOWN_REF' | 'INTERNAL';
|
|
10
|
+
/** Envelope present on every message; both sides reject anything else. */
|
|
11
|
+
export interface ProtocolEnvelope {
|
|
12
|
+
ns: typeof PROTOCOL_NAMESPACE;
|
|
13
|
+
v: typeof PROTOCOL_VERSION;
|
|
14
|
+
}
|
|
15
|
+
/** Opens the handshake. Only accepted with the capability nonce. */
|
|
16
|
+
export interface HelloMessage extends ProtocolEnvelope {
|
|
17
|
+
type: 'HELLO';
|
|
18
|
+
nonce: string;
|
|
19
|
+
protocolVersion: number;
|
|
20
|
+
}
|
|
21
|
+
/** Arms the runtime: region selection, highlights and emitters turn on. */
|
|
22
|
+
export interface ActivateMessage extends ProtocolEnvelope {
|
|
23
|
+
type: 'ACTIVATE';
|
|
24
|
+
}
|
|
25
|
+
/** Disarms the runtime: overlay, `data-fc-ref` stamps and emitters are stripped. */
|
|
26
|
+
export interface DeactivateMessage extends ProtocolEnvelope {
|
|
27
|
+
type: 'DEACTIVATE';
|
|
28
|
+
}
|
|
29
|
+
/** Liveness probe; answered with PONG while handshaken or active. */
|
|
30
|
+
export interface PingMessage extends ProtocolEnvelope {
|
|
31
|
+
type: 'PING';
|
|
32
|
+
}
|
|
33
|
+
/** A completed spray stroke to resolve into elements. */
|
|
34
|
+
export interface RegionSelectMessage extends ProtocolEnvelope {
|
|
35
|
+
type: 'REGION_SELECT';
|
|
36
|
+
requestId: string;
|
|
37
|
+
stroke: Point[];
|
|
38
|
+
radius: number;
|
|
39
|
+
maxElements?: number;
|
|
40
|
+
}
|
|
41
|
+
/** Replaces the highlight boxes with the given refs' current bounds. */
|
|
42
|
+
export interface HighlightSetMessage extends ProtocolEnvelope {
|
|
43
|
+
type: 'HIGHLIGHT_SET';
|
|
44
|
+
refIds: string[];
|
|
45
|
+
}
|
|
46
|
+
/** Removes every highlight box (the overlay container stays mounted). */
|
|
47
|
+
export interface HighlightClearMessage extends ProtocolEnvelope {
|
|
48
|
+
type: 'HIGHLIGHT_CLEAR';
|
|
49
|
+
}
|
|
50
|
+
/** Asks for the current bounds of previously resolved refs. */
|
|
51
|
+
export interface ElementBoundsQueryMessage extends ProtocolEnvelope {
|
|
52
|
+
type: 'ELEMENT_BOUNDS_QUERY';
|
|
53
|
+
requestId: string;
|
|
54
|
+
refIds: string[];
|
|
55
|
+
}
|
|
56
|
+
export type HostMessage = HelloMessage | ActivateMessage | DeactivateMessage | PingMessage | RegionSelectMessage | HighlightSetMessage | HighlightClearMessage | ElementBoundsQueryMessage;
|
|
57
|
+
/**
|
|
58
|
+
* Pre-handshake boot beacon. The only message ever posted with
|
|
59
|
+
* targetOrigin '*'; it carries zero payload beyond the envelope so an
|
|
60
|
+
* arbitrary embedder learns nothing. The host answers with HELLO.
|
|
61
|
+
*/
|
|
62
|
+
export interface ReadyMessage extends ProtocolEnvelope {
|
|
63
|
+
type: 'READY';
|
|
64
|
+
}
|
|
65
|
+
/** Successful handshake reply; the guest has pinned the host origin. */
|
|
66
|
+
export interface HelloAckMessage extends ProtocolEnvelope {
|
|
67
|
+
type: 'HELLO_ACK';
|
|
68
|
+
capabilities: GuestCapabilities;
|
|
69
|
+
url: string;
|
|
70
|
+
viewport: Viewport;
|
|
71
|
+
}
|
|
72
|
+
/** Acknowledges ACTIVATE (idempotent — re-sent for duplicate ACTIVATEs). */
|
|
73
|
+
export interface ActivatedMessage extends ProtocolEnvelope {
|
|
74
|
+
type: 'ACTIVATED';
|
|
75
|
+
}
|
|
76
|
+
/** Acknowledges DEACTIVATE after overlay/stamp/listener teardown. */
|
|
77
|
+
export interface DeactivatedMessage extends ProtocolEnvelope {
|
|
78
|
+
type: 'DEACTIVATED';
|
|
79
|
+
}
|
|
80
|
+
/** Liveness answer; `url` lets the host detect soft (push-state) navigations. */
|
|
81
|
+
export interface PongMessage extends ProtocolEnvelope {
|
|
82
|
+
type: 'PONG';
|
|
83
|
+
url: string;
|
|
84
|
+
scroll: ScrollPosition;
|
|
85
|
+
}
|
|
86
|
+
/** The resolved elements for one REGION_SELECT request. */
|
|
87
|
+
export interface RegionResolvedMessage extends ProtocolEnvelope {
|
|
88
|
+
type: 'REGION_RESOLVED';
|
|
89
|
+
requestId: string;
|
|
90
|
+
elements: ElementDescriptor[];
|
|
91
|
+
regionBounds: Rect;
|
|
92
|
+
truncated: boolean;
|
|
93
|
+
}
|
|
94
|
+
/** Answer to ELEMENT_BOUNDS_QUERY; entries keep the request's ref order. */
|
|
95
|
+
export interface ElementBoundsMessage extends ProtocolEnvelope {
|
|
96
|
+
type: 'ELEMENT_BOUNDS';
|
|
97
|
+
requestId: string;
|
|
98
|
+
entries: ElementBoundsEntry[];
|
|
99
|
+
}
|
|
100
|
+
/** rAF-throttled scroll notification, emitted while active. */
|
|
101
|
+
export interface ScrollMessage extends ProtocolEnvelope {
|
|
102
|
+
type: 'SCROLL';
|
|
103
|
+
scroll: ScrollPosition;
|
|
104
|
+
}
|
|
105
|
+
/** rAF-throttled viewport resize notification, emitted while active. */
|
|
106
|
+
export interface ResizeMessage extends ProtocolEnvelope {
|
|
107
|
+
type: 'RESIZE';
|
|
108
|
+
viewport: Viewport;
|
|
109
|
+
}
|
|
110
|
+
/** popstate/hashchange navigation notification, emitted while active. */
|
|
111
|
+
export interface NavigatedMessage extends ProtocolEnvelope {
|
|
112
|
+
type: 'NAVIGATED';
|
|
113
|
+
url: string;
|
|
114
|
+
}
|
|
115
|
+
/** Post-handshake failure report; pre-handshake failures stay silent. */
|
|
116
|
+
export interface ErrorMessage extends ProtocolEnvelope {
|
|
117
|
+
type: 'ERROR';
|
|
118
|
+
code: RuntimeErrorCode;
|
|
119
|
+
requestId: string | null;
|
|
120
|
+
detail: string | null;
|
|
121
|
+
}
|
|
122
|
+
export type GuestMessage = ReadyMessage | HelloAckMessage | ActivatedMessage | DeactivatedMessage | PongMessage | RegionResolvedMessage | ElementBoundsMessage | ScrollMessage | ResizeMessage | NavigatedMessage | ErrorMessage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.types.js","sourceRoot":"","sources":["../../src/protocol/message.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-protocol constants shared by the guest runtime (tenant storefront
|
|
3
|
+
* iframe) and the dashboard host. Both sides validate `ns` + `v` on every
|
|
4
|
+
* message; anything else on the window message bus (payment SDKs, analytics,
|
|
5
|
+
* HMR sockets) is foreign traffic and must be ignored silently.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PROTOCOL_NAMESPACE = "fc-designer";
|
|
8
|
+
/** Bumped on breaking wire changes; HELLO carries the host's version. */
|
|
9
|
+
export declare const PROTOCOL_VERSION = 1;
|
|
10
|
+
/**
|
|
11
|
+
* URL-fragment key carrying the activation nonce (`#fcd=<uuid>`). The
|
|
12
|
+
* fragment never reaches the server; the guest strips it on boot and parks
|
|
13
|
+
* the nonce in sessionStorage so it survives iframe reloads.
|
|
14
|
+
*/
|
|
15
|
+
export declare const FRAGMENT_KEY = "fcd";
|
|
16
|
+
/** sessionStorage key the guest stores the captured nonce under. */
|
|
17
|
+
export declare const NONCE_STORAGE_KEY = "fc-designer:nonce";
|
|
18
|
+
/**
|
|
19
|
+
* Attribute stamped at build time by the turbo-loader, value
|
|
20
|
+
* `<project-relative-file>:<line>:<col>:<ComponentName>` (1-based line and
|
|
21
|
+
* column of the JSX opening element's `<`).
|
|
22
|
+
*/
|
|
23
|
+
export declare const SOURCE_ATTRIBUTE = "data-fc-source";
|
|
24
|
+
/**
|
|
25
|
+
* Attribute stamped on resolved elements during REGION_SELECT so later
|
|
26
|
+
* HIGHLIGHT_SET / ELEMENT_BOUNDS_QUERY calls can address them by refId.
|
|
27
|
+
*/
|
|
28
|
+
export declare const REF_ATTRIBUTE = "data-fc-ref";
|
|
29
|
+
/** Attribute marking the highlight overlay container element. */
|
|
30
|
+
export declare const OVERLAY_ATTRIBUTE = "data-fc-designer-overlay";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-protocol constants shared by the guest runtime (tenant storefront
|
|
3
|
+
* iframe) and the dashboard host. Both sides validate `ns` + `v` on every
|
|
4
|
+
* message; anything else on the window message bus (payment SDKs, analytics,
|
|
5
|
+
* HMR sockets) is foreign traffic and must be ignored silently.
|
|
6
|
+
*/
|
|
7
|
+
export const PROTOCOL_NAMESPACE = 'fc-designer';
|
|
8
|
+
/** Bumped on breaking wire changes; HELLO carries the host's version. */
|
|
9
|
+
export const PROTOCOL_VERSION = 1;
|
|
10
|
+
/**
|
|
11
|
+
* URL-fragment key carrying the activation nonce (`#fcd=<uuid>`). The
|
|
12
|
+
* fragment never reaches the server; the guest strips it on boot and parks
|
|
13
|
+
* the nonce in sessionStorage so it survives iframe reloads.
|
|
14
|
+
*/
|
|
15
|
+
export const FRAGMENT_KEY = 'fcd';
|
|
16
|
+
/** sessionStorage key the guest stores the captured nonce under. */
|
|
17
|
+
export const NONCE_STORAGE_KEY = 'fc-designer:nonce';
|
|
18
|
+
/**
|
|
19
|
+
* Attribute stamped at build time by the turbo-loader, value
|
|
20
|
+
* `<project-relative-file>:<line>:<col>:<ComponentName>` (1-based line and
|
|
21
|
+
* column of the JSX opening element's `<`).
|
|
22
|
+
*/
|
|
23
|
+
export const SOURCE_ATTRIBUTE = 'data-fc-source';
|
|
24
|
+
/**
|
|
25
|
+
* Attribute stamped on resolved elements during REGION_SELECT so later
|
|
26
|
+
* HIGHLIGHT_SET / ELEMENT_BOUNDS_QUERY calls can address them by refId.
|
|
27
|
+
*/
|
|
28
|
+
export const REF_ATTRIBUTE = 'data-fc-ref';
|
|
29
|
+
/** Attribute marking the highlight overlay container element. */
|
|
30
|
+
export const OVERLAY_ATTRIBUTE = 'data-fc-designer-overlay';
|
|
31
|
+
//# sourceMappingURL=protocol.constant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.constant.js","sourceRoot":"","sources":["../../src/protocol/protocol.constant.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEhD,yEAAyE;AACzE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAElC,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;AAE3C,iEAAiE;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ElementDescriptor } from '../../protocol/element.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Projects a resolved DOM element into the wire {@link ElementDescriptor} —
|
|
4
|
+
* everything the host (and ultimately the AI agent) needs to identify the
|
|
5
|
+
* element in the storefront source tree without access to the live DOM.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ElementDescriptorExtractor {
|
|
8
|
+
private readonly win;
|
|
9
|
+
constructor(win: Window);
|
|
10
|
+
extract(element: Element, refId: string, coverage: number): ElementDescriptor;
|
|
11
|
+
/**
|
|
12
|
+
* Finds the nearest `data-fc-source` stamp on the element or up to three
|
|
13
|
+
* ancestors (components often render a stamped wrapper around unstamped
|
|
14
|
+
* children). The first stamp found is authoritative: a malformed stamp
|
|
15
|
+
* yields null instead of climbing further, which would misattribute the
|
|
16
|
+
* element to an outer component.
|
|
17
|
+
*/
|
|
18
|
+
private resolveSource;
|
|
19
|
+
/**
|
|
20
|
+
* Parses `<file>:<line>:<col>:<ComponentName>` by splitting from the
|
|
21
|
+
* right — the trailing three segments are component, column and line; the
|
|
22
|
+
* rest re-joins as the file path, so colon-bearing paths survive.
|
|
23
|
+
*/
|
|
24
|
+
private parseSource;
|
|
25
|
+
private parsePosition;
|
|
26
|
+
/**
|
|
27
|
+
* Body-rooted `tag:nth-of-type` path. `nthOfType` counts same-tag element
|
|
28
|
+
* siblings, 1-based. Paths deeper than 14 segments keep the first 6 and
|
|
29
|
+
* last 7 with {@link DOM_PATH_ELISION_SEGMENT} marking the elided middle.
|
|
30
|
+
*/
|
|
31
|
+
private buildDomPath;
|
|
32
|
+
private nthOfType;
|
|
33
|
+
private extractText;
|
|
34
|
+
private resolveRole;
|
|
35
|
+
private inputRole;
|
|
36
|
+
private collectAttributes;
|
|
37
|
+
private toRect;
|
|
38
|
+
}
|