@kumwe/studio-preview 0.1.0-alpha.5 → 0.1.0-beta.2
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 +44 -13
- package/THIRD_PARTY_NOTICES.md +9 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/preview-client.d.ts +7 -1
- package/dist/preview-client.d.ts.map +1 -1
- package/dist/preview-client.js +1 -446
- package/dist/preview-host.d.ts +4 -2
- package/dist/preview-host.d.ts.map +1 -1
- package/dist/preview-host.js +1 -375
- package/dist/preview-identity.d.ts +29 -0
- package/dist/preview-identity.d.ts.map +1 -0
- package/dist/preview-identity.js +1 -0
- package/package.json +6 -3
- package/dist/index.js.map +0 -1
- package/dist/preview-client.js.map +0 -1
- package/dist/preview-host.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# `@kumwe/studio-preview`
|
|
2
2
|
|
|
3
|
-
Status: pre-Gate-A
|
|
3
|
+
Status: governed beta development, still pre-Gate-A and not production-supported. The exact coordinated
|
|
4
|
+
version is in the workspace `studio-release.json`; this channel is an executable contract implementation,
|
|
5
|
+
not a qualified host adapter.
|
|
4
6
|
|
|
5
7
|
An exact-origin, typed request channel between Studio and a host-rendered preview surface. A host can
|
|
6
8
|
render Twig, Liquid, JSX, or another server template without teaching the canvas to reproduce its
|
|
@@ -14,7 +16,8 @@ still owns authentication, authorization, CSP, sandboxing, and rendering.
|
|
|
14
16
|
`PreviewClient` is the Studio half of the channel; `PreviewHost` is the preview-surface half. Both
|
|
15
17
|
pin an exact target origin and drop any inbound message whose source window, origin, schema, channel
|
|
16
18
|
ID, session generation, or sequence does not match; each direction stamps its own monotonic sequence
|
|
17
|
-
counter.
|
|
19
|
+
counter. Outbound client messages cross the same canonical guard before posting, and the draft.2
|
|
20
|
+
message vocabulary is closed.
|
|
18
21
|
|
|
19
22
|
The handshake and request flow is announce → ready → render → rendered:
|
|
20
23
|
|
|
@@ -22,21 +25,47 @@ The handshake and request flow is announce → ready → render → rendered:
|
|
|
22
25
|
callback, then calls `announce()` to post `studio.preview/ready`.
|
|
23
26
|
2. Studio awaits `client.ready()`, which resolves with the announced payload — immediately when the
|
|
24
27
|
announcement already arrived — and rejects on timeout, abort, or disposal.
|
|
25
|
-
3. Studio requests `studio.preview/render` via `client.render()
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
posted or resolved
|
|
28
|
+
3. Studio requests `studio.preview/render` via `client.render()` with a session-unique `requestId`.
|
|
29
|
+
The host invokes its render callback with an `AbortSignal` and replies with
|
|
30
|
+
`studio.preview/rendered` carrying the same request ID and draft digest. A newer request aborts and
|
|
31
|
+
generation-invalidates in-flight work on both sides, so a stale result is never posted or resolved
|
|
32
|
+
even when a retry uses the same digest at another viewport.
|
|
29
33
|
4. A failed render is answered with `studio.preview/error` (code `studio.preview/render-failed`, the
|
|
30
|
-
|
|
34
|
+
request ID as `correlationId`, `retryable: true`) and a generic message — renderer failure
|
|
31
35
|
details never cross the channel.
|
|
32
36
|
5. `client.select()` forwards `studio.preview/select` to the host's `onSelect` listeners.
|
|
33
37
|
|
|
38
|
+
## Portable draft identity and markers
|
|
39
|
+
|
|
40
|
+
`canonicalPreviewDraftBytes(draft)` returns exactly the canonical UTF-8 bytes of a complete Studio
|
|
41
|
+
artifact. `computePreviewDraftDigest(draft)` hashes those bytes as lowercase hexadecimal SHA-256; it
|
|
42
|
+
does not add an envelope, prefix, viewport, BOM, or newline. The host still validates and authorizes
|
|
43
|
+
the staged draft, recomputes its digest, and compares it before rendering — the digest is never a
|
|
44
|
+
credential.
|
|
45
|
+
|
|
46
|
+
`createPreviewMarker(digest, ordinal)` implements the canonical
|
|
47
|
+
`studio.preview/node/<digest>/<ordinal>` grammar. `createPreviewMarkerInventory(blueprint, digest)`
|
|
48
|
+
enumerates roots, each node before descendants, sorted slot names, then child arrays. Every rendered
|
|
49
|
+
response requires an exact one-to-one `markerMap`; the generic responder refuses a mismatched digest,
|
|
50
|
+
grammar, contiguous order, duplicate, or incomplete map. Because the channel does not hold the draft,
|
|
51
|
+
the authoritative renderer additionally compares node mapping with `createPreviewMarkerInventory`;
|
|
52
|
+
the standalone reference renderer does so. `announceActivation()` accepts only a marker from the
|
|
53
|
+
currently accepted inventory, and the client independently drops invented or revoked activation
|
|
54
|
+
traffic.
|
|
55
|
+
|
|
56
|
+
These semantics require wire protocol `0.1.0-draft.2`. A `.1` peer is incompatible rather than
|
|
57
|
+
silently accepted. Portable implementations replay `@kumwe/studio-testkit/vectors/preview/` against
|
|
58
|
+
their own canonicalizer and traversal.
|
|
59
|
+
|
|
34
60
|
## Marker geometry
|
|
35
61
|
|
|
36
|
-
`client.measure()` posts `studio.preview/measure` with a bounded marker list and resolves with the
|
|
62
|
+
`client.measure()` posts `studio.preview/measure` with a non-empty bounded marker list and resolves with the
|
|
37
63
|
`studio.preview/measurements` answer: per marker, one or more CSS-pixel rectangles relative to the
|
|
38
64
|
preview viewport origin (inline content fragments across lines), plus viewport metrics. Markers the
|
|
39
|
-
renderer cannot place are returned in a distinct `unknown` list, never thrown.
|
|
65
|
+
renderer cannot place are returned in a distinct `unknown` list, never thrown. A marker outside the
|
|
66
|
+
latest digest-bound inventory is rejected locally with `PreviewChannelError` code
|
|
67
|
+
`studio.preview/measure-stale-marker`; the host independently rejects raw stale traffic without
|
|
68
|
+
invoking the measurer.
|
|
40
69
|
|
|
41
70
|
The host never reads the DOM. The embedding renderer passes a `measure` callback in
|
|
42
71
|
`PreviewHostOptions`; without one, measure requests are answered with the qualified
|
|
@@ -44,10 +73,12 @@ The host never reads the DOM. The embedding renderer passes a `measure` callback
|
|
|
44
73
|
`studio.preview/measure-failed` — measurer failure details never cross the channel.
|
|
45
74
|
|
|
46
75
|
Geometry is volatile, not document state: each response is stamped with the digest of the render it
|
|
47
|
-
was measured against.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
76
|
+
was measured against. The host captures that digest and a private generation before invoking the
|
|
77
|
+
callback. A same-digest rerender, newer measurement, disposal, reload or teardown aborts and
|
|
78
|
+
invalidates the prior measurement. A viewport instruction also rejects the client's pending
|
|
79
|
+
measurement with `PreviewChannelError` code `studio.preview/measure-viewport-changed` and aborts the
|
|
80
|
+
host callback before viewport listeners run, so pre-resize geometry cannot settle late. Measured and
|
|
81
|
+
unknown entries must exactly partition the requested markers.
|
|
51
82
|
|
|
52
83
|
Version negotiation currently requires the exact draft wire version on both sides: schema filtering
|
|
53
84
|
accepts only `STUDIO_WIRE_PROTOCOL_VERSION`, so a ready announcement from a host speaking any other
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/generate-third-party-notices.mjs. Do not edit by hand. -->
|
|
4
|
+
|
|
5
|
+
Package: `@kumwe/studio-preview`
|
|
6
|
+
|
|
7
|
+
Production closure SHA-256: `4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945`
|
|
8
|
+
|
|
9
|
+
This package has no third-party runtime dependencies.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { PreviewClient, type PreviewClientOptions, type PreviewMeasureOptions, type PreviewMeasureOutcome, type PreviewMessageEvent, type PreviewMessageListener, type PreviewMessageSource, type PreviewMessageTarget, type PreviewProtocolListener, type PreviewReadyOptions, type PreviewRenderOptions, } from './preview-client.js';
|
|
1
|
+
export { PreviewClient, PreviewChannelError, type PreviewClientOptions, type PreviewMeasureOptions, type PreviewMeasureOutcome, type PreviewMessageEvent, type PreviewMessageListener, type PreviewMessageSource, type PreviewMessageTarget, type PreviewProtocolListener, type PreviewReadyOptions, type PreviewRenderOptions, } from './preview-client.js';
|
|
2
2
|
export { PreviewHost, type PreviewHostOptions, type PreviewMeasureCallback, type PreviewMeasurement, type PreviewRenderCallback, type PreviewSelectListener, } from './preview-host.js';
|
|
3
|
+
export { canonicalPreviewDraftBytes, computePreviewDraftDigest, createPreviewMarker, createPreviewMarkerInventory, type PreviewDigestOptions, type PreviewMarkerInventory, } from './preview-identity.js';
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,4BAA4B,EAC5B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { PreviewHost, } from './preview-host.js';
|
|
3
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export{PreviewClient,PreviewChannelError}from"./preview-client.js";export{PreviewHost}from"./preview-host.js";export{canonicalPreviewDraftBytes,computePreviewDraftDigest,createPreviewMarker,createPreviewMarkerInventory}from"./preview-identity.js";
|
package/dist/preview-client.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import { type PreviewMeasurePayload, type PreviewMeasurementsPayload, type PreviewMessage, type PreviewReadyPayload, type PreviewRenderedPayload, type PreviewRenderPayload, type PreviewActivatedPayload, type PreviewDisposePayload, type PreviewSelectPayload, type PreviewViewportPayload, type PreviewTeardownPayload } from '@kumwe/studio-protocol';
|
|
1
|
+
import { type PreviewMeasurePayload, type PreviewMeasurementsPayload, type PreviewMessage, type PreviewReadyPayload, type PreviewRenderedPayload, type PreviewRenderPayload, type PreviewActivatedPayload, type PreviewDisposePayload, type PreviewSelectPayload, type PreviewViewportPayload, type PreviewTeardownPayload, type QualifiedName } from '@kumwe/studio-protocol';
|
|
2
|
+
/** Stable client-side and wire failure surfaced by the preview channel. */
|
|
3
|
+
export declare class PreviewChannelError extends Error {
|
|
4
|
+
readonly code: QualifiedName;
|
|
5
|
+
readonly retryable: boolean;
|
|
6
|
+
constructor(code: QualifiedName, message: string, retryable?: boolean);
|
|
7
|
+
}
|
|
2
8
|
export interface PreviewMessageEvent {
|
|
3
9
|
data: unknown;
|
|
4
10
|
origin: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-client.d.ts","sourceRoot":"","sources":["../src/preview-client.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"preview-client.d.ts","sourceRoot":"","sources":["../src/preview-client.ts"],"names":[],"mappings":"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"}
|
package/dist/preview-client.js
CHANGED
|
@@ -1,446 +1 @@
|
|
|
1
|
-
import { isPreviewMessage, STUDIO_CONTRACT_VERSION, } from '@kumwe/studio-protocol';
|
|
2
|
-
export class PreviewClient {
|
|
3
|
-
#activationListeners = new Set();
|
|
4
|
-
#channelId;
|
|
5
|
-
#listener;
|
|
6
|
-
#listeners = new Set();
|
|
7
|
-
#pending = new Map();
|
|
8
|
-
#pendingMeasures = new Map();
|
|
9
|
-
#pendingReady = new Set();
|
|
10
|
-
#sessionGeneration;
|
|
11
|
-
#source;
|
|
12
|
-
#target;
|
|
13
|
-
#targetOrigin;
|
|
14
|
-
#timeoutMilliseconds;
|
|
15
|
-
#disposed = false;
|
|
16
|
-
#lastInboundSequence = -1;
|
|
17
|
-
#latestRenderDigest;
|
|
18
|
-
#latestRenderedDigest;
|
|
19
|
-
#readyPayload;
|
|
20
|
-
#sequence = 0;
|
|
21
|
-
constructor(options) {
|
|
22
|
-
this.#targetOrigin = normalizeOrigin(options.targetOrigin);
|
|
23
|
-
this.#channelId = options.channelId;
|
|
24
|
-
this.#sessionGeneration = options.sessionGeneration;
|
|
25
|
-
this.#source = options.source;
|
|
26
|
-
this.#target = options.target;
|
|
27
|
-
this.#timeoutMilliseconds = options.timeoutMilliseconds ?? 10_000;
|
|
28
|
-
this.#listener = (event) => {
|
|
29
|
-
this.#receive(event);
|
|
30
|
-
};
|
|
31
|
-
this.#source.addEventListener('message', this.#listener);
|
|
32
|
-
}
|
|
33
|
-
dispose() {
|
|
34
|
-
if (this.#disposed) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
this.#disposed = true;
|
|
38
|
-
this.#source.removeEventListener('message', this.#listener);
|
|
39
|
-
for (const pending of this.#pending.values()) {
|
|
40
|
-
clearTimeout(pending.timeout);
|
|
41
|
-
pending.cleanup();
|
|
42
|
-
pending.reject(new Error('Preview client was disposed.'));
|
|
43
|
-
}
|
|
44
|
-
this.#pending.clear();
|
|
45
|
-
for (const pending of this.#pendingMeasures.values()) {
|
|
46
|
-
clearTimeout(pending.timeout);
|
|
47
|
-
pending.cleanup();
|
|
48
|
-
pending.reject(new Error('Preview client was disposed.'));
|
|
49
|
-
}
|
|
50
|
-
this.#pendingMeasures.clear();
|
|
51
|
-
for (const pending of this.#pendingReady) {
|
|
52
|
-
clearTimeout(pending.timeout);
|
|
53
|
-
pending.cleanup();
|
|
54
|
-
pending.reject(new Error('Preview client was disposed.'));
|
|
55
|
-
}
|
|
56
|
-
this.#pendingReady.clear();
|
|
57
|
-
this.#listeners.clear();
|
|
58
|
-
}
|
|
59
|
-
onMessage(listener) {
|
|
60
|
-
this.#listeners.add(listener);
|
|
61
|
-
return () => {
|
|
62
|
-
this.#listeners.delete(listener);
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Resolves once the host announces `studio.preview/ready` on this channel. If the
|
|
67
|
-
* announcement was already received, the cached payload resolves immediately.
|
|
68
|
-
*
|
|
69
|
-
* `isPreviewMessage` accepts only ready payloads carrying the exact draft wire protocol
|
|
70
|
-
* version, so an announcement from an incompatible host is filtered out and never resolves
|
|
71
|
-
* this promise — the wait times out instead. The promise also rejects on abort or when the
|
|
72
|
-
* client is disposed.
|
|
73
|
-
*/
|
|
74
|
-
ready(options = {}) {
|
|
75
|
-
if (this.#disposed) {
|
|
76
|
-
return Promise.reject(new Error('Preview client was disposed.'));
|
|
77
|
-
}
|
|
78
|
-
if (options.signal?.aborted === true) {
|
|
79
|
-
return Promise.reject(new Error('Preview ready wait was aborted.', { cause: options.signal.reason }));
|
|
80
|
-
}
|
|
81
|
-
if (this.#readyPayload !== undefined) {
|
|
82
|
-
return Promise.resolve(this.#readyPayload);
|
|
83
|
-
}
|
|
84
|
-
return new Promise((resolve, reject) => {
|
|
85
|
-
const abort = () => {
|
|
86
|
-
if (this.#pendingReady.delete(pending)) {
|
|
87
|
-
clearTimeout(pending.timeout);
|
|
88
|
-
pending.cleanup();
|
|
89
|
-
pending.reject(new Error('Preview ready wait was aborted.'));
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
const cleanup = () => {
|
|
93
|
-
options.signal?.removeEventListener('abort', abort);
|
|
94
|
-
};
|
|
95
|
-
const timeout = setTimeout(() => {
|
|
96
|
-
if (this.#pendingReady.delete(pending)) {
|
|
97
|
-
pending.cleanup();
|
|
98
|
-
pending.reject(new Error('Preview ready wait timed out.'));
|
|
99
|
-
}
|
|
100
|
-
}, this.#timeoutMilliseconds);
|
|
101
|
-
const pending = { cleanup, reject, resolve, timeout };
|
|
102
|
-
this.#pendingReady.add(pending);
|
|
103
|
-
options.signal?.addEventListener('abort', abort, { once: true });
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
render(payload, options = {}) {
|
|
107
|
-
if (this.#disposed) {
|
|
108
|
-
return Promise.reject(new Error('Preview client was disposed.'));
|
|
109
|
-
}
|
|
110
|
-
if (options.signal?.aborted === true) {
|
|
111
|
-
return Promise.reject(new Error('Preview render was aborted.', { cause: options.signal.reason }));
|
|
112
|
-
}
|
|
113
|
-
if (this.#pending.has(payload.draftDigest)) {
|
|
114
|
-
return Promise.reject(new Error(`Render ${payload.draftDigest} is already pending.`));
|
|
115
|
-
}
|
|
116
|
-
for (const [digest, pending] of this.#pending) {
|
|
117
|
-
clearTimeout(pending.timeout);
|
|
118
|
-
pending.cleanup();
|
|
119
|
-
pending.reject(new Error(`Preview render ${digest} was superseded by ${payload.draftDigest}.`));
|
|
120
|
-
}
|
|
121
|
-
this.#pending.clear();
|
|
122
|
-
this.#latestRenderDigest = payload.draftDigest;
|
|
123
|
-
return new Promise((resolve, reject) => {
|
|
124
|
-
const abort = () => {
|
|
125
|
-
const pending = this.#pending.get(payload.draftDigest);
|
|
126
|
-
if (pending !== undefined) {
|
|
127
|
-
clearTimeout(pending.timeout);
|
|
128
|
-
this.#pending.delete(payload.draftDigest);
|
|
129
|
-
pending.cleanup();
|
|
130
|
-
if (this.#latestRenderDigest === payload.draftDigest) {
|
|
131
|
-
this.#latestRenderDigest = undefined;
|
|
132
|
-
}
|
|
133
|
-
pending.reject(new Error('Preview render was aborted.'));
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
const cleanup = () => {
|
|
137
|
-
options.signal?.removeEventListener('abort', abort);
|
|
138
|
-
};
|
|
139
|
-
const timeout = setTimeout(() => {
|
|
140
|
-
const pending = this.#pending.get(payload.draftDigest);
|
|
141
|
-
if (pending !== undefined) {
|
|
142
|
-
this.#pending.delete(payload.draftDigest);
|
|
143
|
-
pending.cleanup();
|
|
144
|
-
if (this.#latestRenderDigest === payload.draftDigest) {
|
|
145
|
-
this.#latestRenderDigest = undefined;
|
|
146
|
-
}
|
|
147
|
-
pending.reject(new Error(`Preview render ${payload.draftDigest} timed out.`));
|
|
148
|
-
}
|
|
149
|
-
}, this.#timeoutMilliseconds);
|
|
150
|
-
this.#pending.set(payload.draftDigest, { cleanup, reject, resolve, timeout });
|
|
151
|
-
options.signal?.addEventListener('abort', abort, { once: true });
|
|
152
|
-
this.#post({
|
|
153
|
-
channelId: this.#channelId,
|
|
154
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
155
|
-
kind: 'preview-message',
|
|
156
|
-
payload,
|
|
157
|
-
sequence: this.#sequence++,
|
|
158
|
-
sessionGeneration: this.#sessionGeneration,
|
|
159
|
-
type: 'studio.preview/render',
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Requests the on-screen geometry of render markers from the responder. Resolves with a
|
|
165
|
-
* `measured` outcome carrying viewport-relative CSS-pixel rectangles, or a `stale`
|
|
166
|
-
* outcome when the response was measured against a render this client no longer
|
|
167
|
-
* considers latest. Rejects on teardown, reload, supersession, abort, timeout, and
|
|
168
|
-
* disposal exactly like `render()` does. Requires a completed render: geometry is a
|
|
169
|
-
* volatile measurement of a specific render digest, never document state.
|
|
170
|
-
*/
|
|
171
|
-
measure(payload, options = {}) {
|
|
172
|
-
if (this.#disposed) {
|
|
173
|
-
return Promise.reject(new Error('Preview client was disposed.'));
|
|
174
|
-
}
|
|
175
|
-
if (options.signal?.aborted === true) {
|
|
176
|
-
return Promise.reject(new Error('Preview measure was aborted.', { cause: options.signal.reason }));
|
|
177
|
-
}
|
|
178
|
-
if (this.#latestRenderedDigest === undefined) {
|
|
179
|
-
return Promise.reject(new Error('Preview measure requires a completed render.'));
|
|
180
|
-
}
|
|
181
|
-
if (this.#pendingMeasures.has(payload.requestId)) {
|
|
182
|
-
return Promise.reject(new Error(`Measure ${payload.requestId} is already pending.`));
|
|
183
|
-
}
|
|
184
|
-
for (const [requestId, pending] of this.#pendingMeasures) {
|
|
185
|
-
clearTimeout(pending.timeout);
|
|
186
|
-
pending.cleanup();
|
|
187
|
-
pending.reject(new Error(`Preview measure ${requestId} was superseded by ${payload.requestId}.`));
|
|
188
|
-
}
|
|
189
|
-
this.#pendingMeasures.clear();
|
|
190
|
-
return new Promise((resolve, reject) => {
|
|
191
|
-
const abort = () => {
|
|
192
|
-
const pending = this.#pendingMeasures.get(payload.requestId);
|
|
193
|
-
if (pending !== undefined) {
|
|
194
|
-
clearTimeout(pending.timeout);
|
|
195
|
-
this.#pendingMeasures.delete(payload.requestId);
|
|
196
|
-
pending.cleanup();
|
|
197
|
-
pending.reject(new Error('Preview measure was aborted.'));
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
const cleanup = () => {
|
|
201
|
-
options.signal?.removeEventListener('abort', abort);
|
|
202
|
-
};
|
|
203
|
-
const timeout = setTimeout(() => {
|
|
204
|
-
const pending = this.#pendingMeasures.get(payload.requestId);
|
|
205
|
-
if (pending !== undefined) {
|
|
206
|
-
this.#pendingMeasures.delete(payload.requestId);
|
|
207
|
-
pending.cleanup();
|
|
208
|
-
pending.reject(new Error(`Preview measure ${payload.requestId} timed out.`));
|
|
209
|
-
}
|
|
210
|
-
}, this.#timeoutMilliseconds);
|
|
211
|
-
this.#pendingMeasures.set(payload.requestId, { cleanup, reject, resolve, timeout });
|
|
212
|
-
options.signal?.addEventListener('abort', abort, { once: true });
|
|
213
|
-
this.#post({
|
|
214
|
-
channelId: this.#channelId,
|
|
215
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
216
|
-
kind: 'preview-message',
|
|
217
|
-
payload,
|
|
218
|
-
sequence: this.#sequence++,
|
|
219
|
-
sessionGeneration: this.#sessionGeneration,
|
|
220
|
-
type: 'studio.preview/measure',
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Drive the preview surface to a semantic viewport role or to bounded
|
|
226
|
-
* explicit dimensions. The two are alternatives, so a payload carrying both
|
|
227
|
-
* is refused before it reaches the channel.
|
|
228
|
-
*/
|
|
229
|
-
setViewport(payload) {
|
|
230
|
-
this.#assertActive();
|
|
231
|
-
const hasRole = payload.viewport !== undefined;
|
|
232
|
-
const hasDimensions = payload.width !== undefined || payload.height !== undefined;
|
|
233
|
-
if (hasRole === hasDimensions) {
|
|
234
|
-
throw new RangeError('A viewport message carries either a semantic role or explicit dimensions, never both.');
|
|
235
|
-
}
|
|
236
|
-
this.#post({
|
|
237
|
-
channelId: this.#channelId,
|
|
238
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
239
|
-
kind: 'preview-message',
|
|
240
|
-
payload,
|
|
241
|
-
sequence: this.#sequence++,
|
|
242
|
-
sessionGeneration: this.#sessionGeneration,
|
|
243
|
-
type: 'studio.preview/viewport',
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Instruct the renderer to revoke the resources it holds for a superseded
|
|
248
|
-
* draft while the channel stays open. This is not teardown: teardown ends
|
|
249
|
-
* the session, dispose frees a render's resources within it.
|
|
250
|
-
*/
|
|
251
|
-
disposeDraft(payload) {
|
|
252
|
-
this.#assertActive();
|
|
253
|
-
this.#post({
|
|
254
|
-
channelId: this.#channelId,
|
|
255
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
256
|
-
kind: 'preview-message',
|
|
257
|
-
payload,
|
|
258
|
-
sequence: this.#sequence++,
|
|
259
|
-
sessionGeneration: this.#sessionGeneration,
|
|
260
|
-
type: 'studio.preview/dispose',
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
/** Observe trusted marker interactions the renderer reports. */
|
|
264
|
-
onActivated(listener) {
|
|
265
|
-
this.#activationListeners.add(listener);
|
|
266
|
-
return () => {
|
|
267
|
-
this.#activationListeners.delete(listener);
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
select(payload) {
|
|
271
|
-
this.#assertActive();
|
|
272
|
-
this.#post({
|
|
273
|
-
channelId: this.#channelId,
|
|
274
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
275
|
-
kind: 'preview-message',
|
|
276
|
-
payload,
|
|
277
|
-
sequence: this.#sequence++,
|
|
278
|
-
sessionGeneration: this.#sessionGeneration,
|
|
279
|
-
type: 'studio.preview/select',
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
#assertActive() {
|
|
283
|
-
if (this.#disposed) {
|
|
284
|
-
throw new Error('Preview client was disposed.');
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
#post(message) {
|
|
288
|
-
this.#target.postMessage(message, this.#targetOrigin);
|
|
289
|
-
}
|
|
290
|
-
#receive(event) {
|
|
291
|
-
if (event.origin !== this.#targetOrigin ||
|
|
292
|
-
event.source !== this.#target ||
|
|
293
|
-
!isPreviewMessage(event.data) ||
|
|
294
|
-
event.data.channelId !== this.#channelId ||
|
|
295
|
-
event.data.sessionGeneration !== this.#sessionGeneration ||
|
|
296
|
-
event.data.sequence <= this.#lastInboundSequence) {
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
this.#lastInboundSequence = event.data.sequence;
|
|
300
|
-
if (event.data.type === 'studio.preview/activated') {
|
|
301
|
-
for (const listener of this.#activationListeners) {
|
|
302
|
-
listener(event.data.payload);
|
|
303
|
-
}
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
if (event.data.type === 'studio.preview/rendered') {
|
|
307
|
-
if (event.data.payload.draftDigest !== this.#latestRenderDigest) {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
const pending = this.#pending.get(event.data.payload.draftDigest);
|
|
311
|
-
if (pending !== undefined) {
|
|
312
|
-
clearTimeout(pending.timeout);
|
|
313
|
-
pending.cleanup();
|
|
314
|
-
this.#pending.delete(event.data.payload.draftDigest);
|
|
315
|
-
this.#latestRenderDigest = undefined;
|
|
316
|
-
this.#latestRenderedDigest = event.data.payload.draftDigest;
|
|
317
|
-
pending.resolve(event.data.payload);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
else if (event.data.type === 'studio.preview/measurements') {
|
|
321
|
-
const pending = this.#pendingMeasures.get(event.data.payload.requestId);
|
|
322
|
-
if (pending !== undefined) {
|
|
323
|
-
clearTimeout(pending.timeout);
|
|
324
|
-
pending.cleanup();
|
|
325
|
-
this.#pendingMeasures.delete(event.data.payload.requestId);
|
|
326
|
-
// Geometry measured against a superseded render is discarded, not surfaced:
|
|
327
|
-
// the typed stale outcome tells the caller to re-measure.
|
|
328
|
-
if (event.data.payload.draftDigest === this.#latestRenderedDigest) {
|
|
329
|
-
pending.resolve({ geometry: event.data.payload, status: 'measured' });
|
|
330
|
-
}
|
|
331
|
-
else {
|
|
332
|
-
pending.resolve({ measuredDigest: event.data.payload.draftDigest, status: 'stale' });
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
else if (event.data.type === 'studio.preview/error') {
|
|
337
|
-
const message = event.data.payload.message.defaultMessage ?? event.data.payload.message.key;
|
|
338
|
-
const correlationId = event.data.payload.correlationId;
|
|
339
|
-
if (correlationId !== undefined) {
|
|
340
|
-
const pendingRender = this.#pending.get(correlationId);
|
|
341
|
-
const pendingMeasure = this.#pendingMeasures.get(correlationId);
|
|
342
|
-
if (pendingRender === undefined && pendingMeasure === undefined) {
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (pendingRender !== undefined) {
|
|
346
|
-
clearTimeout(pendingRender.timeout);
|
|
347
|
-
pendingRender.cleanup();
|
|
348
|
-
pendingRender.reject(new Error(message));
|
|
349
|
-
this.#pending.delete(correlationId);
|
|
350
|
-
if (this.#latestRenderDigest === correlationId) {
|
|
351
|
-
this.#latestRenderDigest = undefined;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
if (pendingMeasure !== undefined) {
|
|
355
|
-
clearTimeout(pendingMeasure.timeout);
|
|
356
|
-
pendingMeasure.cleanup();
|
|
357
|
-
pendingMeasure.reject(new Error(message));
|
|
358
|
-
this.#pendingMeasures.delete(correlationId);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
for (const pending of this.#pending.values()) {
|
|
363
|
-
clearTimeout(pending.timeout);
|
|
364
|
-
pending.cleanup();
|
|
365
|
-
pending.reject(new Error(message));
|
|
366
|
-
}
|
|
367
|
-
this.#pending.clear();
|
|
368
|
-
for (const pending of this.#pendingMeasures.values()) {
|
|
369
|
-
clearTimeout(pending.timeout);
|
|
370
|
-
pending.cleanup();
|
|
371
|
-
pending.reject(new Error(message));
|
|
372
|
-
}
|
|
373
|
-
this.#pendingMeasures.clear();
|
|
374
|
-
this.#latestRenderDigest = undefined;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
else if (event.data.type === 'studio.preview/ready') {
|
|
378
|
-
this.#readyPayload = event.data.payload;
|
|
379
|
-
const waiters = [...this.#pendingReady];
|
|
380
|
-
this.#pendingReady.clear();
|
|
381
|
-
for (const pending of waiters) {
|
|
382
|
-
clearTimeout(pending.timeout);
|
|
383
|
-
pending.cleanup();
|
|
384
|
-
pending.resolve(event.data.payload);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
else if (event.data.type === 'studio.preview/reload' ||
|
|
388
|
-
event.data.type === 'studio.preview/teardown') {
|
|
389
|
-
const reason = event.data.type === 'studio.preview/reload'
|
|
390
|
-
? 'Preview renderer reloaded before responding.'
|
|
391
|
-
: 'Preview channel was torn down.';
|
|
392
|
-
for (const pending of this.#pending.values()) {
|
|
393
|
-
clearTimeout(pending.timeout);
|
|
394
|
-
pending.cleanup();
|
|
395
|
-
pending.reject(new Error(reason));
|
|
396
|
-
}
|
|
397
|
-
this.#pending.clear();
|
|
398
|
-
// A reload voids in-flight measurements exactly like it voids renders, and the
|
|
399
|
-
// digest they were bound to no longer describes what the surface shows.
|
|
400
|
-
for (const pending of this.#pendingMeasures.values()) {
|
|
401
|
-
clearTimeout(pending.timeout);
|
|
402
|
-
pending.cleanup();
|
|
403
|
-
pending.reject(new Error(reason));
|
|
404
|
-
}
|
|
405
|
-
this.#pendingMeasures.clear();
|
|
406
|
-
this.#latestRenderDigest = undefined;
|
|
407
|
-
this.#latestRenderedDigest = undefined;
|
|
408
|
-
// A reloaded renderer announces itself again; the cached payload may
|
|
409
|
-
// no longer describe it.
|
|
410
|
-
this.#readyPayload = undefined;
|
|
411
|
-
}
|
|
412
|
-
const teardown = event.data.type === 'studio.preview/teardown';
|
|
413
|
-
for (const listener of this.#listeners) {
|
|
414
|
-
listener(event.data);
|
|
415
|
-
}
|
|
416
|
-
if (teardown) {
|
|
417
|
-
this.dispose();
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
/** Announce channel closure to the host, then dispose this client. */
|
|
421
|
-
teardown(reason) {
|
|
422
|
-
this.#assertActive();
|
|
423
|
-
this.#post({
|
|
424
|
-
channelId: this.#channelId,
|
|
425
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
426
|
-
kind: 'preview-message',
|
|
427
|
-
payload: { reason },
|
|
428
|
-
sequence: this.#sequence++,
|
|
429
|
-
sessionGeneration: this.#sessionGeneration,
|
|
430
|
-
type: 'studio.preview/teardown',
|
|
431
|
-
});
|
|
432
|
-
this.dispose();
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
// Shared with PreviewHost; intentionally not re-exported from the package index.
|
|
436
|
-
export function normalizeOrigin(input) {
|
|
437
|
-
if (input === '*') {
|
|
438
|
-
throw new TypeError('Preview target origin must be exact; wildcard origins are forbidden.');
|
|
439
|
-
}
|
|
440
|
-
const url = new URL(input);
|
|
441
|
-
if (url.origin === 'null') {
|
|
442
|
-
throw new TypeError('Preview target origin must use a network origin.');
|
|
443
|
-
}
|
|
444
|
-
return url.origin;
|
|
445
|
-
}
|
|
446
|
-
//# sourceMappingURL=preview-client.js.map
|
|
1
|
+
import{isPreviewMarker as e,isPreviewMessage as t,STUDIO_CONTRACT_VERSION as n}from"@kumwe/studio-protocol";export class PreviewChannelError extends Error{code;retryable;constructor(e,t,n=!1){super(t),this.name=`PreviewChannelError`,this.code=e,this.retryable=n}}function i(e){try{return structuredClone(e)}catch{throw new PreviewChannelError(`studio.preview/invalid-outbound-message`,`Refused an invalid outbound preview message.`)}}export class PreviewClient{#activationListeners=new Set;#channelId;#listener;#listeners=new Set;#markerInventory=new Set;#pending=new Map;#pendingMeasures=new Map;#pendingReady=new Set;#sessionGeneration;#source;#target;#targetOrigin;#timeoutMilliseconds;#usedRequestIds=new Set;#disposed=!1;#lastInboundSequence=-1;#latestRenderRequestId;#latestRenderedDigest;#readyPayload;#sequence=0;constructor(e){this.#targetOrigin=normalizeOrigin(e.targetOrigin),this.#channelId=e.channelId,this.#sessionGeneration=e.sessionGeneration,this.#source=e.source,this.#target=e.target,this.#timeoutMilliseconds=e.timeoutMilliseconds??1e4,this.#listener=e=>{this.#receive(e)},this.#source.addEventListener(`message`,this.#listener)}dispose(){if(!this.#disposed){this.#disposed=!0,this.#source.removeEventListener(`message`,this.#listener);for(let e of this.#pending.values())clearTimeout(e.timeout),e.cleanup(),e.reject(Error(`Preview client was disposed.`));this.#pending.clear();for(let e of this.#pendingMeasures.values())clearTimeout(e.timeout),e.cleanup(),e.reject(Error(`Preview client was disposed.`));this.#pendingMeasures.clear();for(let e of this.#pendingReady)clearTimeout(e.timeout),e.cleanup(),e.reject(Error(`Preview client was disposed.`));this.#pendingReady.clear(),this.#activationListeners.clear(),this.#listeners.clear(),this.#latestRenderRequestId=void 0,this.#latestRenderedDigest=void 0,this.#markerInventory.clear()}}onMessage(e){return this.#listeners.add(e),()=>{this.#listeners.delete(e)}}ready(e={}){return this.#disposed?Promise.reject(Error(`Preview client was disposed.`)):e.signal?.aborted===!0?Promise.reject(Error(`Preview ready wait was aborted.`,{cause:e.signal.reason})):this.#readyPayload===void 0?new Promise((t,n)=>{let r=()=>{this.#pendingReady.delete(i)&&(clearTimeout(i.timeout),i.cleanup(),i.reject(Error(`Preview ready wait was aborted.`)))},i={cleanup:()=>{e.signal?.removeEventListener(`abort`,r)},reject:n,resolve:t,timeout:setTimeout(()=>{this.#pendingReady.delete(i)&&(i.cleanup(),i.reject(Error(`Preview ready wait timed out.`)))},this.#timeoutMilliseconds)};this.#pendingReady.add(i),e.signal?.addEventListener(`abort`,r,{once:!0})}):Promise.resolve(this.#readyPayload)}render(e,t={}){if(this.#disposed)return Promise.reject(Error(`Preview client was disposed.`));if(t.signal?.aborted===!0)return Promise.reject(Error(`Preview render was aborted.`,{cause:t.signal.reason}));let a;try{a=i(e)}catch(e){return Promise.reject(e instanceof Error?e:new PreviewChannelError(`studio.preview/invalid-outbound-message`,`Refused an invalid outbound preview message.`))}let o={channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:a,sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/render`};try{this.#assertOutbound(o)}catch(e){return Promise.reject(e instanceof Error?e:new PreviewChannelError(`studio.preview/invalid-outbound-message`,`Refused an invalid outbound preview message.`))}if(this.#usedRequestIds.has(a.requestId))return Promise.reject(new PreviewChannelError(`studio.preview/request-id-reused`,`Preview request ${a.requestId} was already used in this session.`));for(let[e,t]of this.#pending)clearTimeout(t.timeout),t.cleanup(),t.reject(Error(`Preview render ${e} was superseded by ${a.requestId}.`));return this.#pending.clear(),this.#rejectPendingMeasures(Error(`Preview measurements were superseded by render ${a.requestId}.`)),this.#usedRequestIds.add(a.requestId),this.#latestRenderRequestId=a.requestId,this.#latestRenderedDigest=void 0,this.#markerInventory.clear(),new Promise((e,n)=>{let r=()=>{let e=this.#pending.get(a.requestId);e!==void 0&&(clearTimeout(e.timeout),this.#pending.delete(a.requestId),e.cleanup(),this.#latestRenderRequestId===a.requestId&&(this.#latestRenderRequestId=void 0),e.reject(Error(`Preview render was aborted.`)),this.#revokeRemoteRender(a.draftDigest,`studio.preview/client-aborted`))},i=()=>{t.signal?.removeEventListener(`abort`,r)},s=setTimeout(()=>{let e=this.#pending.get(a.requestId);e!==void 0&&(this.#pending.delete(a.requestId),e.cleanup(),this.#latestRenderRequestId===a.requestId&&(this.#latestRenderRequestId=void 0),e.reject(Error(`Preview render ${a.requestId} timed out.`)),this.#revokeRemoteRender(a.draftDigest,`studio.preview/client-timeout`))},this.#timeoutMilliseconds);this.#pending.set(a.requestId,{cleanup:i,payload:a,reject:n,resolve:e,timeout:s}),t.signal?.addEventListener(`abort`,r,{once:!0});try{this.#post(o)}catch(e){clearTimeout(s),i(),this.#pending.delete(a.requestId),this.#latestRenderRequestId===a.requestId&&(this.#latestRenderRequestId=void 0),n(e instanceof Error?e:Error(`Preview transport failed.`))}})}measure(t,a={}){if(this.#disposed)return Promise.reject(Error(`Preview client was disposed.`));if(a.signal?.aborted===!0)return Promise.reject(Error(`Preview measure was aborted.`,{cause:a.signal.reason}));let o;try{o=i(t)}catch(e){return Promise.reject(e instanceof Error?e:new PreviewChannelError(`studio.preview/invalid-outbound-message`,`Refused an invalid outbound preview message.`))}if(this.#latestRenderedDigest===void 0)return Promise.reject(Error(`Preview measure requires a completed render.`));let s={channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:o,sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/measure`};try{this.#assertOutbound(s)}catch(e){return Promise.reject(e instanceof Error?e:new PreviewChannelError(`studio.preview/invalid-outbound-message`,`Refused an invalid outbound preview message.`))}if(this.#usedRequestIds.has(o.requestId))return Promise.reject(new PreviewChannelError(`studio.preview/request-id-reused`,`Preview request ${o.requestId} was already used in this session.`));if(o.markers.some(t=>!this.#markerInventory.has(t)||!e(t,this.#latestRenderedDigest)))return Promise.reject(new PreviewChannelError(`studio.preview/measure-stale-marker`,`Preview measurement markers must belong to the current render inventory.`,!0));for(let[e,t]of this.#pendingMeasures)clearTimeout(t.timeout),t.cleanup(),t.reject(Error(`Preview measure ${e} was superseded by ${o.requestId}.`));return this.#pendingMeasures.clear(),this.#usedRequestIds.add(o.requestId),new Promise((e,t)=>{let n=()=>{let e=this.#pendingMeasures.get(o.requestId);e!==void 0&&(clearTimeout(e.timeout),this.#pendingMeasures.delete(o.requestId),e.cleanup(),e.reject(Error(`Preview measure was aborted.`)))},r=()=>{a.signal?.removeEventListener(`abort`,n)},i=setTimeout(()=>{let e=this.#pendingMeasures.get(o.requestId);e!==void 0&&(this.#pendingMeasures.delete(o.requestId),e.cleanup(),e.reject(Error(`Preview measure ${o.requestId} timed out.`)))},this.#timeoutMilliseconds);this.#pendingMeasures.set(o.requestId,{cleanup:r,payload:o,reject:t,resolve:e,timeout:i}),a.signal?.addEventListener(`abort`,n,{once:!0});try{this.#post(s)}catch(e){clearTimeout(i),r(),this.#pendingMeasures.delete(o.requestId),t(e instanceof Error?e:Error(`Preview transport failed.`))}})}setViewport(e){if(this.#assertActive(),e.viewport!==void 0==(e.width!==void 0||e.height!==void 0))throw RangeError(`A viewport message carries either a semantic role or explicit dimensions, never both.`);let t={channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:e,sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/viewport`};this.#assertOutbound(t),this.#rejectPendingMeasures(new PreviewChannelError(`studio.preview/measure-viewport-changed`,`Preview measurement was invalidated by a viewport change.`,!0)),this.#post(t)}disposeDraft(e){this.#assertActive();let t={channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:e,sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/dispose`};this.#assertOutbound(t);for(let[t,n]of this.#pending)(e.draftDigest===void 0||n.payload.draftDigest===e.draftDigest)&&(clearTimeout(n.timeout),n.cleanup(),n.reject(new PreviewChannelError(`studio.preview/render-disposed`,`Preview render ${t} was disposed before completion.`)),this.#pending.delete(t),this.#latestRenderRequestId===t&&(this.#latestRenderRequestId=void 0));(e.draftDigest===void 0||e.draftDigest===this.#latestRenderedDigest)&&(this.#latestRenderedDigest=void 0,this.#markerInventory.clear(),this.#rejectPendingMeasures(new PreviewChannelError(`studio.preview/measure-disposed`,`Preview measurement was disposed with its render.`))),this.#post(t)}onActivated(e){return this.#activationListeners.add(e),()=>{this.#activationListeners.delete(e)}}select(e){this.#assertActive(),this.#post({channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:e,sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/select`})}#assertActive(){if(this.#disposed)throw Error(`Preview client was disposed.`)}#assertOutbound(e){if(!t(e))throw new PreviewChannelError(`studio.preview/invalid-outbound-message`,`Refused an invalid outbound preview message.`)}#post(e){this.#assertOutbound(e),this.#sequence+=1,this.#target.postMessage(e,this.#targetOrigin)}#rejectPendingMeasures(e){for(let t of this.#pendingMeasures.values())clearTimeout(t.timeout),t.cleanup(),t.reject(e);this.#pendingMeasures.clear()}#revokeRemoteRender(e,t){if(!this.#disposed)try{this.#post({channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:{draftDigest:e,reason:t},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/dispose`})}catch{}}#receive(n){if(n.origin!==this.#targetOrigin||n.source!==this.#target||!t(n.data)||n.data.channelId!==this.#channelId||n.data.sessionGeneration!==this.#sessionGeneration||n.data.sequence<=this.#lastInboundSequence)return;if(this.#lastInboundSequence=n.data.sequence,n.data.type===`studio.preview/activated`){if(!this.#markerInventory.has(n.data.payload.marker)||!e(n.data.payload.marker,this.#latestRenderedDigest))return;for(let e of this.#activationListeners)e(n.data.payload);return}if(n.data.type===`studio.preview/rendered`){if(n.data.payload.requestId!==this.#latestRenderRequestId)return;let e=this.#pending.get(n.data.payload.requestId);if(e!==void 0&&n.data.payload.draftDigest!==e.payload.draftDigest){clearTimeout(e.timeout),e.cleanup(),this.#pending.delete(n.data.payload.requestId),this.#latestRenderRequestId=void 0,e.reject(new PreviewChannelError(`studio.preview/render-correlation-mismatch`,`Preview response digest did not match its render request.`));return}if(e!==void 0){clearTimeout(e.timeout),e.cleanup(),this.#pending.delete(n.data.payload.requestId),this.#latestRenderRequestId=void 0,this.#latestRenderedDigest=n.data.payload.draftDigest,this.#markerInventory.clear();for(let e of n.data.payload.markers)this.#markerInventory.add(e);e.resolve(n.data.payload)}}else if(n.data.type===`studio.preview/measurements`){let e=this.#pendingMeasures.get(n.data.payload.requestId);if(e!==void 0){let t=[...Object.keys(n.data.payload.measurements),...n.data.payload.unknown];if(t.length!==e.payload.markers.length||e.payload.markers.some(e=>!t.includes(e))){clearTimeout(e.timeout),e.cleanup(),this.#pendingMeasures.delete(n.data.payload.requestId),e.reject(new PreviewChannelError(`studio.preview/invalid-measurements`,`Preview measurements did not exactly partition the requested marker inventory.`));return}clearTimeout(e.timeout),e.cleanup(),this.#pendingMeasures.delete(n.data.payload.requestId),n.data.payload.draftDigest===this.#latestRenderedDigest?e.resolve({geometry:n.data.payload,status:`measured`}):e.resolve({measuredDigest:n.data.payload.draftDigest,status:`stale`})}}else if(n.data.type===`studio.preview/error`){let e=n.data.payload.message.defaultMessage??n.data.payload.message.key,t=n.data.payload.correlationId;if(t!==void 0){let i=this.#pending.get(t),a=this.#pendingMeasures.get(t);if(i===void 0&&a===void 0)return;i!==void 0&&(clearTimeout(i.timeout),i.cleanup(),i.reject(new PreviewChannelError(n.data.payload.code,e,n.data.payload.retryable)),this.#pending.delete(t),this.#latestRenderRequestId===t&&(this.#latestRenderRequestId=void 0,this.#markerInventory.clear())),a!==void 0&&(clearTimeout(a.timeout),a.cleanup(),a.reject(new PreviewChannelError(n.data.payload.code,e,n.data.payload.retryable)),this.#pendingMeasures.delete(t))}else{for(let t of this.#pending.values())clearTimeout(t.timeout),t.cleanup(),t.reject(Error(e));this.#pending.clear();for(let t of this.#pendingMeasures.values())clearTimeout(t.timeout),t.cleanup(),t.reject(Error(e));this.#pendingMeasures.clear(),this.#latestRenderRequestId=void 0,this.#latestRenderedDigest=void 0,this.#markerInventory.clear()}}else if(n.data.type===`studio.preview/ready`){this.#readyPayload=n.data.payload;let e=[...this.#pendingReady];this.#pendingReady.clear();for(let t of e)clearTimeout(t.timeout),t.cleanup(),t.resolve(n.data.payload)}else if(n.data.type===`studio.preview/reload`||n.data.type===`studio.preview/teardown`){let e=n.data.type===`studio.preview/reload`?`Preview renderer reloaded before responding.`:`Preview channel was torn down.`;for(let t of this.#pending.values())clearTimeout(t.timeout),t.cleanup(),t.reject(Error(e));this.#pending.clear();for(let t of this.#pendingMeasures.values())clearTimeout(t.timeout),t.cleanup(),t.reject(Error(e));this.#pendingMeasures.clear(),this.#latestRenderRequestId=void 0,this.#latestRenderedDigest=void 0,this.#markerInventory.clear(),this.#readyPayload=void 0}let i=n.data.type===`studio.preview/teardown`;for(let e of this.#listeners)e(n.data);i&&this.dispose()}teardown(e){this.#assertActive(),this.#post({channelId:this.#channelId,contractVersion:n,kind:`preview-message`,payload:{reason:e},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/teardown`}),this.dispose()}}export function normalizeOrigin(e){if(e===`*`)throw TypeError(`Preview target origin must be exact; wildcard origins are forbidden.`);let t=new URL(e);if(t.origin===`null`)throw TypeError(`Preview target origin must use a network origin.`);return t.origin}
|
package/dist/preview-host.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type LocalName, type PreviewMarkerRect, type PreviewRenderedPayload, type PreviewRenderPayload, type PreviewActivatedPayload, type PreviewDisposePayload, type PreviewSelectPayload, type PreviewViewportPayload, type PreviewViewportMetrics, type QualifiedName, type StableId } from '@kumwe/studio-protocol';
|
|
2
2
|
import { type PreviewMessageSource, type PreviewMessageTarget } from './preview-client.js';
|
|
3
|
-
|
|
3
|
+
/** Render work is attempt-scoped; implementations should stop promptly when the signal aborts. */
|
|
4
|
+
export type PreviewRenderCallback = (payload: PreviewRenderPayload, signal: AbortSignal) => Promise<PreviewRenderedPayload>;
|
|
4
5
|
/**
|
|
5
6
|
* Raw measurement produced by the embedding renderer. The responder never reads the
|
|
6
7
|
* DOM itself: the renderer supplies marker rectangles and viewport metrics, keeping
|
|
@@ -11,7 +12,8 @@ export interface PreviewMeasurement {
|
|
|
11
12
|
rects: Record<StableId, PreviewMarkerRect[]>;
|
|
12
13
|
viewport: PreviewViewportMetrics;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
/** Measurement work is render-generation-scoped and receives the same cancellation discipline. */
|
|
16
|
+
export type PreviewMeasureCallback = (markers: StableId[], signal: AbortSignal) => Promise<PreviewMeasurement>;
|
|
15
17
|
export type PreviewSelectListener = (payload: PreviewSelectPayload) => void;
|
|
16
18
|
export type PreviewViewportListener = (payload: PreviewViewportPayload) => void;
|
|
17
19
|
export type PreviewDisposeListener = (payload: PreviewDisposePayload) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-host.d.ts","sourceRoot":"","sources":["../src/preview-host.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"preview-host.d.ts","sourceRoot":"","sources":["../src/preview-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACd,KAAK,iBAAiB,EAGtB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAE7B,kGAAkG;AAClG,MAAM,MAAM,qBAAqB,GAAG,CAClC,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAErC;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC7C,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAED,kGAAkG;AAClG,MAAM,MAAM,sBAAsB,GAAG,CACnC,OAAO,EAAE,QAAQ,EAAE,EACnB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;AAE5E,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;AAEhF,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAE9E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,EAAE,CAAC;CACxB;AAgBD;;;;;;GAMG;AACH,qBAAa,WAAW;;gBAyBH,OAAO,EAAE,kBAAkB;IAgB9C;;;;OAIG;IACI,QAAQ,IAAI,IAAI;IAiBhB,OAAO,IAAI,IAAI;IAetB;;;;OAIG;IACI,kBAAkB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI;IAmBjE,wEAAwE;IACjE,UAAU,CAAC,QAAQ,EAAE,uBAAuB,GAAG,MAAM,IAAI;IAOhE,4EAA4E;IACrE,SAAS,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAOvD,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAO5D;;;OAGG;IACI,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAkB1C,sEAAsE;IAC/D,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;CAiX7C"}
|
package/dist/preview-host.js
CHANGED
|
@@ -1,375 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { normalizeOrigin, } from './preview-client.js';
|
|
3
|
-
/**
|
|
4
|
-
* The preview-surface half of the channel: answers `studio.preview/render` and
|
|
5
|
-
* `studio.preview/measure` requests from a `PreviewClient` and forwards
|
|
6
|
-
* `studio.preview/select` to registered listeners. Inbound messages are filtered exactly
|
|
7
|
-
* like the client filters its own: pinned origin, expected source window, canonical
|
|
8
|
-
* schema, channel ID, session generation, and a strictly increasing sequence.
|
|
9
|
-
*/
|
|
10
|
-
export class PreviewHost {
|
|
11
|
-
#channelId;
|
|
12
|
-
#listener;
|
|
13
|
-
#measureCallback;
|
|
14
|
-
#renderCallback;
|
|
15
|
-
#renderer;
|
|
16
|
-
#viewportListeners = new Set();
|
|
17
|
-
#disposeListeners = new Set();
|
|
18
|
-
#selectListeners = new Set();
|
|
19
|
-
#sessionGeneration;
|
|
20
|
-
#source;
|
|
21
|
-
#target;
|
|
22
|
-
#targetOrigin;
|
|
23
|
-
#viewports;
|
|
24
|
-
#disposed = false;
|
|
25
|
-
#lastInboundSequence = -1;
|
|
26
|
-
#latestMeasureRequestId;
|
|
27
|
-
#latestRenderDigest;
|
|
28
|
-
#measuredRenderDigest;
|
|
29
|
-
#sequence = 0;
|
|
30
|
-
constructor(options) {
|
|
31
|
-
this.#targetOrigin = normalizeOrigin(options.targetOrigin);
|
|
32
|
-
this.#channelId = options.channelId;
|
|
33
|
-
this.#sessionGeneration = options.sessionGeneration;
|
|
34
|
-
this.#source = options.source;
|
|
35
|
-
this.#target = options.target;
|
|
36
|
-
this.#measureCallback = options.measure;
|
|
37
|
-
this.#renderCallback = options.render;
|
|
38
|
-
this.#renderer = options.renderer;
|
|
39
|
-
this.#viewports = [...options.viewports];
|
|
40
|
-
this.#listener = (event) => {
|
|
41
|
-
this.#receive(event);
|
|
42
|
-
};
|
|
43
|
-
this.#source.addEventListener('message', this.#listener);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Posts the `studio.preview/ready` announcement carrying the wire protocol version,
|
|
47
|
-
* renderer id, and viewport inventory. Announcement is an explicit step so the host can
|
|
48
|
-
* finish its own setup before opening the channel.
|
|
49
|
-
*/
|
|
50
|
-
announce() {
|
|
51
|
-
this.#assertActive();
|
|
52
|
-
this.#post({
|
|
53
|
-
channelId: this.#channelId,
|
|
54
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
55
|
-
kind: 'preview-message',
|
|
56
|
-
payload: {
|
|
57
|
-
protocolVersion: STUDIO_WIRE_PROTOCOL_VERSION,
|
|
58
|
-
renderer: this.#renderer,
|
|
59
|
-
viewports: [...this.#viewports],
|
|
60
|
-
},
|
|
61
|
-
sequence: this.#sequence++,
|
|
62
|
-
sessionGeneration: this.#sessionGeneration,
|
|
63
|
-
type: 'studio.preview/ready',
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
dispose() {
|
|
67
|
-
if (this.#disposed) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
this.#disposed = true;
|
|
71
|
-
this.#source.removeEventListener('message', this.#listener);
|
|
72
|
-
this.#selectListeners.clear();
|
|
73
|
-
this.#viewportListeners.clear();
|
|
74
|
-
this.#disposeListeners.clear();
|
|
75
|
-
this.#latestMeasureRequestId = undefined;
|
|
76
|
-
this.#latestRenderDigest = undefined;
|
|
77
|
-
this.#measuredRenderDigest = undefined;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Report a trusted interaction with a marked region. The renderer reports
|
|
81
|
-
* intent, never raw input events, and the marker carries nothing beyond the
|
|
82
|
-
* node identity the render already published.
|
|
83
|
-
*/
|
|
84
|
-
announceActivation(payload) {
|
|
85
|
-
this.#post({
|
|
86
|
-
channelId: this.#channelId,
|
|
87
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
88
|
-
kind: 'preview-message',
|
|
89
|
-
payload,
|
|
90
|
-
sequence: this.#sequence++,
|
|
91
|
-
sessionGeneration: this.#sessionGeneration,
|
|
92
|
-
type: 'studio.preview/activated',
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
/** Observe viewport instructions the client drives the surface with. */
|
|
96
|
-
onViewport(listener) {
|
|
97
|
-
this.#viewportListeners.add(listener);
|
|
98
|
-
return () => {
|
|
99
|
-
this.#viewportListeners.delete(listener);
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
/** Observe requests to revoke the resources held for a superseded draft. */
|
|
103
|
-
onDispose(listener) {
|
|
104
|
-
this.#disposeListeners.add(listener);
|
|
105
|
-
return () => {
|
|
106
|
-
this.#disposeListeners.delete(listener);
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
onSelect(listener) {
|
|
110
|
-
this.#selectListeners.add(listener);
|
|
111
|
-
return () => {
|
|
112
|
-
this.#selectListeners.delete(listener);
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Announce that the renderer reloaded: any in-flight render or measurement is
|
|
117
|
-
* void and the client must resend. The host re-announces readiness afterwards.
|
|
118
|
-
*/
|
|
119
|
-
reload(reason) {
|
|
120
|
-
this.#assertActive();
|
|
121
|
-
this.#latestMeasureRequestId = undefined;
|
|
122
|
-
this.#latestRenderDigest = undefined;
|
|
123
|
-
this.#measuredRenderDigest = undefined;
|
|
124
|
-
this.#post({
|
|
125
|
-
channelId: this.#channelId,
|
|
126
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
127
|
-
kind: 'preview-message',
|
|
128
|
-
payload: { reason },
|
|
129
|
-
sequence: this.#sequence++,
|
|
130
|
-
sessionGeneration: this.#sessionGeneration,
|
|
131
|
-
type: 'studio.preview/reload',
|
|
132
|
-
});
|
|
133
|
-
this.announce();
|
|
134
|
-
}
|
|
135
|
-
/** Announce channel closure to the client, then dispose this host. */
|
|
136
|
-
teardown(reason) {
|
|
137
|
-
this.#assertActive();
|
|
138
|
-
this.#post({
|
|
139
|
-
channelId: this.#channelId,
|
|
140
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
141
|
-
kind: 'preview-message',
|
|
142
|
-
payload: { reason },
|
|
143
|
-
sequence: this.#sequence++,
|
|
144
|
-
sessionGeneration: this.#sessionGeneration,
|
|
145
|
-
type: 'studio.preview/teardown',
|
|
146
|
-
});
|
|
147
|
-
this.dispose();
|
|
148
|
-
}
|
|
149
|
-
#assertActive() {
|
|
150
|
-
if (this.#disposed) {
|
|
151
|
-
throw new Error('Preview host was disposed.');
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
#handleMeasure(payload) {
|
|
155
|
-
const requestId = payload.requestId;
|
|
156
|
-
this.#latestMeasureRequestId = requestId;
|
|
157
|
-
if (this.#measureCallback === undefined) {
|
|
158
|
-
this.#settleMeasureFailure(requestId, {
|
|
159
|
-
code: 'studio.preview/measure-unavailable',
|
|
160
|
-
defaultMessage: 'Preview measurement is unavailable.',
|
|
161
|
-
retryable: false,
|
|
162
|
-
});
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
if (this.#measuredRenderDigest === undefined) {
|
|
166
|
-
// Nothing has rendered yet, so there is no digest to bind geometry to.
|
|
167
|
-
this.#settleMeasureFailure(requestId, {
|
|
168
|
-
code: 'studio.preview/measure-unavailable',
|
|
169
|
-
defaultMessage: 'Preview measurement is unavailable.',
|
|
170
|
-
retryable: true,
|
|
171
|
-
});
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
const markers = [...new Set(payload.markers)];
|
|
175
|
-
let result;
|
|
176
|
-
try {
|
|
177
|
-
result = this.#measureCallback(markers);
|
|
178
|
-
}
|
|
179
|
-
catch {
|
|
180
|
-
this.#settleMeasureFailure(requestId, measureFailed());
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
void result.then((measurement) => {
|
|
184
|
-
this.#settleMeasured(requestId, markers, measurement);
|
|
185
|
-
}, () => {
|
|
186
|
-
this.#settleMeasureFailure(requestId, measureFailed());
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
#handleRender(payload) {
|
|
190
|
-
const draftDigest = payload.draftDigest;
|
|
191
|
-
this.#latestRenderDigest = draftDigest;
|
|
192
|
-
let result;
|
|
193
|
-
try {
|
|
194
|
-
result = this.#renderCallback(payload);
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
this.#settleFailure(draftDigest);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
void result.then((rendered) => {
|
|
201
|
-
this.#settleRendered(draftDigest, rendered);
|
|
202
|
-
}, () => {
|
|
203
|
-
this.#settleFailure(draftDigest);
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
#post(message) {
|
|
207
|
-
this.#target.postMessage(message, this.#targetOrigin);
|
|
208
|
-
}
|
|
209
|
-
#receive(event) {
|
|
210
|
-
if (event.origin !== this.#targetOrigin ||
|
|
211
|
-
event.source !== this.#target ||
|
|
212
|
-
!isPreviewMessage(event.data) ||
|
|
213
|
-
event.data.channelId !== this.#channelId ||
|
|
214
|
-
event.data.sessionGeneration !== this.#sessionGeneration ||
|
|
215
|
-
event.data.sequence <= this.#lastInboundSequence) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
this.#lastInboundSequence = event.data.sequence;
|
|
219
|
-
if (event.data.type === 'studio.preview/render') {
|
|
220
|
-
this.#handleRender(event.data.payload);
|
|
221
|
-
}
|
|
222
|
-
else if (event.data.type === 'studio.preview/measure') {
|
|
223
|
-
this.#handleMeasure(event.data.payload);
|
|
224
|
-
}
|
|
225
|
-
else if (event.data.type === 'studio.preview/select') {
|
|
226
|
-
for (const listener of this.#selectListeners) {
|
|
227
|
-
listener(event.data.payload);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else if (event.data.type === 'studio.preview/viewport') {
|
|
231
|
-
for (const listener of this.#viewportListeners) {
|
|
232
|
-
listener(event.data.payload);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
else if (event.data.type === 'studio.preview/dispose') {
|
|
236
|
-
// Resource revocation for a superseded draft; the channel stays open.
|
|
237
|
-
for (const listener of this.#disposeListeners) {
|
|
238
|
-
listener(event.data.payload);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
else if (event.data.type === 'studio.preview/teardown') {
|
|
242
|
-
this.dispose();
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Measurer failure details never cross the channel: the rejection reason is dropped and a
|
|
246
|
-
// stable generic error is posted instead, correlated by the request identifier.
|
|
247
|
-
#settleMeasureFailure(requestId, failure) {
|
|
248
|
-
if (this.#disposed || this.#latestMeasureRequestId !== requestId) {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
this.#latestMeasureRequestId = undefined;
|
|
252
|
-
this.#post({
|
|
253
|
-
channelId: this.#channelId,
|
|
254
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
255
|
-
kind: 'preview-message',
|
|
256
|
-
payload: {
|
|
257
|
-
code: failure.code,
|
|
258
|
-
correlationId: requestId,
|
|
259
|
-
message: { defaultMessage: failure.defaultMessage, key: failure.code },
|
|
260
|
-
retryable: failure.retryable,
|
|
261
|
-
},
|
|
262
|
-
sequence: this.#sequence++,
|
|
263
|
-
sessionGeneration: this.#sessionGeneration,
|
|
264
|
-
type: 'studio.preview/error',
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
// Geometry is stamped with the digest of the render the surface currently shows, and only
|
|
268
|
-
// markers from the request are answered — requested markers the measurer cannot place are
|
|
269
|
-
// listed as unknown, extra markers it invents are dropped. A measurement superseded by a
|
|
270
|
-
// newer request, voided by a reload, or settling after disposal is dropped silently.
|
|
271
|
-
#settleMeasured(requestId, markers, measurement) {
|
|
272
|
-
const draftDigest = this.#measuredRenderDigest;
|
|
273
|
-
if (this.#disposed || this.#latestMeasureRequestId !== requestId || draftDigest === undefined) {
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
this.#latestMeasureRequestId = undefined;
|
|
277
|
-
const measurements = {};
|
|
278
|
-
const unknown = [];
|
|
279
|
-
for (const marker of markers) {
|
|
280
|
-
const rects = Object.hasOwn(measurement.rects, marker)
|
|
281
|
-
? measurement.rects[marker]
|
|
282
|
-
: undefined;
|
|
283
|
-
if (rects === undefined || rects.length === 0) {
|
|
284
|
-
unknown.push(marker);
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
measurements[marker] = rects.map((rect) => ({
|
|
288
|
-
height: rect.height,
|
|
289
|
-
width: rect.width,
|
|
290
|
-
x: rect.x,
|
|
291
|
-
y: rect.y,
|
|
292
|
-
}));
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
this.#post({
|
|
296
|
-
channelId: this.#channelId,
|
|
297
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
298
|
-
kind: 'preview-message',
|
|
299
|
-
payload: {
|
|
300
|
-
draftDigest,
|
|
301
|
-
measurements,
|
|
302
|
-
requestId,
|
|
303
|
-
unknown,
|
|
304
|
-
viewport: {
|
|
305
|
-
devicePixelRatio: measurement.viewport.devicePixelRatio,
|
|
306
|
-
height: measurement.viewport.height,
|
|
307
|
-
scrollX: measurement.viewport.scrollX,
|
|
308
|
-
scrollY: measurement.viewport.scrollY,
|
|
309
|
-
width: measurement.viewport.width,
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
sequence: this.#sequence++,
|
|
313
|
-
sessionGeneration: this.#sessionGeneration,
|
|
314
|
-
type: 'studio.preview/measurements',
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
// Renderer failure details never cross the channel: the rejection reason is dropped and a
|
|
318
|
-
// stable generic error is posted instead, correlated by the request's draft digest.
|
|
319
|
-
#settleFailure(draftDigest) {
|
|
320
|
-
if (this.#disposed || this.#latestRenderDigest !== draftDigest) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
this.#latestRenderDigest = undefined;
|
|
324
|
-
this.#post({
|
|
325
|
-
channelId: this.#channelId,
|
|
326
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
327
|
-
kind: 'preview-message',
|
|
328
|
-
payload: {
|
|
329
|
-
code: 'studio.preview/render-failed',
|
|
330
|
-
correlationId: draftDigest,
|
|
331
|
-
message: {
|
|
332
|
-
defaultMessage: 'Preview rendering failed.',
|
|
333
|
-
key: 'studio.preview/render-failed',
|
|
334
|
-
},
|
|
335
|
-
retryable: true,
|
|
336
|
-
},
|
|
337
|
-
sequence: this.#sequence++,
|
|
338
|
-
sessionGeneration: this.#sessionGeneration,
|
|
339
|
-
type: 'studio.preview/error',
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
// The response digest is stamped from the request, so a callback can never answer for a
|
|
343
|
-
// different draft than the one it was asked to render. Results that were superseded by a
|
|
344
|
-
// newer request, or that settle after disposal, are dropped silently.
|
|
345
|
-
#settleRendered(draftDigest, rendered) {
|
|
346
|
-
if (this.#disposed || this.#latestRenderDigest !== draftDigest) {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
this.#latestRenderDigest = undefined;
|
|
350
|
-
// The surface now shows this render; measurements are bound to its digest.
|
|
351
|
-
this.#measuredRenderDigest = draftDigest;
|
|
352
|
-
this.#post({
|
|
353
|
-
channelId: this.#channelId,
|
|
354
|
-
contractVersion: STUDIO_CONTRACT_VERSION,
|
|
355
|
-
kind: 'preview-message',
|
|
356
|
-
payload: {
|
|
357
|
-
diagnostics: rendered.diagnostics,
|
|
358
|
-
draftDigest,
|
|
359
|
-
markers: rendered.markers,
|
|
360
|
-
...(rendered.markerMap === undefined ? {} : { markerMap: rendered.markerMap }),
|
|
361
|
-
},
|
|
362
|
-
sequence: this.#sequence++,
|
|
363
|
-
sessionGeneration: this.#sessionGeneration,
|
|
364
|
-
type: 'studio.preview/rendered',
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
function measureFailed() {
|
|
369
|
-
return {
|
|
370
|
-
code: 'studio.preview/measure-failed',
|
|
371
|
-
defaultMessage: 'Preview measurement failed.',
|
|
372
|
-
retryable: true,
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
//# sourceMappingURL=preview-host.js.map
|
|
1
|
+
import{isPreviewMarker as e,isPreviewMessage as t,isPreviewRenderedPayload as n,STUDIO_CONTRACT_VERSION as r,STUDIO_WIRE_PROTOCOL_VERSION as i}from"@kumwe/studio-protocol";import{normalizeOrigin as a}from"./preview-client.js";export class PreviewHost{#channelId;#listener;#measureCallback;#renderCallback;#renderer;#viewportListeners=new Set;#disposeListeners=new Set;#selectListeners=new Set;#markerInventory=new Set;#sessionGeneration;#source;#target;#targetOrigin;#usedRequestIds=new Set;#viewports;#activeMeasure;#activeRender;#disposed=!1;#lastInboundSequence=-1;#measureGeneration=0;#measuredRenderDigest;#renderGeneration=0;#sequence=0;constructor(e){this.#targetOrigin=a(e.targetOrigin),this.#channelId=e.channelId,this.#sessionGeneration=e.sessionGeneration,this.#source=e.source,this.#target=e.target,this.#measureCallback=e.measure,this.#renderCallback=e.render,this.#renderer=e.renderer,this.#viewports=[...e.viewports],this.#listener=e=>{this.#receive(e)},this.#source.addEventListener(`message`,this.#listener)}announce(){this.#assertActive(),this.#post({channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:{protocolVersion:i,renderer:this.#renderer,viewports:[...this.#viewports]},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/ready`})}dispose(){this.#disposed||(this.#disposed=!0,this.#source.removeEventListener(`message`,this.#listener),this.#selectListeners.clear(),this.#viewportListeners.clear(),this.#disposeListeners.clear(),this.#invalidateMeasure(`Preview host was disposed.`),this.#invalidateRender(`Preview host was disposed.`),this.#measuredRenderDigest=void 0,this.#markerInventory.clear())}announceActivation(t){if(this.#assertActive(),!this.#markerInventory.has(t.marker)||!e(t.marker,this.#measuredRenderDigest))throw RangeError(`Preview activation marker is not in the current render inventory.`);this.#post({channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:t,sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/activated`})}onViewport(e){return this.#viewportListeners.add(e),()=>{this.#viewportListeners.delete(e)}}onDispose(e){return this.#disposeListeners.add(e),()=>{this.#disposeListeners.delete(e)}}onSelect(e){return this.#selectListeners.add(e),()=>{this.#selectListeners.delete(e)}}reload(e){this.#assertActive(),this.#invalidateMeasure(`Preview renderer reloaded.`),this.#invalidateRender(`Preview renderer reloaded.`),this.#measuredRenderDigest=void 0,this.#markerInventory.clear(),this.#post({channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:{reason:e},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/reload`}),this.announce()}teardown(e){this.#assertActive(),this.#post({channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:{reason:e},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/teardown`}),this.dispose()}#assertActive(){if(this.#disposed)throw Error(`Preview host was disposed.`)}#handleMeasure(t){let n=t.requestId;if(this.#usedRequestIds.has(n)){this.#postError(n,{code:`studio.preview/request-id-reused`,defaultMessage:`The preview request identifier was already used in this session.`,retryable:!1});return}if(this.#usedRequestIds.add(n),this.#measuredRenderDigest===void 0){this.#postError(n,{code:`studio.preview/measure-unavailable`,defaultMessage:`Preview measurement is unavailable.`,retryable:!0});return}let r=this.#measuredRenderDigest;if(t.markers.some(t=>!this.#markerInventory.has(t)||!e(t,r))){this.#postError(n,{code:`studio.preview/measure-stale-marker`,defaultMessage:`Preview measurement markers are not in the current render inventory.`,retryable:!0});return}if(this.#measureCallback===void 0){this.#postError(n,{code:`studio.preview/measure-unavailable`,defaultMessage:`Preview measurement is unavailable.`,retryable:!1});return}this.#invalidateMeasure(`Preview measurement was superseded.`);let i={controller:new AbortController,draftDigest:r,generation:this.#measureGeneration,requestId:n};this.#activeMeasure=i;let a=[...t.markers],o;try{o=this.#measureCallback(a,i.controller.signal)}catch{this.#settleMeasureFailure(i,s());return}Promise.resolve(o).then(e=>{try{this.#settleMeasured(i,a,e)}catch{this.#settleMeasureFailure(i,s())}},()=>{this.#settleMeasureFailure(i,s())})}#handleRender(e){if(this.#usedRequestIds.has(e.requestId)){this.#postError(e.requestId,{code:`studio.preview/request-id-reused`,defaultMessage:`The preview request identifier was already used in this session.`,retryable:!1});return}this.#usedRequestIds.add(e.requestId),this.#invalidateMeasure(`Preview measurement was superseded by a render.`),this.#invalidateRender(`Preview render was superseded.`),this.#measuredRenderDigest=void 0,this.#markerInventory.clear();let t={controller:new AbortController,draftDigest:e.draftDigest,generation:this.#renderGeneration,requestId:e.requestId};this.#activeRender=t;let n;try{n=this.#renderCallback(e,t.controller.signal)}catch{this.#settleFailure(t);return}Promise.resolve(n).then(e=>{try{this.#settleRendered(t,e)}catch{this.#settleFailure(t)}},()=>{this.#settleFailure(t)})}#post(e){if(!t(e))throw TypeError(`Refused an invalid outbound preview message.`);this.#sequence+=1,this.#target.postMessage(e,this.#targetOrigin)}#receive(e){if(!(e.origin!==this.#targetOrigin||e.source!==this.#target||!t(e.data)||e.data.channelId!==this.#channelId||e.data.sessionGeneration!==this.#sessionGeneration||e.data.sequence<=this.#lastInboundSequence)){if(this.#lastInboundSequence=e.data.sequence,e.data.type===`studio.preview/render`)this.#handleRender(e.data.payload);else if(e.data.type===`studio.preview/measure`)this.#handleMeasure(e.data.payload);else if(e.data.type===`studio.preview/select`)for(let t of this.#selectListeners)t(e.data.payload);else if(e.data.type===`studio.preview/viewport`){this.#invalidateMeasure(`Preview viewport changed.`);for(let t of this.#viewportListeners)t(e.data.payload)}else if(e.data.type===`studio.preview/dispose`){(e.data.payload.draftDigest===void 0||e.data.payload.draftDigest===this.#activeRender?.draftDigest)&&this.#invalidateRender(`Preview render was disposed.`),(e.data.payload.draftDigest===void 0||e.data.payload.draftDigest===this.#measuredRenderDigest)&&(this.#invalidateMeasure(`Preview measurement was disposed.`),this.#measuredRenderDigest=void 0,this.#markerInventory.clear());for(let t of this.#disposeListeners)t(e.data.payload)}else e.data.type===`studio.preview/teardown`&&this.dispose()}}#settleMeasureFailure(e,t){this.#isActiveMeasure(e)&&(this.#activeMeasure=void 0,this.#postError(e.requestId,t))}#postError(e,t){this.#disposed||this.#post({channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:{code:t.code,correlationId:e,message:{defaultMessage:t.defaultMessage,key:t.code},retryable:t.retryable},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/error`})}#settleMeasured(e,n,i){if(!this.#isActiveMeasure(e))return;let a={},o=[];for(let e of n){let t=Object.hasOwn(i.rects,e)?i.rects[e]:void 0;t===void 0||t.length===0?o.push(e):a[e]=t.map(e=>({height:e.height,width:e.width,x:e.x,y:e.y}))}let c={channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:{draftDigest:e.draftDigest,measurements:a,requestId:e.requestId,unknown:o,viewport:{devicePixelRatio:i.viewport.devicePixelRatio,height:i.viewport.height,scrollX:i.viewport.scrollX,scrollY:i.viewport.scrollY,width:i.viewport.width}},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/measurements`};if(!t(c)){this.#settleMeasureFailure(e,s());return}this.#activeMeasure=void 0,this.#post(c)}#settleFailure(e){this.#isActiveRender(e)&&(this.#activeRender=void 0,this.#postError(e.requestId,{code:`studio.preview/render-failed`,defaultMessage:`Preview rendering failed.`,retryable:!0}))}#settleRendered(e,t){if(this.#isActiveRender(e)){if(!n(t)||t.draftDigest!==e.draftDigest||t.requestId!==e.requestId){this.#settleFailure(e);return}this.#activeRender=void 0,this.#measuredRenderDigest=e.draftDigest,this.#markerInventory.clear();for(let e of t.markers)this.#markerInventory.add(e);this.#post({channelId:this.#channelId,contractVersion:r,kind:`preview-message`,payload:{diagnostics:t.diagnostics,draftDigest:e.draftDigest,markers:t.markers,markerMap:t.markerMap,requestId:e.requestId},sequence:this.#sequence,sessionGeneration:this.#sessionGeneration,type:`studio.preview/rendered`})}}#invalidateMeasure(e){this.#measureGeneration+=1,this.#activeMeasure?.controller.abort(e),this.#activeMeasure=void 0}#invalidateRender(e){this.#renderGeneration+=1,this.#activeRender?.controller.abort(e),this.#activeRender=void 0}#isActiveMeasure(e){return!this.#disposed&&this.#activeMeasure===e&&e.generation===this.#measureGeneration&&e.draftDigest===this.#measuredRenderDigest}#isActiveRender(e){return!this.#disposed&&this.#activeRender===e&&e.generation===this.#renderGeneration}}function s(){return{code:`studio.preview/measure-failed`,defaultMessage:`Preview measurement failed.`,retryable:!0}}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type CanonicalSerializationOptions } from '@kumwe/studio-core';
|
|
2
|
+
import type { BlueprintDocument, NodeId, StableId, StudioArtifact } from '@kumwe/studio-protocol';
|
|
3
|
+
export interface PreviewDigestOptions extends CanonicalSerializationOptions {
|
|
4
|
+
/** Web Crypto implementation used to hash the canonical bytes. */
|
|
5
|
+
subtle?: Pick<SubtleCrypto, 'digest'>;
|
|
6
|
+
}
|
|
7
|
+
export interface PreviewMarkerInventory {
|
|
8
|
+
markerMap: Record<StableId, NodeId>;
|
|
9
|
+
markers: StableId[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Return the exact digest preimage for a complete, schema-valid Studio draft.
|
|
13
|
+
* No transport envelope, prefix, BOM, viewport, revision override, or trailing
|
|
14
|
+
* newline is added: the preimage is only the canonical UTF-8 artifact bytes.
|
|
15
|
+
* The authoritative host MUST schema- and semantics-validate the artifact
|
|
16
|
+
* before treating this helper's result as a valid draft identity.
|
|
17
|
+
*/
|
|
18
|
+
export declare function canonicalPreviewDraftBytes(draft: StudioArtifact, options?: Readonly<CanonicalSerializationOptions>): Uint8Array;
|
|
19
|
+
/** Compute the lowercase SHA-256 hex identity of a complete Studio draft. */
|
|
20
|
+
export declare function computePreviewDraftDigest(draft: StudioArtifact, options?: Readonly<PreviewDigestOptions>): Promise<string>;
|
|
21
|
+
/** Create the canonical marker for one zero-based Blueprint preorder ordinal. */
|
|
22
|
+
export declare function createPreviewMarker(draftDigest: string, ordinal: number): StableId;
|
|
23
|
+
/**
|
|
24
|
+
* Build the portable marker inventory for a Blueprint. Traversal is roots in
|
|
25
|
+
* array order, each node before descendants, slot names in ascending UTF-16
|
|
26
|
+
* code-unit order, and children in array order. Node ids must be unique.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createPreviewMarkerInventory(draft: BlueprintDocument, draftDigest: string): PreviewMarkerInventory;
|
|
29
|
+
//# sourceMappingURL=preview-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-identity.d.ts","sourceRoot":"","sources":["../src/preview-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,KAAK,EACV,iBAAiB,EAGjB,MAAM,EACN,QAAQ,EACR,cAAc,EACf,MAAM,wBAAwB,CAAC;AAKhC,MAAM,WAAW,oBAAqB,SAAQ,6BAA6B;IACzE,kEAAkE;IAClE,MAAM,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,QAAQ,CAAC,6BAA6B,CAAM,GACpD,UAAU,CAEZ;AAED,6EAA6E;AAC7E,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,QAAQ,CAAC,oBAAoB,CAAM,GAC3C,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,CAQlF;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,MAAM,GAClB,sBAAsB,CA4BxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{canonicalUtf8Bytes as e}from"@kumwe/studio-core";const t=/^[0-9a-f]{64}$/u,n=99999;export function canonicalPreviewDraftBytes(t,n={}){return e(t,n)}export async function computePreviewDraftDigest(e,t={}){let n=t.subtle??globalThis.crypto.subtle,i=t.maximumDepth===void 0?{}:{maximumDepth:t.maximumDepth},a=Uint8Array.from(canonicalPreviewDraftBytes(e,i)),o=await n.digest(`SHA-256`,a);return[...new Uint8Array(o)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}export function createPreviewMarker(e,r){if(!t.test(e))throw TypeError(`Preview draft digest must be 64 lowercase hexadecimal characters.`);if(!Number.isSafeInteger(r)||r<0||r>n)throw RangeError(`Preview marker ordinal must be between 0 and ${n}.`);return`studio.preview/node/${e}/${r}`}export function createPreviewMarkerInventory(e,t){let n={},r=[],i=new Set,o=e=>{if(i.has(e.id))throw TypeError(`Preview marker inventory cannot contain duplicate node id ${e.id}.`);i.add(e.id);let s=createPreviewMarker(t,r.length);r.push(s),n[s]=e.id;let c=Object.entries(e.slots).sort(([e],[t])=>e<t?-1:+(e>t));for(let[,e]of c)for(let t of e)o(t)};for(let t of e.roots)o(t);return{markerMap:n,markers:r}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kumwe/studio-preview",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-beta.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/kumwe/studio.git",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"files": [
|
|
15
15
|
"LICENSE",
|
|
16
|
+
"THIRD_PARTY_NOTICES.md",
|
|
17
|
+
"third-party-licenses",
|
|
16
18
|
"dist",
|
|
17
19
|
"README.md"
|
|
18
20
|
],
|
|
@@ -23,10 +25,11 @@
|
|
|
23
25
|
}
|
|
24
26
|
},
|
|
25
27
|
"scripts": {
|
|
26
|
-
"build": "tsc -b"
|
|
28
|
+
"build": "tsc -b && node ../../scripts/minify-package-dist.mjs --package packages/preview"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
|
-
"@kumwe/studio-
|
|
31
|
+
"@kumwe/studio-core": "0.1.0-beta.2",
|
|
32
|
+
"@kumwe/studio-protocol": "0.1.0-beta.2"
|
|
30
33
|
},
|
|
31
34
|
"publishConfig": {
|
|
32
35
|
"access": "public",
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,GAWd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,WAAW,GAMZ,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"preview-client.js","sourceRoot":"","sources":["../src/preview-client.ts"],"names":[],"mappings":"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"}
|
package/dist/preview-host.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"preview-host.js","sourceRoot":"","sources":["../src/preview-host.ts"],"names":[],"mappings":"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"}
|