@snowcone-app/sdk 0.1.15 → 0.2.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/CHANGELOG.md +13 -0
- package/README.md +47 -12
- package/dist/{chunk-RPA3B6I3.js → chunk-D5ZRGKA5.js} +26 -0
- package/dist/index.cjs +72 -0
- package/dist/index.d.cts +71 -5
- package/dist/index.d.ts +71 -5
- package/dist/index.js +46 -1
- package/dist/react.cjs +26 -0
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{websocket-BQH1HYJp.d.cts → websocket-Poy8LZNA.d.cts} +7 -0
- package/dist/{websocket-BQH1HYJp.d.ts → websocket-Poy8LZNA.d.ts} +7 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#220](https://github.com/snowcone-app/snowcone-monorepo/pull/220) [`aa318b5`](https://github.com/snowcone-app/snowcone-monorepo/commit/aa318b51a15e977ecb993c81ae30b6afcf6864b8) Thanks [@kevinsproles](https://github.com/kevinsproles)! - Add realtime saved-design-state API: `createDesignState` (top-level export for building a design state payload) and `RenderSession.renderSavedState(placement, stateId)` (render a previously-saved design state in a realtime session). These were already in `main` and documented on developers.snowcone.app but were missing from the published `@snowcone-app/sdk@0.1.15`, so docs examples failed to compile against the npm package.
|
|
8
|
+
|
|
3
9
|
All notable changes to the Merch SDK will be documented in this file.
|
|
4
10
|
|
|
5
11
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
@@ -8,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
14
|
## [0.1.9] - 2025-10-16
|
|
9
15
|
|
|
10
16
|
### Added
|
|
17
|
+
|
|
11
18
|
- **DOM-Based URL Resolution** - Intelligent URL resolution for transformed assets
|
|
12
19
|
- Added `resolveUrlFromDOM()` to find actual rendered URLs in the DOM
|
|
13
20
|
- Automatically resolves Vercel Blob Storage URLs from v0.dev
|
|
@@ -15,18 +22,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
22
|
- Perfect for environments where image URLs are transformed at runtime
|
|
16
23
|
|
|
17
24
|
### Changed
|
|
25
|
+
|
|
18
26
|
- **Enhanced URL Normalization** - Multi-tier resolution strategy
|
|
19
27
|
1. First attempts to find actual URL in DOM (for v0/Blob Storage)
|
|
20
28
|
2. Falls back to `window.location.origin` conversion
|
|
21
29
|
3. Warns about localhost URLs for better developer experience
|
|
22
30
|
|
|
23
31
|
### Fixed
|
|
32
|
+
|
|
24
33
|
- Relative URLs now work correctly in v0.dev and Vercel Blob Storage environments
|
|
25
34
|
- Mockup generation can access transformed image URLs with hash suffixes
|
|
26
35
|
|
|
27
36
|
## [0.1.8] - 2025-10-16
|
|
28
37
|
|
|
29
38
|
### Added
|
|
39
|
+
|
|
30
40
|
- **Automatic URL Normalization** - Relative artwork URLs are now automatically converted to absolute URLs
|
|
31
41
|
- Added `normalizeImageUrl()` utility function in `utils/url.ts`
|
|
32
42
|
- Supports `/images/art.jpg`, `./art.jpg`, `../art.jpg` patterns
|
|
@@ -34,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
34
44
|
- SSR-safe with helpful warnings
|
|
35
45
|
|
|
36
46
|
### Changed
|
|
47
|
+
|
|
37
48
|
- **Design Generation** - All artwork URLs are normalized in `createDesignForPlacements()`
|
|
38
49
|
- Handles placement designs, provided images, and default URLs
|
|
39
50
|
- Single source of truth for URL normalization
|
|
@@ -42,12 +53,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
53
|
- Clear error messages for invalid formats
|
|
43
54
|
|
|
44
55
|
### Fixed
|
|
56
|
+
|
|
45
57
|
- Artwork URLs no longer require absolute paths - relative paths work seamlessly
|
|
46
58
|
- Better developer experience matching Next.js image patterns
|
|
47
59
|
|
|
48
60
|
## [0.1.7] - 2025-10-16
|
|
49
61
|
|
|
50
62
|
### Changed
|
|
63
|
+
|
|
51
64
|
- Version bump to maintain parity with @snowcone-app/ui 0.1.11
|
|
52
65
|
- No functional changes in this release
|
|
53
66
|
|
package/README.md
CHANGED
|
@@ -167,25 +167,60 @@ const url = getMockupUrl('hoodie-black', {
|
|
|
167
167
|
|
|
168
168
|
See [Public or signed](https://developers.snowcone.app/get-started) for the full picture.
|
|
169
169
|
|
|
170
|
-
###
|
|
170
|
+
### Realtime: render a saved canvas, no pixel upload
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
`getMockupUrl` composites **one** artwork onto a product. For a full multi-layer
|
|
173
|
+
design — the kind the Snowcone canvas editor produces — use a **`RenderSession`**:
|
|
174
|
+
the browser sends a ~1 KB description of the canvas (or just a saved design's id)
|
|
175
|
+
over a WebSocket, and the server rasterizes it and **fetches the referenced assets
|
|
176
|
+
itself**. No per-placement PNG is ever uploaded, so it's fast on thin/mobile
|
|
177
|
+
clients. This is exactly how the Snowcone PDP renders mockups (see ADR-0079).
|
|
178
|
+
|
|
179
|
+
Authorize the session with a short-lived **grant**. Mint it server-side with a
|
|
180
|
+
secret API key (`sk_…`, scope `mockups:realtime`) so the key never reaches the
|
|
181
|
+
browser. Create the key — and find your publishable `shop.id` — on the
|
|
182
|
+
[API keys page](https://snowcone.app/api-keys):
|
|
173
183
|
|
|
174
184
|
```typescript
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
185
|
+
// YOUR backend route, e.g. POST /api/realtime/grant
|
|
186
|
+
import { mintRealtimeGrant } from '@snowcone-app/sdk';
|
|
187
|
+
|
|
188
|
+
export async function POST(req: Request) {
|
|
189
|
+
const { shop } = await req.json();
|
|
190
|
+
const grant = await mintRealtimeGrant({
|
|
191
|
+
apiKey: process.env.SNOWCONE_API_KEY!, // secret — server only
|
|
192
|
+
shop, // = shop.id (publishable)
|
|
183
193
|
});
|
|
184
|
-
|
|
185
|
-
return <img src={mockupUrl} alt="Product mockup" />;
|
|
194
|
+
return Response.json(grant); // { token, expiresAt }
|
|
186
195
|
}
|
|
187
196
|
```
|
|
188
197
|
|
|
198
|
+
In the browser, point a `RenderSession` at that proxy and render. Render a **saved**
|
|
199
|
+
design by id (no canvas JSON needed) or a live `serializeStateForServer(...)` state:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { RenderSession } from '@snowcone-app/sdk';
|
|
203
|
+
|
|
204
|
+
const session = new RenderSession({
|
|
205
|
+
shop: 'YOUR_SHOP_ID', // publishable, like Stripe pk_
|
|
206
|
+
grantUrl: '/api/realtime/grant', // your proxy above
|
|
207
|
+
product: { productId: 'BEEB77', mockupIds: ['Front'] },
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
session.onMockups((results) => { img.src = results[0].imageUrl; });
|
|
211
|
+
|
|
212
|
+
// (a) render a SAVED canvas by id — ideal for fulfillment / agents
|
|
213
|
+
await session.renderSavedState('Front', 'design-state-id');
|
|
214
|
+
|
|
215
|
+
// (b) or render a live canvas state from @snowcone-app/canvas
|
|
216
|
+
// import { serializeStateForServer } from '@snowcone-app/canvas';
|
|
217
|
+
// await session.renderState('Front', serializeStateForServer(canvasState));
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
React apps can use the lower-level `useRealtimeMockup({ getToken })` hook from
|
|
221
|
+
`@snowcone-app/sdk/react` instead. Full walkthrough:
|
|
222
|
+
[Realtime server-side render](https://developers.snowcone.app/realtime).
|
|
223
|
+
|
|
189
224
|
## TypeScript Support
|
|
190
225
|
|
|
191
226
|
Full TypeScript definitions are included. Import types:
|
|
@@ -472,6 +472,32 @@ var RealtimeMockupService = class {
|
|
|
472
472
|
}
|
|
473
473
|
return true;
|
|
474
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). Sends a `stateId`
|
|
477
|
+
* instead of inline state; the server resolves it, fetches the referenced
|
|
478
|
+
* assets, and renders — nothing is uploaded and the client need not hold the
|
|
479
|
+
* canvas JSON. One-shot (no throttle). Results arrive like any other render.
|
|
480
|
+
*/
|
|
481
|
+
sendCanvasStateRef(placement, stateId) {
|
|
482
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN || !this.isConfigured) {
|
|
483
|
+
const reason = !this.ws ? "no WebSocket" : this.ws.readyState !== WebSocket.OPEN ? `ws.readyState=${this.ws.readyState}` : "not configured";
|
|
484
|
+
console.log(`[WS] sendCanvasStateRef BLOCKED for "${placement}": ${reason}`);
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
this.lastSentVersion = ++this.requestVersion;
|
|
488
|
+
this.latestSentVersionByPlacement[placement] = this.lastSentVersion;
|
|
489
|
+
const message = JSON.stringify({
|
|
490
|
+
type: "canvas_state",
|
|
491
|
+
placement,
|
|
492
|
+
version: this.lastSentVersion,
|
|
493
|
+
stateId
|
|
494
|
+
});
|
|
495
|
+
this.ws.send(message);
|
|
496
|
+
this.lastBlobSentAt = Date.now();
|
|
497
|
+
this.addLog(`Sent canvas stateId "${stateId}" for "${placement}" (v${this.lastSentVersion})`, "sent");
|
|
498
|
+
this.callbacks.onBlobSent?.(placement);
|
|
499
|
+
return true;
|
|
500
|
+
}
|
|
475
501
|
sendCanvasStateImmediately(placement, state) {
|
|
476
502
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
477
503
|
console.log(`[WS] sendCanvasStateImmediately ABORTED: ws not open`);
|
package/dist/index.cjs
CHANGED
|
@@ -76,6 +76,7 @@ __export(index_exports, {
|
|
|
76
76
|
createComponent: () => createComponent,
|
|
77
77
|
createContextProvider: () => createContextProvider,
|
|
78
78
|
createDesignForPlacements: () => createDesignForPlacements,
|
|
79
|
+
createDesignState: () => createDesignState,
|
|
79
80
|
createDevFetcher: () => createDevFetcher,
|
|
80
81
|
createErrorHandler: () => createErrorHandler,
|
|
81
82
|
createEventManager: () => createEventManager,
|
|
@@ -5276,6 +5277,32 @@ var RealtimeMockupService = class {
|
|
|
5276
5277
|
}
|
|
5277
5278
|
return true;
|
|
5278
5279
|
}
|
|
5280
|
+
/**
|
|
5281
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). Sends a `stateId`
|
|
5282
|
+
* instead of inline state; the server resolves it, fetches the referenced
|
|
5283
|
+
* assets, and renders — nothing is uploaded and the client need not hold the
|
|
5284
|
+
* canvas JSON. One-shot (no throttle). Results arrive like any other render.
|
|
5285
|
+
*/
|
|
5286
|
+
sendCanvasStateRef(placement, stateId) {
|
|
5287
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN || !this.isConfigured) {
|
|
5288
|
+
const reason = !this.ws ? "no WebSocket" : this.ws.readyState !== WebSocket.OPEN ? `ws.readyState=${this.ws.readyState}` : "not configured";
|
|
5289
|
+
console.log(`[WS] sendCanvasStateRef BLOCKED for "${placement}": ${reason}`);
|
|
5290
|
+
return false;
|
|
5291
|
+
}
|
|
5292
|
+
this.lastSentVersion = ++this.requestVersion;
|
|
5293
|
+
this.latestSentVersionByPlacement[placement] = this.lastSentVersion;
|
|
5294
|
+
const message = JSON.stringify({
|
|
5295
|
+
type: "canvas_state",
|
|
5296
|
+
placement,
|
|
5297
|
+
version: this.lastSentVersion,
|
|
5298
|
+
stateId
|
|
5299
|
+
});
|
|
5300
|
+
this.ws.send(message);
|
|
5301
|
+
this.lastBlobSentAt = Date.now();
|
|
5302
|
+
this.addLog(`Sent canvas stateId "${stateId}" for "${placement}" (v${this.lastSentVersion})`, "sent");
|
|
5303
|
+
this.callbacks.onBlobSent?.(placement);
|
|
5304
|
+
return true;
|
|
5305
|
+
}
|
|
5279
5306
|
sendCanvasStateImmediately(placement, state) {
|
|
5280
5307
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
5281
5308
|
console.log(`[WS] sendCanvasStateImmediately ABORTED: ws not open`);
|
|
@@ -5566,11 +5593,32 @@ var RenderSession = class {
|
|
|
5566
5593
|
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
5567
5594
|
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
5568
5595
|
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
5596
|
+
*
|
|
5597
|
+
* `placement` is the print-area NAME (e.g. `'Front'`, the product's
|
|
5598
|
+
* `placements[].label`) — a different id from the product's `mockupIds`, and it
|
|
5599
|
+
* must match an artboard in `state`. The server renders only once it has a state
|
|
5600
|
+
* for EVERY required placement, so on a multi-placement product call this once
|
|
5601
|
+
* per placement; a missing one surfaces as an `incomplete_canvas_placements`
|
|
5602
|
+
* error on {@link RenderSession.onError}.
|
|
5603
|
+
*
|
|
5604
|
+
* `state` is the flattened `serializeStateForServer()` shape — NOT the
|
|
5605
|
+
* un-flattened shape `createDesignState` takes.
|
|
5569
5606
|
*/
|
|
5570
5607
|
async renderState(placement, state, throttleMs = 0) {
|
|
5571
5608
|
await this.connect();
|
|
5572
5609
|
this.svc.sendCanvasState(placement, state, this.product?.mockupIds.length ?? 1, throttleMs);
|
|
5573
5610
|
}
|
|
5611
|
+
/**
|
|
5612
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). The server resolves
|
|
5613
|
+
* the `stateId`, fetches the referenced assets, and renders — no pixels are
|
|
5614
|
+
* uploaded and you don't need to hold the canvas JSON. Ideal for re-rendering
|
|
5615
|
+
* a stored design (fulfillment, agents, server-to-server). Results arrive via
|
|
5616
|
+
* {@link RenderSession.onMockups}.
|
|
5617
|
+
*/
|
|
5618
|
+
async renderSavedState(placement, stateId) {
|
|
5619
|
+
await this.connect();
|
|
5620
|
+
this.svc.sendCanvasStateRef(placement, stateId);
|
|
5621
|
+
}
|
|
5574
5622
|
/** Update only the mockup ids to render (reuses the current state). */
|
|
5575
5623
|
updateMockupIds(mockupIds) {
|
|
5576
5624
|
if (this.product) this.product = { ...this.product, mockupIds };
|
|
@@ -5603,6 +5651,29 @@ var RenderSession = class {
|
|
|
5603
5651
|
}
|
|
5604
5652
|
};
|
|
5605
5653
|
|
|
5654
|
+
// src/realtime/design-state.ts
|
|
5655
|
+
var TRANSPARENT_1X1_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==";
|
|
5656
|
+
async function createDesignState(input) {
|
|
5657
|
+
const f = input.fetch ?? globalThis.fetch;
|
|
5658
|
+
const res = await f(`${input.base ?? DEFAULT_GRANT_BASE}/snowcone/design-states`, {
|
|
5659
|
+
method: "POST",
|
|
5660
|
+
headers: { "Content-Type": "application/json" },
|
|
5661
|
+
body: JSON.stringify({
|
|
5662
|
+
productId: input.productId,
|
|
5663
|
+
stateJson: JSON.stringify(input.state),
|
|
5664
|
+
previewBase64: input.previewBase64 ?? TRANSPARENT_1X1_PNG
|
|
5665
|
+
})
|
|
5666
|
+
});
|
|
5667
|
+
if (!res.ok) {
|
|
5668
|
+
const detail = await res.text().catch(() => "");
|
|
5669
|
+
throw new Error(`createDesignState failed: ${res.status}${detail ? ` ${detail}` : ""}`);
|
|
5670
|
+
}
|
|
5671
|
+
const body = await res.json();
|
|
5672
|
+
const ds = body?.designState;
|
|
5673
|
+
if (!ds?.id) throw new Error("createDesignState: response missing designState.id");
|
|
5674
|
+
return { stateId: ds.id, stateUrl: ds.stateUrl ?? "", previewUrl: ds.previewUrl ?? "" };
|
|
5675
|
+
}
|
|
5676
|
+
|
|
5606
5677
|
// src/index.ts
|
|
5607
5678
|
function getFetcher(config) {
|
|
5608
5679
|
return config?.fetcher || globalThis.fetch.bind(globalThis);
|
|
@@ -5728,6 +5799,7 @@ function createClient(config) {
|
|
|
5728
5799
|
createComponent,
|
|
5729
5800
|
createContextProvider,
|
|
5730
5801
|
createDesignForPlacements,
|
|
5802
|
+
createDesignState,
|
|
5731
5803
|
createDevFetcher,
|
|
5732
5804
|
createErrorHandler,
|
|
5733
5805
|
createEventManager,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { createDevFetcher } from './dev-fetcher.cjs';
|
|
2
2
|
import { PublicDesign, PublicFill, PublicOptions } from '@snowcone-app/mockup-url';
|
|
3
|
-
import { O as OptionAttribute, a as OptionSelection, C as Combination, F as FrameworkAdapter, b as ComponentProps, c as ComponentDescriptor, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, g as FrameworkUtilities, P as PlacementSettings, M as MockupResult, R as RealtimeMockupService } from './websocket-
|
|
4
|
-
export { A as AdapterRegistry, h as ProductComponentContext, i as RealtimeMockupCallbacks, j as RealtimeMockupState, k as RenderResult, W as WebSocketConfig, l as WebSocketMessage, m as adapterRegistry, n as computeDisabledChoices, o as createComponent, p as defineComponent, q as deriveDefaultSelection, r as findBestCombination, s as getPricePreview, t as isOptionAvailable, u as resolveBestCombination } from './websocket-
|
|
3
|
+
import { O as OptionAttribute, a as OptionSelection, C as Combination, F as FrameworkAdapter, b as ComponentProps, c as ComponentDescriptor, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, g as FrameworkUtilities, P as PlacementSettings, M as MockupResult, R as RealtimeMockupService } from './websocket-Poy8LZNA.cjs';
|
|
4
|
+
export { A as AdapterRegistry, h as ProductComponentContext, i as RealtimeMockupCallbacks, j as RealtimeMockupState, k as RenderResult, W as WebSocketConfig, l as WebSocketMessage, m as adapterRegistry, n as computeDisabledChoices, o as createComponent, p as defineComponent, q as deriveDefaultSelection, r as findBestCombination, s as getPricePreview, t as isOptionAvailable, u as resolveBestCombination } from './websocket-Poy8LZNA.cjs';
|
|
5
5
|
|
|
6
6
|
interface CatalogProduct$2 {
|
|
7
7
|
id: string;
|
|
@@ -16,7 +16,6 @@ interface CatalogProduct$2 {
|
|
|
16
16
|
highestPrice?: number;
|
|
17
17
|
mockups?: {
|
|
18
18
|
id: string;
|
|
19
|
-
ar: number;
|
|
20
19
|
gvids: string[];
|
|
21
20
|
}[];
|
|
22
21
|
options?: {
|
|
@@ -2581,8 +2580,18 @@ interface RenderState {
|
|
|
2581
2580
|
/** Product the session renders against (Snowcone catalog ids). */
|
|
2582
2581
|
interface RenderProduct {
|
|
2583
2582
|
productId: string;
|
|
2583
|
+
/**
|
|
2584
|
+
* The mockup scenes to render — opaque catalog codes (the product's
|
|
2585
|
+
* `mockups[].id`, e.g. `'FV1qjO'`). These are a DIFFERENT namespace from the
|
|
2586
|
+
* `placement` you pass to {@link RenderSession.renderState} (a print-area name
|
|
2587
|
+
* like `'Front'`). Don't pass a placement name here.
|
|
2588
|
+
*/
|
|
2584
2589
|
mockupIds: string[];
|
|
2585
|
-
/**
|
|
2590
|
+
/**
|
|
2591
|
+
* Optional variant (gvid). Omit if the product has no variant axis. Required
|
|
2592
|
+
* for products with a color option — it auto-fills the color placement; without
|
|
2593
|
+
* it the render waits for a color blob that never comes.
|
|
2594
|
+
*/
|
|
2586
2595
|
variantId?: string;
|
|
2587
2596
|
/** Render width in px (default 1000). */
|
|
2588
2597
|
width?: number;
|
|
@@ -2631,8 +2640,26 @@ declare class RenderSession {
|
|
|
2631
2640
|
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
2632
2641
|
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
2633
2642
|
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
2643
|
+
*
|
|
2644
|
+
* `placement` is the print-area NAME (e.g. `'Front'`, the product's
|
|
2645
|
+
* `placements[].label`) — a different id from the product's `mockupIds`, and it
|
|
2646
|
+
* must match an artboard in `state`. The server renders only once it has a state
|
|
2647
|
+
* for EVERY required placement, so on a multi-placement product call this once
|
|
2648
|
+
* per placement; a missing one surfaces as an `incomplete_canvas_placements`
|
|
2649
|
+
* error on {@link RenderSession.onError}.
|
|
2650
|
+
*
|
|
2651
|
+
* `state` is the flattened `serializeStateForServer()` shape — NOT the
|
|
2652
|
+
* un-flattened shape `createDesignState` takes.
|
|
2634
2653
|
*/
|
|
2635
2654
|
renderState(placement: string, state: RenderState, throttleMs?: number): Promise<void>;
|
|
2655
|
+
/**
|
|
2656
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). The server resolves
|
|
2657
|
+
* the `stateId`, fetches the referenced assets, and renders — no pixels are
|
|
2658
|
+
* uploaded and you don't need to hold the canvas JSON. Ideal for re-rendering
|
|
2659
|
+
* a stored design (fulfillment, agents, server-to-server). Results arrive via
|
|
2660
|
+
* {@link RenderSession.onMockups}.
|
|
2661
|
+
*/
|
|
2662
|
+
renderSavedState(placement: string, stateId: string): Promise<void>;
|
|
2636
2663
|
/** Update only the mockup ids to render (reuses the current state). */
|
|
2637
2664
|
updateMockupIds(mockupIds: string[]): void;
|
|
2638
2665
|
/** Current rendered results. */
|
|
@@ -2644,6 +2671,45 @@ declare class RenderSession {
|
|
|
2644
2671
|
private toConfig;
|
|
2645
2672
|
}
|
|
2646
2673
|
|
|
2674
|
+
interface CreateDesignStateInput {
|
|
2675
|
+
/** Catalog product code the design targets. */
|
|
2676
|
+
productId: string;
|
|
2677
|
+
/**
|
|
2678
|
+
* The canvas state to persist — the **raw, un-flattened** stored shape:
|
|
2679
|
+
* top-level `elements` with `transformType` + nested `transformData`, plus
|
|
2680
|
+
* bare `artboards` metadata. The server flattens this at render time
|
|
2681
|
+
* (`normalizeCanvasState`).
|
|
2682
|
+
*
|
|
2683
|
+
* ⚠️ This is NOT the `serializeStateForServer()` output you pass to
|
|
2684
|
+
* `RenderSession.renderState` — that shape is already flattened and will
|
|
2685
|
+
* mis-render if stored here. Persist the raw canvas state (e.g. `toJSON()`
|
|
2686
|
+
* from the editor), not the server-render payload.
|
|
2687
|
+
*/
|
|
2688
|
+
state: RenderState | Record<string, unknown>;
|
|
2689
|
+
/**
|
|
2690
|
+
* Preview thumbnail as a base64 PNG/JPEG (no data: prefix). Optional —
|
|
2691
|
+
* defaults to a 1×1 transparent PNG, which is fine for render-only use.
|
|
2692
|
+
*/
|
|
2693
|
+
previewBase64?: string;
|
|
2694
|
+
/** Backend base URL. Defaults to {@link DEFAULT_GRANT_BASE}. */
|
|
2695
|
+
base?: string;
|
|
2696
|
+
/** Override fetch (tests / non-global-fetch runtimes). */
|
|
2697
|
+
fetch?: typeof fetch;
|
|
2698
|
+
}
|
|
2699
|
+
interface CreatedDesignState {
|
|
2700
|
+
/** The id to pass to `renderSavedState(placement, stateId)`. */
|
|
2701
|
+
stateId: string;
|
|
2702
|
+
/** Content-addressed URL of the persisted state JSON. */
|
|
2703
|
+
stateUrl: string;
|
|
2704
|
+
/** Content-addressed URL of the preview image. */
|
|
2705
|
+
previewUrl: string;
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Persist a canvas state and return its `stateId` (+ URLs). Pair with
|
|
2709
|
+
* `RenderSession.renderSavedState(placement, stateId)`.
|
|
2710
|
+
*/
|
|
2711
|
+
declare function createDesignState(input: CreateDesignStateInput): Promise<CreatedDesignState>;
|
|
2712
|
+
|
|
2647
2713
|
interface ProductPlacement {
|
|
2648
2714
|
label: string;
|
|
2649
2715
|
x: number;
|
|
@@ -2698,4 +2764,4 @@ declare function getProduct(idOrSlug: string, config?: Partial<SdkConfig>): Prom
|
|
|
2698
2764
|
*/
|
|
2699
2765
|
declare function createClient(config: SdkConfig): SnowconeClient;
|
|
2700
2766
|
|
|
2701
|
-
export { AbstractTemplateRenderer, type AddToCartOptions, Animations, type ArtSelectorContext, type ArtSelectorDescriptor, type ArtSelectorOptions, type ArtworkData, type AspectRatio, Attributes, type BaseDescriptor, type BlendConfig, type BuildMockupUrlConfig, type CartDetail, type CatalogListResponse, type CatalogProduct$2 as CatalogProduct, ClassNames, type ColorDesignElement, ColorPickerUtils, Combination, CommonProps, ComponentContext, type ComponentDefinition, ComponentDescriptor, ComponentEventManager, ComponentFactory, ComponentLifecycle, ComponentLifecycleHooks, type ComponentMetadata, ComponentProps, ComponentRegistry, ComponentState, type ComponentTemplate, ComponentTemplates, type ContainerDescriptor, ContextBridge, type ContextComparator, type ContextConsumer, ContextInjector, type ContextProviderConfig, type ContextSubscriber, ContextSynchronizer, DEFAULT_ARTWORK_URL, DEFAULT_ASPECT_RATIO, DEFAULT_COLOR, DEFAULT_GRANT_BASE, DEFAULT_MOCKUP_BASE, DEFAULT_PLACEMENT_DIMENSIONS, type Descriptor, type Design, type DesignElement, type DesignGenerationContext, type Effects, Elements, type ErrorContext, type ErrorHandler, ErrorManager, type EventDefinition, EventDelegator, EventEmitter, EventHandler, type EventListener, type EventPayload, type Fill, Focus, FrameworkAdapter, FrameworkUtilities, type GetMockupUrlOptions, type ImageAlignment, type ImageDesignElement, type LifecycleHook, LifecycleManager, type LifecyclePhase, type LifecycleTransition, LitAdapter, type MaskOverride, type MockupGenerationOptions, MockupResult, type MockupService, type MockupServiceConfig, OptionAttribute, type OptionChoice, type OptionChoiceRenderData, type OptionRenderData, OptionSelection, type Placement, type PlacementDesign, PlacementSettings, type ProductArtAlignmentContext, type ProductArtAlignmentDescriptor, type ProductArtAlignmentOptions, type ProductContext, type ProductContextEvents, ProductContextManager, type ProductData, type ProductFetcher, type ProductImageDescriptor, type ProductImageOptions, ProductLoader, type ProductMockupData, type ProductOptionChoice, type ProductOptionData, type ProductOptionsDescriptor, type ProductOptionsOptions, type ProductPlacement, type ProductPriceDescriptor, type ProductPriceOptions, ProductProps, type ProductSpec, type ProductTitleDescriptor, type ProductTitleOptions, type ProductVariant, type PropDefinition, type PropSchema, type PropType, PropertyManager, REALTIME_WS_URL, type RateLimitState, type RealtimeGrant, RealtimeMockupService, type RegularArtwork, type RenderProduct, RenderSession, type RenderSessionOptions, type RenderState, type SdkConfig, type SeamlessPattern, type SignedUrlResponse, type SnowconeClient, StandardComponents, StandardEvents, StateManager, type StateManagerOptions, type StateMiddleware, type StateSelector, type StateSubscriber, type StateUpdater, Styles, SvelteAdapter, SwatchUtils, type TagName, TemplateBuilder, type TemplateNode, type TemplateNodeType, type TemplateRenderer, type TextDescriptor, type TileCount, UniversalContextProvider, type UserSelection, type ValidationError, type ValidationResult, VueAdapter, autoRegister, buildMockupUrl, componentRegistry, createAddToCartEvent, createAddToCartHandler, createCartDetail, createClient, createContextProvider, createDesignForPlacements, createErrorHandler, createEventManager, createLifecycle, createLitComponent, createProductContext, createProductLoader, createPropertyManager, createStateHook, createStateStore, createSvelteComponent, createUniversalProvider, createVueComponent, describeArtSelector, describeProductArtAlignment, describeProductImage, describeProductOptions, describeProductPrice, describeProductTitle, extractProductId, fetchRealtimeGrant, filterImagePlacements, findClosestSnapPoint, findVariantForSelection, formatPrice, formatValidationErrors, getDefaultVariantId, getEffectiveAlignment, getIncompleteSelectionMessage, getMissingSelections, getMockupUrl, getOptionRenderType, getProduct, getSelectionDisplayText, getSnapPoints, getVariant, handleOptionChange, isSelectionComplete, isValidAlignment, isValidTileCount, listProducts, mintRealtimeGrant, mockupUrl, normalizeChoice, prepareOptionRenderData, registerStandardComponents, resolveMockupId, resolveVariantId, retryOperation, simulateCartOperation, toCombinations, toOptionAttributes, useFrameworkAdapter as useVueAdapter, validateAlignment, validateDesignElement, validateEffects, validateImageUrl, validateMockupOptions, validateProductSelection, validateProductSpec, validateRequiredOptions, validateTileCount, withContext, withErrorHandling, withSyncErrorHandling };
|
|
2767
|
+
export { AbstractTemplateRenderer, type AddToCartOptions, Animations, type ArtSelectorContext, type ArtSelectorDescriptor, type ArtSelectorOptions, type ArtworkData, type AspectRatio, Attributes, type BaseDescriptor, type BlendConfig, type BuildMockupUrlConfig, type CartDetail, type CatalogListResponse, type CatalogProduct$2 as CatalogProduct, ClassNames, type ColorDesignElement, ColorPickerUtils, Combination, CommonProps, ComponentContext, type ComponentDefinition, ComponentDescriptor, ComponentEventManager, ComponentFactory, ComponentLifecycle, ComponentLifecycleHooks, type ComponentMetadata, ComponentProps, ComponentRegistry, ComponentState, type ComponentTemplate, ComponentTemplates, type ContainerDescriptor, ContextBridge, type ContextComparator, type ContextConsumer, ContextInjector, type ContextProviderConfig, type ContextSubscriber, ContextSynchronizer, type CreateDesignStateInput, type CreatedDesignState, DEFAULT_ARTWORK_URL, DEFAULT_ASPECT_RATIO, DEFAULT_COLOR, DEFAULT_GRANT_BASE, DEFAULT_MOCKUP_BASE, DEFAULT_PLACEMENT_DIMENSIONS, type Descriptor, type Design, type DesignElement, type DesignGenerationContext, type Effects, Elements, type ErrorContext, type ErrorHandler, ErrorManager, type EventDefinition, EventDelegator, EventEmitter, EventHandler, type EventListener, type EventPayload, type Fill, Focus, FrameworkAdapter, FrameworkUtilities, type GetMockupUrlOptions, type ImageAlignment, type ImageDesignElement, type LifecycleHook, LifecycleManager, type LifecyclePhase, type LifecycleTransition, LitAdapter, type MaskOverride, type MockupGenerationOptions, MockupResult, type MockupService, type MockupServiceConfig, OptionAttribute, type OptionChoice, type OptionChoiceRenderData, type OptionRenderData, OptionSelection, type Placement, type PlacementDesign, PlacementSettings, type ProductArtAlignmentContext, type ProductArtAlignmentDescriptor, type ProductArtAlignmentOptions, type ProductContext, type ProductContextEvents, ProductContextManager, type ProductData, type ProductFetcher, type ProductImageDescriptor, type ProductImageOptions, ProductLoader, type ProductMockupData, type ProductOptionChoice, type ProductOptionData, type ProductOptionsDescriptor, type ProductOptionsOptions, type ProductPlacement, type ProductPriceDescriptor, type ProductPriceOptions, ProductProps, type ProductSpec, type ProductTitleDescriptor, type ProductTitleOptions, type ProductVariant, type PropDefinition, type PropSchema, type PropType, PropertyManager, REALTIME_WS_URL, type RateLimitState, type RealtimeGrant, RealtimeMockupService, type RegularArtwork, type RenderProduct, RenderSession, type RenderSessionOptions, type RenderState, type SdkConfig, type SeamlessPattern, type SignedUrlResponse, type SnowconeClient, StandardComponents, StandardEvents, StateManager, type StateManagerOptions, type StateMiddleware, type StateSelector, type StateSubscriber, type StateUpdater, Styles, SvelteAdapter, SwatchUtils, type TagName, TemplateBuilder, type TemplateNode, type TemplateNodeType, type TemplateRenderer, type TextDescriptor, type TileCount, UniversalContextProvider, type UserSelection, type ValidationError, type ValidationResult, VueAdapter, autoRegister, buildMockupUrl, componentRegistry, createAddToCartEvent, createAddToCartHandler, createCartDetail, createClient, createContextProvider, createDesignForPlacements, createDesignState, createErrorHandler, createEventManager, createLifecycle, createLitComponent, createProductContext, createProductLoader, createPropertyManager, createStateHook, createStateStore, createSvelteComponent, createUniversalProvider, createVueComponent, describeArtSelector, describeProductArtAlignment, describeProductImage, describeProductOptions, describeProductPrice, describeProductTitle, extractProductId, fetchRealtimeGrant, filterImagePlacements, findClosestSnapPoint, findVariantForSelection, formatPrice, formatValidationErrors, getDefaultVariantId, getEffectiveAlignment, getIncompleteSelectionMessage, getMissingSelections, getMockupUrl, getOptionRenderType, getProduct, getSelectionDisplayText, getSnapPoints, getVariant, handleOptionChange, isSelectionComplete, isValidAlignment, isValidTileCount, listProducts, mintRealtimeGrant, mockupUrl, normalizeChoice, prepareOptionRenderData, registerStandardComponents, resolveMockupId, resolveVariantId, retryOperation, simulateCartOperation, toCombinations, toOptionAttributes, useFrameworkAdapter as useVueAdapter, validateAlignment, validateDesignElement, validateEffects, validateImageUrl, validateMockupOptions, validateProductSelection, validateProductSpec, validateRequiredOptions, validateTileCount, withContext, withErrorHandling, withSyncErrorHandling };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { createDevFetcher } from './dev-fetcher.js';
|
|
2
2
|
import { PublicDesign, PublicFill, PublicOptions } from '@snowcone-app/mockup-url';
|
|
3
|
-
import { O as OptionAttribute, a as OptionSelection, C as Combination, F as FrameworkAdapter, b as ComponentProps, c as ComponentDescriptor, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, g as FrameworkUtilities, P as PlacementSettings, M as MockupResult, R as RealtimeMockupService } from './websocket-
|
|
4
|
-
export { A as AdapterRegistry, h as ProductComponentContext, i as RealtimeMockupCallbacks, j as RealtimeMockupState, k as RenderResult, W as WebSocketConfig, l as WebSocketMessage, m as adapterRegistry, n as computeDisabledChoices, o as createComponent, p as defineComponent, q as deriveDefaultSelection, r as findBestCombination, s as getPricePreview, t as isOptionAvailable, u as resolveBestCombination } from './websocket-
|
|
3
|
+
import { O as OptionAttribute, a as OptionSelection, C as Combination, F as FrameworkAdapter, b as ComponentProps, c as ComponentDescriptor, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, g as FrameworkUtilities, P as PlacementSettings, M as MockupResult, R as RealtimeMockupService } from './websocket-Poy8LZNA.js';
|
|
4
|
+
export { A as AdapterRegistry, h as ProductComponentContext, i as RealtimeMockupCallbacks, j as RealtimeMockupState, k as RenderResult, W as WebSocketConfig, l as WebSocketMessage, m as adapterRegistry, n as computeDisabledChoices, o as createComponent, p as defineComponent, q as deriveDefaultSelection, r as findBestCombination, s as getPricePreview, t as isOptionAvailable, u as resolveBestCombination } from './websocket-Poy8LZNA.js';
|
|
5
5
|
|
|
6
6
|
interface CatalogProduct$2 {
|
|
7
7
|
id: string;
|
|
@@ -16,7 +16,6 @@ interface CatalogProduct$2 {
|
|
|
16
16
|
highestPrice?: number;
|
|
17
17
|
mockups?: {
|
|
18
18
|
id: string;
|
|
19
|
-
ar: number;
|
|
20
19
|
gvids: string[];
|
|
21
20
|
}[];
|
|
22
21
|
options?: {
|
|
@@ -2581,8 +2580,18 @@ interface RenderState {
|
|
|
2581
2580
|
/** Product the session renders against (Snowcone catalog ids). */
|
|
2582
2581
|
interface RenderProduct {
|
|
2583
2582
|
productId: string;
|
|
2583
|
+
/**
|
|
2584
|
+
* The mockup scenes to render — opaque catalog codes (the product's
|
|
2585
|
+
* `mockups[].id`, e.g. `'FV1qjO'`). These are a DIFFERENT namespace from the
|
|
2586
|
+
* `placement` you pass to {@link RenderSession.renderState} (a print-area name
|
|
2587
|
+
* like `'Front'`). Don't pass a placement name here.
|
|
2588
|
+
*/
|
|
2584
2589
|
mockupIds: string[];
|
|
2585
|
-
/**
|
|
2590
|
+
/**
|
|
2591
|
+
* Optional variant (gvid). Omit if the product has no variant axis. Required
|
|
2592
|
+
* for products with a color option — it auto-fills the color placement; without
|
|
2593
|
+
* it the render waits for a color blob that never comes.
|
|
2594
|
+
*/
|
|
2586
2595
|
variantId?: string;
|
|
2587
2596
|
/** Render width in px (default 1000). */
|
|
2588
2597
|
width?: number;
|
|
@@ -2631,8 +2640,26 @@ declare class RenderSession {
|
|
|
2631
2640
|
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
2632
2641
|
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
2633
2642
|
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
2643
|
+
*
|
|
2644
|
+
* `placement` is the print-area NAME (e.g. `'Front'`, the product's
|
|
2645
|
+
* `placements[].label`) — a different id from the product's `mockupIds`, and it
|
|
2646
|
+
* must match an artboard in `state`. The server renders only once it has a state
|
|
2647
|
+
* for EVERY required placement, so on a multi-placement product call this once
|
|
2648
|
+
* per placement; a missing one surfaces as an `incomplete_canvas_placements`
|
|
2649
|
+
* error on {@link RenderSession.onError}.
|
|
2650
|
+
*
|
|
2651
|
+
* `state` is the flattened `serializeStateForServer()` shape — NOT the
|
|
2652
|
+
* un-flattened shape `createDesignState` takes.
|
|
2634
2653
|
*/
|
|
2635
2654
|
renderState(placement: string, state: RenderState, throttleMs?: number): Promise<void>;
|
|
2655
|
+
/**
|
|
2656
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). The server resolves
|
|
2657
|
+
* the `stateId`, fetches the referenced assets, and renders — no pixels are
|
|
2658
|
+
* uploaded and you don't need to hold the canvas JSON. Ideal for re-rendering
|
|
2659
|
+
* a stored design (fulfillment, agents, server-to-server). Results arrive via
|
|
2660
|
+
* {@link RenderSession.onMockups}.
|
|
2661
|
+
*/
|
|
2662
|
+
renderSavedState(placement: string, stateId: string): Promise<void>;
|
|
2636
2663
|
/** Update only the mockup ids to render (reuses the current state). */
|
|
2637
2664
|
updateMockupIds(mockupIds: string[]): void;
|
|
2638
2665
|
/** Current rendered results. */
|
|
@@ -2644,6 +2671,45 @@ declare class RenderSession {
|
|
|
2644
2671
|
private toConfig;
|
|
2645
2672
|
}
|
|
2646
2673
|
|
|
2674
|
+
interface CreateDesignStateInput {
|
|
2675
|
+
/** Catalog product code the design targets. */
|
|
2676
|
+
productId: string;
|
|
2677
|
+
/**
|
|
2678
|
+
* The canvas state to persist — the **raw, un-flattened** stored shape:
|
|
2679
|
+
* top-level `elements` with `transformType` + nested `transformData`, plus
|
|
2680
|
+
* bare `artboards` metadata. The server flattens this at render time
|
|
2681
|
+
* (`normalizeCanvasState`).
|
|
2682
|
+
*
|
|
2683
|
+
* ⚠️ This is NOT the `serializeStateForServer()` output you pass to
|
|
2684
|
+
* `RenderSession.renderState` — that shape is already flattened and will
|
|
2685
|
+
* mis-render if stored here. Persist the raw canvas state (e.g. `toJSON()`
|
|
2686
|
+
* from the editor), not the server-render payload.
|
|
2687
|
+
*/
|
|
2688
|
+
state: RenderState | Record<string, unknown>;
|
|
2689
|
+
/**
|
|
2690
|
+
* Preview thumbnail as a base64 PNG/JPEG (no data: prefix). Optional —
|
|
2691
|
+
* defaults to a 1×1 transparent PNG, which is fine for render-only use.
|
|
2692
|
+
*/
|
|
2693
|
+
previewBase64?: string;
|
|
2694
|
+
/** Backend base URL. Defaults to {@link DEFAULT_GRANT_BASE}. */
|
|
2695
|
+
base?: string;
|
|
2696
|
+
/** Override fetch (tests / non-global-fetch runtimes). */
|
|
2697
|
+
fetch?: typeof fetch;
|
|
2698
|
+
}
|
|
2699
|
+
interface CreatedDesignState {
|
|
2700
|
+
/** The id to pass to `renderSavedState(placement, stateId)`. */
|
|
2701
|
+
stateId: string;
|
|
2702
|
+
/** Content-addressed URL of the persisted state JSON. */
|
|
2703
|
+
stateUrl: string;
|
|
2704
|
+
/** Content-addressed URL of the preview image. */
|
|
2705
|
+
previewUrl: string;
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Persist a canvas state and return its `stateId` (+ URLs). Pair with
|
|
2709
|
+
* `RenderSession.renderSavedState(placement, stateId)`.
|
|
2710
|
+
*/
|
|
2711
|
+
declare function createDesignState(input: CreateDesignStateInput): Promise<CreatedDesignState>;
|
|
2712
|
+
|
|
2647
2713
|
interface ProductPlacement {
|
|
2648
2714
|
label: string;
|
|
2649
2715
|
x: number;
|
|
@@ -2698,4 +2764,4 @@ declare function getProduct(idOrSlug: string, config?: Partial<SdkConfig>): Prom
|
|
|
2698
2764
|
*/
|
|
2699
2765
|
declare function createClient(config: SdkConfig): SnowconeClient;
|
|
2700
2766
|
|
|
2701
|
-
export { AbstractTemplateRenderer, type AddToCartOptions, Animations, type ArtSelectorContext, type ArtSelectorDescriptor, type ArtSelectorOptions, type ArtworkData, type AspectRatio, Attributes, type BaseDescriptor, type BlendConfig, type BuildMockupUrlConfig, type CartDetail, type CatalogListResponse, type CatalogProduct$2 as CatalogProduct, ClassNames, type ColorDesignElement, ColorPickerUtils, Combination, CommonProps, ComponentContext, type ComponentDefinition, ComponentDescriptor, ComponentEventManager, ComponentFactory, ComponentLifecycle, ComponentLifecycleHooks, type ComponentMetadata, ComponentProps, ComponentRegistry, ComponentState, type ComponentTemplate, ComponentTemplates, type ContainerDescriptor, ContextBridge, type ContextComparator, type ContextConsumer, ContextInjector, type ContextProviderConfig, type ContextSubscriber, ContextSynchronizer, DEFAULT_ARTWORK_URL, DEFAULT_ASPECT_RATIO, DEFAULT_COLOR, DEFAULT_GRANT_BASE, DEFAULT_MOCKUP_BASE, DEFAULT_PLACEMENT_DIMENSIONS, type Descriptor, type Design, type DesignElement, type DesignGenerationContext, type Effects, Elements, type ErrorContext, type ErrorHandler, ErrorManager, type EventDefinition, EventDelegator, EventEmitter, EventHandler, type EventListener, type EventPayload, type Fill, Focus, FrameworkAdapter, FrameworkUtilities, type GetMockupUrlOptions, type ImageAlignment, type ImageDesignElement, type LifecycleHook, LifecycleManager, type LifecyclePhase, type LifecycleTransition, LitAdapter, type MaskOverride, type MockupGenerationOptions, MockupResult, type MockupService, type MockupServiceConfig, OptionAttribute, type OptionChoice, type OptionChoiceRenderData, type OptionRenderData, OptionSelection, type Placement, type PlacementDesign, PlacementSettings, type ProductArtAlignmentContext, type ProductArtAlignmentDescriptor, type ProductArtAlignmentOptions, type ProductContext, type ProductContextEvents, ProductContextManager, type ProductData, type ProductFetcher, type ProductImageDescriptor, type ProductImageOptions, ProductLoader, type ProductMockupData, type ProductOptionChoice, type ProductOptionData, type ProductOptionsDescriptor, type ProductOptionsOptions, type ProductPlacement, type ProductPriceDescriptor, type ProductPriceOptions, ProductProps, type ProductSpec, type ProductTitleDescriptor, type ProductTitleOptions, type ProductVariant, type PropDefinition, type PropSchema, type PropType, PropertyManager, REALTIME_WS_URL, type RateLimitState, type RealtimeGrant, RealtimeMockupService, type RegularArtwork, type RenderProduct, RenderSession, type RenderSessionOptions, type RenderState, type SdkConfig, type SeamlessPattern, type SignedUrlResponse, type SnowconeClient, StandardComponents, StandardEvents, StateManager, type StateManagerOptions, type StateMiddleware, type StateSelector, type StateSubscriber, type StateUpdater, Styles, SvelteAdapter, SwatchUtils, type TagName, TemplateBuilder, type TemplateNode, type TemplateNodeType, type TemplateRenderer, type TextDescriptor, type TileCount, UniversalContextProvider, type UserSelection, type ValidationError, type ValidationResult, VueAdapter, autoRegister, buildMockupUrl, componentRegistry, createAddToCartEvent, createAddToCartHandler, createCartDetail, createClient, createContextProvider, createDesignForPlacements, createErrorHandler, createEventManager, createLifecycle, createLitComponent, createProductContext, createProductLoader, createPropertyManager, createStateHook, createStateStore, createSvelteComponent, createUniversalProvider, createVueComponent, describeArtSelector, describeProductArtAlignment, describeProductImage, describeProductOptions, describeProductPrice, describeProductTitle, extractProductId, fetchRealtimeGrant, filterImagePlacements, findClosestSnapPoint, findVariantForSelection, formatPrice, formatValidationErrors, getDefaultVariantId, getEffectiveAlignment, getIncompleteSelectionMessage, getMissingSelections, getMockupUrl, getOptionRenderType, getProduct, getSelectionDisplayText, getSnapPoints, getVariant, handleOptionChange, isSelectionComplete, isValidAlignment, isValidTileCount, listProducts, mintRealtimeGrant, mockupUrl, normalizeChoice, prepareOptionRenderData, registerStandardComponents, resolveMockupId, resolveVariantId, retryOperation, simulateCartOperation, toCombinations, toOptionAttributes, useFrameworkAdapter as useVueAdapter, validateAlignment, validateDesignElement, validateEffects, validateImageUrl, validateMockupOptions, validateProductSelection, validateProductSpec, validateRequiredOptions, validateTileCount, withContext, withErrorHandling, withSyncErrorHandling };
|
|
2767
|
+
export { AbstractTemplateRenderer, type AddToCartOptions, Animations, type ArtSelectorContext, type ArtSelectorDescriptor, type ArtSelectorOptions, type ArtworkData, type AspectRatio, Attributes, type BaseDescriptor, type BlendConfig, type BuildMockupUrlConfig, type CartDetail, type CatalogListResponse, type CatalogProduct$2 as CatalogProduct, ClassNames, type ColorDesignElement, ColorPickerUtils, Combination, CommonProps, ComponentContext, type ComponentDefinition, ComponentDescriptor, ComponentEventManager, ComponentFactory, ComponentLifecycle, ComponentLifecycleHooks, type ComponentMetadata, ComponentProps, ComponentRegistry, ComponentState, type ComponentTemplate, ComponentTemplates, type ContainerDescriptor, ContextBridge, type ContextComparator, type ContextConsumer, ContextInjector, type ContextProviderConfig, type ContextSubscriber, ContextSynchronizer, type CreateDesignStateInput, type CreatedDesignState, DEFAULT_ARTWORK_URL, DEFAULT_ASPECT_RATIO, DEFAULT_COLOR, DEFAULT_GRANT_BASE, DEFAULT_MOCKUP_BASE, DEFAULT_PLACEMENT_DIMENSIONS, type Descriptor, type Design, type DesignElement, type DesignGenerationContext, type Effects, Elements, type ErrorContext, type ErrorHandler, ErrorManager, type EventDefinition, EventDelegator, EventEmitter, EventHandler, type EventListener, type EventPayload, type Fill, Focus, FrameworkAdapter, FrameworkUtilities, type GetMockupUrlOptions, type ImageAlignment, type ImageDesignElement, type LifecycleHook, LifecycleManager, type LifecyclePhase, type LifecycleTransition, LitAdapter, type MaskOverride, type MockupGenerationOptions, MockupResult, type MockupService, type MockupServiceConfig, OptionAttribute, type OptionChoice, type OptionChoiceRenderData, type OptionRenderData, OptionSelection, type Placement, type PlacementDesign, PlacementSettings, type ProductArtAlignmentContext, type ProductArtAlignmentDescriptor, type ProductArtAlignmentOptions, type ProductContext, type ProductContextEvents, ProductContextManager, type ProductData, type ProductFetcher, type ProductImageDescriptor, type ProductImageOptions, ProductLoader, type ProductMockupData, type ProductOptionChoice, type ProductOptionData, type ProductOptionsDescriptor, type ProductOptionsOptions, type ProductPlacement, type ProductPriceDescriptor, type ProductPriceOptions, ProductProps, type ProductSpec, type ProductTitleDescriptor, type ProductTitleOptions, type ProductVariant, type PropDefinition, type PropSchema, type PropType, PropertyManager, REALTIME_WS_URL, type RateLimitState, type RealtimeGrant, RealtimeMockupService, type RegularArtwork, type RenderProduct, RenderSession, type RenderSessionOptions, type RenderState, type SdkConfig, type SeamlessPattern, type SignedUrlResponse, type SnowconeClient, StandardComponents, StandardEvents, StateManager, type StateManagerOptions, type StateMiddleware, type StateSelector, type StateSubscriber, type StateUpdater, Styles, SvelteAdapter, SwatchUtils, type TagName, TemplateBuilder, type TemplateNode, type TemplateNodeType, type TemplateRenderer, type TextDescriptor, type TileCount, UniversalContextProvider, type UserSelection, type ValidationError, type ValidationResult, VueAdapter, autoRegister, buildMockupUrl, componentRegistry, createAddToCartEvent, createAddToCartHandler, createCartDetail, createClient, createContextProvider, createDesignForPlacements, createDesignState, createErrorHandler, createEventManager, createLifecycle, createLitComponent, createProductContext, createProductLoader, createPropertyManager, createStateHook, createStateStore, createSvelteComponent, createUniversalProvider, createVueComponent, describeArtSelector, describeProductArtAlignment, describeProductImage, describeProductOptions, describeProductPrice, describeProductTitle, extractProductId, fetchRealtimeGrant, filterImagePlacements, findClosestSnapPoint, findVariantForSelection, formatPrice, formatValidationErrors, getDefaultVariantId, getEffectiveAlignment, getIncompleteSelectionMessage, getMissingSelections, getMockupUrl, getOptionRenderType, getProduct, getSelectionDisplayText, getSnapPoints, getVariant, handleOptionChange, isSelectionComplete, isValidAlignment, isValidTileCount, listProducts, mintRealtimeGrant, mockupUrl, normalizeChoice, prepareOptionRenderData, registerStandardComponents, resolveMockupId, resolveVariantId, retryOperation, simulateCartOperation, toCombinations, toOptionAttributes, useFrameworkAdapter as useVueAdapter, validateAlignment, validateDesignElement, validateEffects, validateImageUrl, validateMockupOptions, validateProductSelection, validateProductSpec, validateRequiredOptions, validateTileCount, withContext, withErrorHandling, withSyncErrorHandling };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
REALTIME_WS_URL,
|
|
6
6
|
RealtimeMockupService
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-D5ZRGKA5.js";
|
|
8
8
|
|
|
9
9
|
// src/validation.ts
|
|
10
10
|
import { z } from "zod";
|
|
@@ -4760,11 +4760,32 @@ var RenderSession = class {
|
|
|
4760
4760
|
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
4761
4761
|
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
4762
4762
|
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
4763
|
+
*
|
|
4764
|
+
* `placement` is the print-area NAME (e.g. `'Front'`, the product's
|
|
4765
|
+
* `placements[].label`) — a different id from the product's `mockupIds`, and it
|
|
4766
|
+
* must match an artboard in `state`. The server renders only once it has a state
|
|
4767
|
+
* for EVERY required placement, so on a multi-placement product call this once
|
|
4768
|
+
* per placement; a missing one surfaces as an `incomplete_canvas_placements`
|
|
4769
|
+
* error on {@link RenderSession.onError}.
|
|
4770
|
+
*
|
|
4771
|
+
* `state` is the flattened `serializeStateForServer()` shape — NOT the
|
|
4772
|
+
* un-flattened shape `createDesignState` takes.
|
|
4763
4773
|
*/
|
|
4764
4774
|
async renderState(placement, state, throttleMs = 0) {
|
|
4765
4775
|
await this.connect();
|
|
4766
4776
|
this.svc.sendCanvasState(placement, state, this.product?.mockupIds.length ?? 1, throttleMs);
|
|
4767
4777
|
}
|
|
4778
|
+
/**
|
|
4779
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). The server resolves
|
|
4780
|
+
* the `stateId`, fetches the referenced assets, and renders — no pixels are
|
|
4781
|
+
* uploaded and you don't need to hold the canvas JSON. Ideal for re-rendering
|
|
4782
|
+
* a stored design (fulfillment, agents, server-to-server). Results arrive via
|
|
4783
|
+
* {@link RenderSession.onMockups}.
|
|
4784
|
+
*/
|
|
4785
|
+
async renderSavedState(placement, stateId) {
|
|
4786
|
+
await this.connect();
|
|
4787
|
+
this.svc.sendCanvasStateRef(placement, stateId);
|
|
4788
|
+
}
|
|
4768
4789
|
/** Update only the mockup ids to render (reuses the current state). */
|
|
4769
4790
|
updateMockupIds(mockupIds) {
|
|
4770
4791
|
if (this.product) this.product = { ...this.product, mockupIds };
|
|
@@ -4797,6 +4818,29 @@ var RenderSession = class {
|
|
|
4797
4818
|
}
|
|
4798
4819
|
};
|
|
4799
4820
|
|
|
4821
|
+
// src/realtime/design-state.ts
|
|
4822
|
+
var TRANSPARENT_1X1_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==";
|
|
4823
|
+
async function createDesignState(input) {
|
|
4824
|
+
const f = input.fetch ?? globalThis.fetch;
|
|
4825
|
+
const res = await f(`${input.base ?? DEFAULT_GRANT_BASE}/snowcone/design-states`, {
|
|
4826
|
+
method: "POST",
|
|
4827
|
+
headers: { "Content-Type": "application/json" },
|
|
4828
|
+
body: JSON.stringify({
|
|
4829
|
+
productId: input.productId,
|
|
4830
|
+
stateJson: JSON.stringify(input.state),
|
|
4831
|
+
previewBase64: input.previewBase64 ?? TRANSPARENT_1X1_PNG
|
|
4832
|
+
})
|
|
4833
|
+
});
|
|
4834
|
+
if (!res.ok) {
|
|
4835
|
+
const detail = await res.text().catch(() => "");
|
|
4836
|
+
throw new Error(`createDesignState failed: ${res.status}${detail ? ` ${detail}` : ""}`);
|
|
4837
|
+
}
|
|
4838
|
+
const body = await res.json();
|
|
4839
|
+
const ds = body?.designState;
|
|
4840
|
+
if (!ds?.id) throw new Error("createDesignState: response missing designState.id");
|
|
4841
|
+
return { stateId: ds.id, stateUrl: ds.stateUrl ?? "", previewUrl: ds.previewUrl ?? "" };
|
|
4842
|
+
}
|
|
4843
|
+
|
|
4800
4844
|
// src/index.ts
|
|
4801
4845
|
function getFetcher(config) {
|
|
4802
4846
|
return config?.fetcher || globalThis.fetch.bind(globalThis);
|
|
@@ -4921,6 +4965,7 @@ export {
|
|
|
4921
4965
|
createComponent,
|
|
4922
4966
|
createContextProvider,
|
|
4923
4967
|
createDesignForPlacements,
|
|
4968
|
+
createDesignState,
|
|
4924
4969
|
createDevFetcher,
|
|
4925
4970
|
createErrorHandler,
|
|
4926
4971
|
createEventManager,
|
package/dist/react.cjs
CHANGED
|
@@ -504,6 +504,32 @@ var RealtimeMockupService = class {
|
|
|
504
504
|
}
|
|
505
505
|
return true;
|
|
506
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). Sends a `stateId`
|
|
509
|
+
* instead of inline state; the server resolves it, fetches the referenced
|
|
510
|
+
* assets, and renders — nothing is uploaded and the client need not hold the
|
|
511
|
+
* canvas JSON. One-shot (no throttle). Results arrive like any other render.
|
|
512
|
+
*/
|
|
513
|
+
sendCanvasStateRef(placement, stateId) {
|
|
514
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN || !this.isConfigured) {
|
|
515
|
+
const reason = !this.ws ? "no WebSocket" : this.ws.readyState !== WebSocket.OPEN ? `ws.readyState=${this.ws.readyState}` : "not configured";
|
|
516
|
+
console.log(`[WS] sendCanvasStateRef BLOCKED for "${placement}": ${reason}`);
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
this.lastSentVersion = ++this.requestVersion;
|
|
520
|
+
this.latestSentVersionByPlacement[placement] = this.lastSentVersion;
|
|
521
|
+
const message = JSON.stringify({
|
|
522
|
+
type: "canvas_state",
|
|
523
|
+
placement,
|
|
524
|
+
version: this.lastSentVersion,
|
|
525
|
+
stateId
|
|
526
|
+
});
|
|
527
|
+
this.ws.send(message);
|
|
528
|
+
this.lastBlobSentAt = Date.now();
|
|
529
|
+
this.addLog(`Sent canvas stateId "${stateId}" for "${placement}" (v${this.lastSentVersion})`, "sent");
|
|
530
|
+
this.callbacks.onBlobSent?.(placement);
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
507
533
|
sendCanvasStateImmediately(placement, state) {
|
|
508
534
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
509
535
|
console.log(`[WS] sendCanvasStateImmediately ABORTED: ws not open`);
|
package/dist/react.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MockupResult, W as WebSocketConfig, P as PlacementSettings, F as FrameworkAdapter, b as ComponentProps, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, c as ComponentDescriptor, g as FrameworkUtilities } from './websocket-
|
|
1
|
+
import { M as MockupResult, W as WebSocketConfig, P as PlacementSettings, F as FrameworkAdapter, b as ComponentProps, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, c as ComponentDescriptor, g as FrameworkUtilities } from './websocket-Poy8LZNA.cjs';
|
|
2
2
|
|
|
3
3
|
interface UseRealtimeMockupOptions {
|
|
4
4
|
wsUrl?: string;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MockupResult, W as WebSocketConfig, P as PlacementSettings, F as FrameworkAdapter, b as ComponentProps, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, c as ComponentDescriptor, g as FrameworkUtilities } from './websocket-
|
|
1
|
+
import { M as MockupResult, W as WebSocketConfig, P as PlacementSettings, F as FrameworkAdapter, b as ComponentProps, d as ComponentState, e as ComponentContext, f as ComponentLifecycleHooks, E as EventHandler, c as ComponentDescriptor, g as FrameworkUtilities } from './websocket-Poy8LZNA.js';
|
|
2
2
|
|
|
3
3
|
interface UseRealtimeMockupOptions {
|
|
4
4
|
wsUrl?: string;
|
package/dist/react.js
CHANGED
|
@@ -356,6 +356,13 @@ declare class RealtimeMockupService {
|
|
|
356
356
|
* Alternative to sendCanvasBlob — the server renders the PNG instead of the client.
|
|
357
357
|
*/
|
|
358
358
|
sendCanvasState(placement: string, state: object, mockupCount?: number, baseThrottleMs?: number): boolean;
|
|
359
|
+
/**
|
|
360
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). Sends a `stateId`
|
|
361
|
+
* instead of inline state; the server resolves it, fetches the referenced
|
|
362
|
+
* assets, and renders — nothing is uploaded and the client need not hold the
|
|
363
|
+
* canvas JSON. One-shot (no throttle). Results arrive like any other render.
|
|
364
|
+
*/
|
|
365
|
+
sendCanvasStateRef(placement: string, stateId: string): boolean;
|
|
359
366
|
private sendCanvasStateImmediately;
|
|
360
367
|
private sendBlobImmediately;
|
|
361
368
|
/**
|
|
@@ -356,6 +356,13 @@ declare class RealtimeMockupService {
|
|
|
356
356
|
* Alternative to sendCanvasBlob — the server renders the PNG instead of the client.
|
|
357
357
|
*/
|
|
358
358
|
sendCanvasState(placement: string, state: object, mockupCount?: number, baseThrottleMs?: number): boolean;
|
|
359
|
+
/**
|
|
360
|
+
* Render a SAVED canvas by reference (ADR-0079 Phase 4). Sends a `stateId`
|
|
361
|
+
* instead of inline state; the server resolves it, fetches the referenced
|
|
362
|
+
* assets, and renders — nothing is uploaded and the client need not hold the
|
|
363
|
+
* canvas JSON. One-shot (no throttle). Results arrive like any other render.
|
|
364
|
+
*/
|
|
365
|
+
sendCanvasStateRef(placement: string, stateId: string): boolean;
|
|
359
366
|
private sendCanvasStateImmediately;
|
|
360
367
|
private sendBlobImmediately;
|
|
361
368
|
/**
|