@snowcone-app/sdk 0.1.14 → 0.1.15
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 +23 -19
- package/dist/{chunk-6MV7TDTM.js → chunk-RPA3B6I3.js} +5 -1
- package/dist/index.cjs +162 -1
- package/dist/index.d.cts +166 -3
- package/dist/index.d.ts +166 -3
- package/dist/index.js +155 -1
- package/dist/react.cjs +4 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{websocket-Dum3OooZ.d.cts → websocket-BQH1HYJp.d.cts} +1 -1
- package/dist/{websocket-Dum3OooZ.d.ts → websocket-BQH1HYJp.d.ts} +1 -1
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
**JavaScript/TypeScript SDK for product mockups and print-on-demand**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A small, isomorphic SDK for fetching product data and building real-time
|
|
6
|
+
merchandise mockup URLs. Use it to visualize artwork on t-shirts, posters, mugs,
|
|
7
|
+
and more — in the browser or on the server.
|
|
8
|
+
|
|
9
|
+
📖 **Full documentation: [developers.snowcone.app/sdk](https://developers.snowcone.app/sdk)**
|
|
6
10
|
|
|
7
11
|
## Installation
|
|
8
12
|
|
|
@@ -33,9 +37,9 @@ const url = getMockupUrl('hoodie-black', {
|
|
|
33
37
|
// <img src={url} />
|
|
34
38
|
```
|
|
35
39
|
|
|
36
|
-
> The `
|
|
37
|
-
> Cloudinary's cloud name). It defaults to your `shop.id`. See
|
|
38
|
-
>
|
|
40
|
+
> The `shop` ID is your **publishable** token — public and safe to expose (like
|
|
41
|
+
> Cloudinary's cloud name). It defaults to your `shop.id`. See [Public or
|
|
42
|
+
> signed](#public-or-signed) below if you want to lock things down.
|
|
39
43
|
|
|
40
44
|
## Core Functions
|
|
41
45
|
|
|
@@ -94,7 +98,7 @@ const url = getMockupUrl(productCode: string, opts: {
|
|
|
94
98
|
asset?: string; // Single default-placement image (get-started shorthand)
|
|
95
99
|
design?: Design; // Multi-placement: { [placementKey]: Fill } — takes precedence over `asset`
|
|
96
100
|
options?: Record<string, string>; // Variant picks: { size: "m" } → opt.size=m
|
|
97
|
-
secret?: string; // Optional: per-shop secret → appends
|
|
101
|
+
secret?: string; // Optional: per-shop secret → appends a signed &signature (server only)
|
|
98
102
|
base?: string; // Optional: override the host (default img.snowcone.app)
|
|
99
103
|
width?: number; // Optional: display width
|
|
100
104
|
view?: string; // Optional: camera view / mockup scene (alias: `mockup`)
|
|
@@ -140,18 +144,16 @@ const cap = getMockupUrl('RQNU68', {
|
|
|
140
144
|
> accepted (it builds the same URL as `getMockupUrl(productCode, { asset, … })`).
|
|
141
145
|
> Prefer the code-first form above for new code.
|
|
142
146
|
|
|
143
|
-
###
|
|
147
|
+
### Public or signed
|
|
144
148
|
|
|
145
|
-
The default is open and frictionless
|
|
149
|
+
The default is open and frictionless. There's one decision to make up front:
|
|
146
150
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
| **L2** | asset allowlist | restrict which asset sources composite |
|
|
152
|
-
| **L3** | signed URLs | URL must carry a valid `&s` (HMAC of a per-shop secret) |
|
|
151
|
+
- **Public** — the Shop ID alone, safe to expose. Lock it to your **asset
|
|
152
|
+
origins** so a stolen ID can only re-render your own catalog.
|
|
153
|
+
- **Signed** — your server appends an `&signature` (HMAC of a per-shop secret),
|
|
154
|
+
so only you can mint valid URLs. The secret stays server-side.
|
|
153
155
|
|
|
154
|
-
|
|
156
|
+
To sign, pass `secret` (server-side only) and `getMockupUrl` appends the
|
|
155
157
|
verified `&signature`:
|
|
156
158
|
|
|
157
159
|
```typescript
|
|
@@ -163,6 +165,8 @@ const url = getMockupUrl('hoodie-black', {
|
|
|
163
165
|
});
|
|
164
166
|
```
|
|
165
167
|
|
|
168
|
+
See [Public or signed](https://developers.snowcone.app/get-started) for the full picture.
|
|
169
|
+
|
|
166
170
|
### React Hooks (Optional)
|
|
167
171
|
|
|
168
172
|
For React applications, use the React-specific exports:
|
|
@@ -211,14 +215,14 @@ See: [@snowcone-app/ui on npm](https://www.npmjs.com/package/@snowcone-app/ui)
|
|
|
211
215
|
|
|
212
216
|
## Examples
|
|
213
217
|
|
|
214
|
-
- [
|
|
215
|
-
- [
|
|
218
|
+
- [Getting started](https://developers.snowcone.app/get-started)
|
|
219
|
+
- [Mockup URLs reference](https://developers.snowcone.app/mockups)
|
|
220
|
+
- [Live playground](https://developers.snowcone.app/playground)
|
|
216
221
|
|
|
217
222
|
## Support
|
|
218
223
|
|
|
219
|
-
- **
|
|
220
|
-
- **
|
|
221
|
-
- **Docs:** [developers.snowcone.app](https://developers.snowcone.app)
|
|
224
|
+
- **Docs:** [developers.snowcone.app/sdk](https://developers.snowcone.app/sdk)
|
|
225
|
+
- **Issues:** [GitHub Issues](https://github.com/snowcone-app/snowcone-monorepo/issues)
|
|
222
226
|
|
|
223
227
|
## License
|
|
224
228
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
// src/realtime/constants.ts
|
|
2
|
+
var REALTIME_WS_URL = "wss://cdn.snowcone.app/realtime";
|
|
3
|
+
|
|
1
4
|
// src/realtime/websocket.ts
|
|
2
5
|
var RealtimeMockupService = class {
|
|
3
|
-
constructor(wsUrl =
|
|
6
|
+
constructor(wsUrl = REALTIME_WS_URL) {
|
|
4
7
|
this.wsUrl = wsUrl;
|
|
5
8
|
}
|
|
6
9
|
ws = null;
|
|
@@ -649,5 +652,6 @@ ${versionToSend}
|
|
|
649
652
|
};
|
|
650
653
|
|
|
651
654
|
export {
|
|
655
|
+
REALTIME_WS_URL,
|
|
652
656
|
RealtimeMockupService
|
|
653
657
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -38,6 +38,7 @@ __export(index_exports, {
|
|
|
38
38
|
DEFAULT_ARTWORK_URL: () => DEFAULT_ARTWORK_URL,
|
|
39
39
|
DEFAULT_ASPECT_RATIO: () => DEFAULT_ASPECT_RATIO,
|
|
40
40
|
DEFAULT_COLOR: () => DEFAULT_COLOR,
|
|
41
|
+
DEFAULT_GRANT_BASE: () => DEFAULT_GRANT_BASE,
|
|
41
42
|
DEFAULT_MOCKUP_BASE: () => DEFAULT_MOCKUP_BASE,
|
|
42
43
|
DEFAULT_PLACEMENT_DIMENSIONS: () => DEFAULT_PLACEMENT_DIMENSIONS,
|
|
43
44
|
Elements: () => Elements,
|
|
@@ -51,7 +52,9 @@ __export(index_exports, {
|
|
|
51
52
|
ProductLoader: () => ProductLoader,
|
|
52
53
|
ProductProps: () => ProductProps,
|
|
53
54
|
PropertyManager: () => PropertyManager,
|
|
55
|
+
REALTIME_WS_URL: () => REALTIME_WS_URL,
|
|
54
56
|
RealtimeMockupService: () => RealtimeMockupService,
|
|
57
|
+
RenderSession: () => RenderSession,
|
|
55
58
|
StandardComponents: () => StandardComponents,
|
|
56
59
|
StandardEvents: () => StandardEvents,
|
|
57
60
|
StateManager: () => StateManager,
|
|
@@ -95,6 +98,7 @@ __export(index_exports, {
|
|
|
95
98
|
describeProductPrice: () => describeProductPrice,
|
|
96
99
|
describeProductTitle: () => describeProductTitle,
|
|
97
100
|
extractProductId: () => extractProductId,
|
|
101
|
+
fetchRealtimeGrant: () => fetchRealtimeGrant,
|
|
98
102
|
filterImagePlacements: () => filterImagePlacements,
|
|
99
103
|
findBestCombination: () => findBestCombination,
|
|
100
104
|
findClosestSnapPoint: () => findClosestSnapPoint,
|
|
@@ -118,6 +122,7 @@ __export(index_exports, {
|
|
|
118
122
|
isValidAlignment: () => isValidAlignment,
|
|
119
123
|
isValidTileCount: () => isValidTileCount,
|
|
120
124
|
listProducts: () => listProducts,
|
|
125
|
+
mintRealtimeGrant: () => mintRealtimeGrant,
|
|
121
126
|
mockupUrl: () => mockupUrl,
|
|
122
127
|
normalizeChoice: () => normalizeChoice,
|
|
123
128
|
prepareOptionRenderData: () => prepareOptionRenderData,
|
|
@@ -4797,9 +4802,12 @@ function createSvelteComponent(descriptor, svelte) {
|
|
|
4797
4802
|
};
|
|
4798
4803
|
}
|
|
4799
4804
|
|
|
4805
|
+
// src/realtime/constants.ts
|
|
4806
|
+
var REALTIME_WS_URL = "wss://cdn.snowcone.app/realtime";
|
|
4807
|
+
|
|
4800
4808
|
// src/realtime/websocket.ts
|
|
4801
4809
|
var RealtimeMockupService = class {
|
|
4802
|
-
constructor(wsUrl =
|
|
4810
|
+
constructor(wsUrl = REALTIME_WS_URL) {
|
|
4803
4811
|
this.wsUrl = wsUrl;
|
|
4804
4812
|
}
|
|
4805
4813
|
ws = null;
|
|
@@ -5447,6 +5455,154 @@ ${versionToSend}
|
|
|
5447
5455
|
}
|
|
5448
5456
|
};
|
|
5449
5457
|
|
|
5458
|
+
// src/realtime/grant.ts
|
|
5459
|
+
var DEFAULT_GRANT_BASE = "https://api.snowcone.app";
|
|
5460
|
+
async function mintRealtimeGrant(opts) {
|
|
5461
|
+
const f = opts.fetch ?? globalThis.fetch;
|
|
5462
|
+
const res = await f(`${opts.base ?? DEFAULT_GRANT_BASE}/realtime/grant`, {
|
|
5463
|
+
method: "POST",
|
|
5464
|
+
headers: {
|
|
5465
|
+
"Content-Type": "application/json",
|
|
5466
|
+
Authorization: `Bearer ${opts.apiKey}`
|
|
5467
|
+
},
|
|
5468
|
+
body: JSON.stringify({ shop: opts.shop })
|
|
5469
|
+
});
|
|
5470
|
+
if (!res.ok) {
|
|
5471
|
+
const detail = await res.text().catch(() => "");
|
|
5472
|
+
throw new Error(`realtime grant failed: ${res.status}${detail ? ` ${detail}` : ""}`);
|
|
5473
|
+
}
|
|
5474
|
+
return await res.json();
|
|
5475
|
+
}
|
|
5476
|
+
async function fetchRealtimeGrant(grantUrl, shop, fetchImpl) {
|
|
5477
|
+
const f = fetchImpl ?? globalThis.fetch;
|
|
5478
|
+
const res = await f(grantUrl, {
|
|
5479
|
+
method: "POST",
|
|
5480
|
+
headers: { "Content-Type": "application/json" },
|
|
5481
|
+
body: JSON.stringify({ shop })
|
|
5482
|
+
});
|
|
5483
|
+
if (!res.ok) throw new Error(`realtime grant failed: ${res.status}`);
|
|
5484
|
+
return await res.json();
|
|
5485
|
+
}
|
|
5486
|
+
|
|
5487
|
+
// src/realtime/session.ts
|
|
5488
|
+
var RenderSession = class {
|
|
5489
|
+
svc;
|
|
5490
|
+
opts;
|
|
5491
|
+
product;
|
|
5492
|
+
mockupCb = null;
|
|
5493
|
+
errorCb = null;
|
|
5494
|
+
ready = null;
|
|
5495
|
+
constructor(opts) {
|
|
5496
|
+
if (!opts.shop) throw new Error("RenderSession: `shop` is required");
|
|
5497
|
+
if (!opts.getToken && !opts.grantUrl) {
|
|
5498
|
+
throw new Error("RenderSession: provide `grantUrl` or `getToken` to authorize the session");
|
|
5499
|
+
}
|
|
5500
|
+
this.opts = opts;
|
|
5501
|
+
this.product = opts.product ?? null;
|
|
5502
|
+
this.svc = new RealtimeMockupService(opts.wsUrl ?? REALTIME_WS_URL);
|
|
5503
|
+
const getToken = opts.getToken ?? (() => fetchRealtimeGrant(opts.grantUrl, opts.shop, opts.fetch));
|
|
5504
|
+
this.svc.setTokenProvider(getToken);
|
|
5505
|
+
}
|
|
5506
|
+
/** Register a callback fired whenever rendered mockup URLs update. */
|
|
5507
|
+
onMockups(cb) {
|
|
5508
|
+
this.mockupCb = cb;
|
|
5509
|
+
return this;
|
|
5510
|
+
}
|
|
5511
|
+
/** Register an error callback (server/transport errors). */
|
|
5512
|
+
onError(cb) {
|
|
5513
|
+
this.errorCb = cb;
|
|
5514
|
+
return this;
|
|
5515
|
+
}
|
|
5516
|
+
/** Set or update the product. Sends config immediately if already connected. */
|
|
5517
|
+
setProduct(product) {
|
|
5518
|
+
this.product = product;
|
|
5519
|
+
this.svc.sendConfig(this.toConfig(product));
|
|
5520
|
+
}
|
|
5521
|
+
/**
|
|
5522
|
+
* Connect, authorize, and configure. Resolves once the session is ready to
|
|
5523
|
+
* accept {@link RenderSession.renderState}. Idempotent.
|
|
5524
|
+
*/
|
|
5525
|
+
connect() {
|
|
5526
|
+
if (this.ready) return this.ready;
|
|
5527
|
+
if (!this.product) {
|
|
5528
|
+
return Promise.reject(
|
|
5529
|
+
new Error("RenderSession: set a product (via options.product or setProduct) before connect()")
|
|
5530
|
+
);
|
|
5531
|
+
}
|
|
5532
|
+
const product = this.product;
|
|
5533
|
+
this.ready = new Promise((resolve, reject) => {
|
|
5534
|
+
let settled = false;
|
|
5535
|
+
this.svc.setCallbacks({
|
|
5536
|
+
onConnected: () => {
|
|
5537
|
+
this.svc.sendConfig(this.toConfig(product));
|
|
5538
|
+
},
|
|
5539
|
+
onConfigReceived: () => {
|
|
5540
|
+
if (!settled) {
|
|
5541
|
+
settled = true;
|
|
5542
|
+
resolve();
|
|
5543
|
+
}
|
|
5544
|
+
},
|
|
5545
|
+
onMockupRendered: () => {
|
|
5546
|
+
this.mockupCb?.(this.svc.getState().mockupResults);
|
|
5547
|
+
},
|
|
5548
|
+
onAllMockupsRendered: (results) => {
|
|
5549
|
+
this.mockupCb?.(results);
|
|
5550
|
+
},
|
|
5551
|
+
onError: (error) => {
|
|
5552
|
+
this.errorCb?.(error);
|
|
5553
|
+
if (!settled) {
|
|
5554
|
+
settled = true;
|
|
5555
|
+
reject(new Error(error));
|
|
5556
|
+
}
|
|
5557
|
+
}
|
|
5558
|
+
});
|
|
5559
|
+
this.svc.sendConfig(this.toConfig(product));
|
|
5560
|
+
this.svc.connect();
|
|
5561
|
+
});
|
|
5562
|
+
return this.ready;
|
|
5563
|
+
}
|
|
5564
|
+
/**
|
|
5565
|
+
* Render a canvas state for a placement. The server rasterizes it and fetches
|
|
5566
|
+
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
5567
|
+
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
5568
|
+
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
5569
|
+
*/
|
|
5570
|
+
async renderState(placement, state, throttleMs = 0) {
|
|
5571
|
+
await this.connect();
|
|
5572
|
+
this.svc.sendCanvasState(placement, state, this.product?.mockupIds.length ?? 1, throttleMs);
|
|
5573
|
+
}
|
|
5574
|
+
/** Update only the mockup ids to render (reuses the current state). */
|
|
5575
|
+
updateMockupIds(mockupIds) {
|
|
5576
|
+
if (this.product) this.product = { ...this.product, mockupIds };
|
|
5577
|
+
this.svc.updateMockupIds(mockupIds);
|
|
5578
|
+
}
|
|
5579
|
+
/** Current rendered results. */
|
|
5580
|
+
getMockups() {
|
|
5581
|
+
return this.svc.getState().mockupResults;
|
|
5582
|
+
}
|
|
5583
|
+
/** Close the WebSocket and stop auto-renew. */
|
|
5584
|
+
close() {
|
|
5585
|
+
this.svc.disconnect();
|
|
5586
|
+
this.ready = null;
|
|
5587
|
+
}
|
|
5588
|
+
/** Escape hatch: the underlying low-level service. */
|
|
5589
|
+
get service() {
|
|
5590
|
+
return this.svc;
|
|
5591
|
+
}
|
|
5592
|
+
toConfig(product) {
|
|
5593
|
+
return {
|
|
5594
|
+
productId: product.productId,
|
|
5595
|
+
mockupIds: product.mockupIds,
|
|
5596
|
+
// shop comes from the grant token server-side; sent for completeness.
|
|
5597
|
+
shop: this.opts.shop,
|
|
5598
|
+
// WebSocketConfig requires these; the server treats empty variant as "none".
|
|
5599
|
+
variantId: product.variantId ?? "",
|
|
5600
|
+
width: product.width ?? 1e3,
|
|
5601
|
+
...product.placementSettings ? { placementSettings: product.placementSettings } : {}
|
|
5602
|
+
};
|
|
5603
|
+
}
|
|
5604
|
+
};
|
|
5605
|
+
|
|
5450
5606
|
// src/index.ts
|
|
5451
5607
|
function getFetcher(config) {
|
|
5452
5608
|
return config?.fetcher || globalThis.fetch.bind(globalThis);
|
|
@@ -5534,6 +5690,7 @@ function createClient(config) {
|
|
|
5534
5690
|
DEFAULT_ARTWORK_URL,
|
|
5535
5691
|
DEFAULT_ASPECT_RATIO,
|
|
5536
5692
|
DEFAULT_COLOR,
|
|
5693
|
+
DEFAULT_GRANT_BASE,
|
|
5537
5694
|
DEFAULT_MOCKUP_BASE,
|
|
5538
5695
|
DEFAULT_PLACEMENT_DIMENSIONS,
|
|
5539
5696
|
Elements,
|
|
@@ -5547,7 +5704,9 @@ function createClient(config) {
|
|
|
5547
5704
|
ProductLoader,
|
|
5548
5705
|
ProductProps,
|
|
5549
5706
|
PropertyManager,
|
|
5707
|
+
REALTIME_WS_URL,
|
|
5550
5708
|
RealtimeMockupService,
|
|
5709
|
+
RenderSession,
|
|
5551
5710
|
StandardComponents,
|
|
5552
5711
|
StandardEvents,
|
|
5553
5712
|
StateManager,
|
|
@@ -5591,6 +5750,7 @@ function createClient(config) {
|
|
|
5591
5750
|
describeProductPrice,
|
|
5592
5751
|
describeProductTitle,
|
|
5593
5752
|
extractProductId,
|
|
5753
|
+
fetchRealtimeGrant,
|
|
5594
5754
|
filterImagePlacements,
|
|
5595
5755
|
findBestCombination,
|
|
5596
5756
|
findClosestSnapPoint,
|
|
@@ -5614,6 +5774,7 @@ function createClient(config) {
|
|
|
5614
5774
|
isValidAlignment,
|
|
5615
5775
|
isValidTileCount,
|
|
5616
5776
|
listProducts,
|
|
5777
|
+
mintRealtimeGrant,
|
|
5617
5778
|
mockupUrl,
|
|
5618
5779
|
normalizeChoice,
|
|
5619
5780
|
prepareOptionRenderData,
|
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 } from './websocket-
|
|
4
|
-
export { A as AdapterRegistry,
|
|
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-BQH1HYJp.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-BQH1HYJp.cjs';
|
|
5
5
|
|
|
6
6
|
interface CatalogProduct$2 {
|
|
7
7
|
id: string;
|
|
@@ -2481,6 +2481,169 @@ declare class SvelteAdapter implements FrameworkAdapter<ComponentProps> {
|
|
|
2481
2481
|
*/
|
|
2482
2482
|
declare function createSvelteComponent(descriptor: ComponentDescriptor, svelte: any): any;
|
|
2483
2483
|
|
|
2484
|
+
/**
|
|
2485
|
+
* Production realtime render WebSocket endpoint (the rendercenter edge).
|
|
2486
|
+
*
|
|
2487
|
+
* This is the value to connect to for server-side canvas rendering — open
|
|
2488
|
+
* `${REALTIME_WS_URL}?token=<grant>`. Replaces the old un-discoverable
|
|
2489
|
+
* `wss://WS_URL_NOT_CONFIGURED.invalid/realtime` placeholder so a 3rd party
|
|
2490
|
+
* can find the endpoint from the package alone (ADR-0079, Phase 2).
|
|
2491
|
+
*/
|
|
2492
|
+
declare const REALTIME_WS_URL = "wss://cdn.snowcone.app/realtime";
|
|
2493
|
+
|
|
2494
|
+
/**
|
|
2495
|
+
* Realtime grant helpers (ADR-0079, Phase 2).
|
|
2496
|
+
*
|
|
2497
|
+
* A realtime render session is authorized by a short-lived (60s) grant token.
|
|
2498
|
+
* There are two ways to obtain one, mirroring Stripe's pk_/sk_ split:
|
|
2499
|
+
*
|
|
2500
|
+
* - {@link mintRealtimeGrant} — SERVER-SIDE, with a secret API key (sk_).
|
|
2501
|
+
* - {@link fetchRealtimeGrant} — BROWSER, from your own proxy endpoint.
|
|
2502
|
+
*
|
|
2503
|
+
* The browser then opens `${REALTIME_WS_URL}?token=<token>` (RenderSession does
|
|
2504
|
+
* this for you).
|
|
2505
|
+
*/
|
|
2506
|
+
/** A short-lived realtime session grant. */
|
|
2507
|
+
interface RealtimeGrant {
|
|
2508
|
+
/** Opaque session token to put on the WS URL as `?token=`. */
|
|
2509
|
+
token: string;
|
|
2510
|
+
/** Expiry, epoch seconds. Renew before this (RenderSession auto-renews). */
|
|
2511
|
+
expiresAt: number;
|
|
2512
|
+
}
|
|
2513
|
+
/** Default backend base URL hosting `POST /realtime/grant`. */
|
|
2514
|
+
declare const DEFAULT_GRANT_BASE = "https://api.snowcone.app";
|
|
2515
|
+
/**
|
|
2516
|
+
* SERVER-SIDE: mint a realtime grant with a secret API key (sk_). Call this
|
|
2517
|
+
* from YOUR backend — never the browser; the API key must stay secret. The key
|
|
2518
|
+
* needs the `mockups:realtime` (or `mockups`) scope and its organization must
|
|
2519
|
+
* own the target `shop`. Returns a 60s grant your browser code opens the WS
|
|
2520
|
+
* with (hand it down via your own endpoint + {@link fetchRealtimeGrant}).
|
|
2521
|
+
*
|
|
2522
|
+
* @example
|
|
2523
|
+
* // your backend route: POST /api/realtime/grant
|
|
2524
|
+
* const grant = await mintRealtimeGrant({ apiKey: process.env.SNOWCONE_API_KEY!, shop });
|
|
2525
|
+
* return Response.json(grant);
|
|
2526
|
+
*/
|
|
2527
|
+
declare function mintRealtimeGrant(opts: {
|
|
2528
|
+
/** Secret API key (sk_) with the `mockups:realtime` or `mockups` scope. */
|
|
2529
|
+
apiKey: string;
|
|
2530
|
+
/** Target shop id (= shop.id). Must belong to the key's organization. */
|
|
2531
|
+
shop: string;
|
|
2532
|
+
/** Backend base URL. Defaults to {@link DEFAULT_GRANT_BASE}. */
|
|
2533
|
+
base?: string;
|
|
2534
|
+
/** Override fetch (e.g. in tests / non-global-fetch runtimes). */
|
|
2535
|
+
fetch?: typeof fetch;
|
|
2536
|
+
}): Promise<RealtimeGrant>;
|
|
2537
|
+
/**
|
|
2538
|
+
* BROWSER: fetch a grant from your own proxy endpoint, which calls
|
|
2539
|
+
* {@link mintRealtimeGrant} server-side (so the secret key never reaches the
|
|
2540
|
+
* browser). The proxy receives `POST { shop }` and returns `{ token, expiresAt }`.
|
|
2541
|
+
* This is the default token provider {@link RenderSession} uses when given a
|
|
2542
|
+
* `grantUrl`.
|
|
2543
|
+
*/
|
|
2544
|
+
declare function fetchRealtimeGrant(grantUrl: string, shop: string, fetchImpl?: typeof fetch): Promise<RealtimeGrant>;
|
|
2545
|
+
|
|
2546
|
+
/**
|
|
2547
|
+
* RenderSession — a high-level facade over {@link RealtimeMockupService} for the
|
|
2548
|
+
* server-side canvas render flow (ADR-0079, Phase 2).
|
|
2549
|
+
*
|
|
2550
|
+
* It hides the connect → grant → config → renew → canvas_state choreography so a
|
|
2551
|
+
* 3rd party can do what the www PDP does in a few calls, without holding the
|
|
2552
|
+
* artwork bytes or rendering each placement client-side:
|
|
2553
|
+
*
|
|
2554
|
+
* @example
|
|
2555
|
+
* const session = new RenderSession({
|
|
2556
|
+
* shop: 'YOUR_SHOP_ID',
|
|
2557
|
+
* grantUrl: '/api/realtime/grant', // your proxy → mintRealtimeGrant (server)
|
|
2558
|
+
* product: { productId: 'BEEB77', mockupIds: ['front'] },
|
|
2559
|
+
* });
|
|
2560
|
+
* session.onMockups((results) => { img.src = results[0].imageUrl; });
|
|
2561
|
+
* await session.connect();
|
|
2562
|
+
* session.renderState('Front', serializeStateForServer(canvasState));
|
|
2563
|
+
*
|
|
2564
|
+
* For the low-level escape hatch, use {@link RealtimeMockupService} directly.
|
|
2565
|
+
*/
|
|
2566
|
+
|
|
2567
|
+
/**
|
|
2568
|
+
* The server-render canvas state — the JSON produced by `serializeStateForServer()`
|
|
2569
|
+
* in `@snowcone-app/canvas` (its `ServerRenderRequest`). Typed structurally here
|
|
2570
|
+
* so the SDK stays dependency-free; if you have `@snowcone-app/canvas`, its
|
|
2571
|
+
* `ServerRenderRequest` is assignable to this. `schemaVersion` is the wire
|
|
2572
|
+
* contract version (`CANVAS_STATE_SCHEMA_VERSION`); a missing value is treated
|
|
2573
|
+
* as `1` by the renderer.
|
|
2574
|
+
*/
|
|
2575
|
+
interface RenderState {
|
|
2576
|
+
schemaVersion?: number;
|
|
2577
|
+
artboards?: Array<Record<string, unknown>>;
|
|
2578
|
+
elements?: Array<Record<string, unknown>>;
|
|
2579
|
+
[key: string]: unknown;
|
|
2580
|
+
}
|
|
2581
|
+
/** Product the session renders against (Snowcone catalog ids). */
|
|
2582
|
+
interface RenderProduct {
|
|
2583
|
+
productId: string;
|
|
2584
|
+
mockupIds: string[];
|
|
2585
|
+
/** Optional variant (gvid). Omit if the product has no variant axis. */
|
|
2586
|
+
variantId?: string;
|
|
2587
|
+
/** Render width in px (default 1000). */
|
|
2588
|
+
width?: number;
|
|
2589
|
+
/** Per-placement settings (tiling, scale mode). */
|
|
2590
|
+
placementSettings?: Record<string, PlacementSettings>;
|
|
2591
|
+
}
|
|
2592
|
+
interface RenderSessionOptions {
|
|
2593
|
+
/** Publishable shop id (= shop.id, like Stripe pk_). */
|
|
2594
|
+
shop: string;
|
|
2595
|
+
/** Product config. Can also be set later via {@link RenderSession.setProduct}. */
|
|
2596
|
+
product?: RenderProduct;
|
|
2597
|
+
/** Realtime WS endpoint. Defaults to {@link REALTIME_WS_URL}. */
|
|
2598
|
+
wsUrl?: string;
|
|
2599
|
+
/**
|
|
2600
|
+
* How to authorize the session. Provide exactly one:
|
|
2601
|
+
* - `grantUrl`: your endpoint that returns `{ token, expiresAt }` for
|
|
2602
|
+
* `POST { shop }` (recommended — a same-origin proxy to `mintRealtimeGrant`).
|
|
2603
|
+
* - `getToken`: full control over fetching the grant.
|
|
2604
|
+
*/
|
|
2605
|
+
grantUrl?: string;
|
|
2606
|
+
getToken?: () => Promise<RealtimeGrant>;
|
|
2607
|
+
/** Override fetch (used with `grantUrl`). */
|
|
2608
|
+
fetch?: typeof fetch;
|
|
2609
|
+
}
|
|
2610
|
+
declare class RenderSession {
|
|
2611
|
+
private readonly svc;
|
|
2612
|
+
private readonly opts;
|
|
2613
|
+
private product;
|
|
2614
|
+
private mockupCb;
|
|
2615
|
+
private errorCb;
|
|
2616
|
+
private ready;
|
|
2617
|
+
constructor(opts: RenderSessionOptions);
|
|
2618
|
+
/** Register a callback fired whenever rendered mockup URLs update. */
|
|
2619
|
+
onMockups(cb: (results: MockupResult[]) => void): this;
|
|
2620
|
+
/** Register an error callback (server/transport errors). */
|
|
2621
|
+
onError(cb: (error: string) => void): this;
|
|
2622
|
+
/** Set or update the product. Sends config immediately if already connected. */
|
|
2623
|
+
setProduct(product: RenderProduct): void;
|
|
2624
|
+
/**
|
|
2625
|
+
* Connect, authorize, and configure. Resolves once the session is ready to
|
|
2626
|
+
* accept {@link RenderSession.renderState}. Idempotent.
|
|
2627
|
+
*/
|
|
2628
|
+
connect(): Promise<void>;
|
|
2629
|
+
/**
|
|
2630
|
+
* Render a canvas state for a placement. The server rasterizes it and fetches
|
|
2631
|
+
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
2632
|
+
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
2633
|
+
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
2634
|
+
*/
|
|
2635
|
+
renderState(placement: string, state: RenderState, throttleMs?: number): Promise<void>;
|
|
2636
|
+
/** Update only the mockup ids to render (reuses the current state). */
|
|
2637
|
+
updateMockupIds(mockupIds: string[]): void;
|
|
2638
|
+
/** Current rendered results. */
|
|
2639
|
+
getMockups(): MockupResult[];
|
|
2640
|
+
/** Close the WebSocket and stop auto-renew. */
|
|
2641
|
+
close(): void;
|
|
2642
|
+
/** Escape hatch: the underlying low-level service. */
|
|
2643
|
+
get service(): RealtimeMockupService;
|
|
2644
|
+
private toConfig;
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2484
2647
|
interface ProductPlacement {
|
|
2485
2648
|
label: string;
|
|
2486
2649
|
x: number;
|
|
@@ -2535,4 +2698,4 @@ declare function getProduct(idOrSlug: string, config?: Partial<SdkConfig>): Prom
|
|
|
2535
2698
|
*/
|
|
2536
2699
|
declare function createClient(config: SdkConfig): SnowconeClient;
|
|
2537
2700
|
|
|
2538
|
-
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_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, type MockupService, type MockupServiceConfig, OptionAttribute, type OptionChoice, type OptionChoiceRenderData, type OptionRenderData, OptionSelection, type Placement, type PlacementDesign, 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, type RateLimitState, type RegularArtwork, 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, filterImagePlacements, findClosestSnapPoint, findVariantForSelection, formatPrice, formatValidationErrors, getDefaultVariantId, getEffectiveAlignment, getIncompleteSelectionMessage, getMissingSelections, getMockupUrl, getOptionRenderType, getProduct, getSelectionDisplayText, getSnapPoints, getVariant, handleOptionChange, isSelectionComplete, isValidAlignment, isValidTileCount, listProducts, 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 };
|
|
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 };
|
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 } from './websocket-
|
|
4
|
-
export { A as AdapterRegistry,
|
|
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-BQH1HYJp.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-BQH1HYJp.js';
|
|
5
5
|
|
|
6
6
|
interface CatalogProduct$2 {
|
|
7
7
|
id: string;
|
|
@@ -2481,6 +2481,169 @@ declare class SvelteAdapter implements FrameworkAdapter<ComponentProps> {
|
|
|
2481
2481
|
*/
|
|
2482
2482
|
declare function createSvelteComponent(descriptor: ComponentDescriptor, svelte: any): any;
|
|
2483
2483
|
|
|
2484
|
+
/**
|
|
2485
|
+
* Production realtime render WebSocket endpoint (the rendercenter edge).
|
|
2486
|
+
*
|
|
2487
|
+
* This is the value to connect to for server-side canvas rendering — open
|
|
2488
|
+
* `${REALTIME_WS_URL}?token=<grant>`. Replaces the old un-discoverable
|
|
2489
|
+
* `wss://WS_URL_NOT_CONFIGURED.invalid/realtime` placeholder so a 3rd party
|
|
2490
|
+
* can find the endpoint from the package alone (ADR-0079, Phase 2).
|
|
2491
|
+
*/
|
|
2492
|
+
declare const REALTIME_WS_URL = "wss://cdn.snowcone.app/realtime";
|
|
2493
|
+
|
|
2494
|
+
/**
|
|
2495
|
+
* Realtime grant helpers (ADR-0079, Phase 2).
|
|
2496
|
+
*
|
|
2497
|
+
* A realtime render session is authorized by a short-lived (60s) grant token.
|
|
2498
|
+
* There are two ways to obtain one, mirroring Stripe's pk_/sk_ split:
|
|
2499
|
+
*
|
|
2500
|
+
* - {@link mintRealtimeGrant} — SERVER-SIDE, with a secret API key (sk_).
|
|
2501
|
+
* - {@link fetchRealtimeGrant} — BROWSER, from your own proxy endpoint.
|
|
2502
|
+
*
|
|
2503
|
+
* The browser then opens `${REALTIME_WS_URL}?token=<token>` (RenderSession does
|
|
2504
|
+
* this for you).
|
|
2505
|
+
*/
|
|
2506
|
+
/** A short-lived realtime session grant. */
|
|
2507
|
+
interface RealtimeGrant {
|
|
2508
|
+
/** Opaque session token to put on the WS URL as `?token=`. */
|
|
2509
|
+
token: string;
|
|
2510
|
+
/** Expiry, epoch seconds. Renew before this (RenderSession auto-renews). */
|
|
2511
|
+
expiresAt: number;
|
|
2512
|
+
}
|
|
2513
|
+
/** Default backend base URL hosting `POST /realtime/grant`. */
|
|
2514
|
+
declare const DEFAULT_GRANT_BASE = "https://api.snowcone.app";
|
|
2515
|
+
/**
|
|
2516
|
+
* SERVER-SIDE: mint a realtime grant with a secret API key (sk_). Call this
|
|
2517
|
+
* from YOUR backend — never the browser; the API key must stay secret. The key
|
|
2518
|
+
* needs the `mockups:realtime` (or `mockups`) scope and its organization must
|
|
2519
|
+
* own the target `shop`. Returns a 60s grant your browser code opens the WS
|
|
2520
|
+
* with (hand it down via your own endpoint + {@link fetchRealtimeGrant}).
|
|
2521
|
+
*
|
|
2522
|
+
* @example
|
|
2523
|
+
* // your backend route: POST /api/realtime/grant
|
|
2524
|
+
* const grant = await mintRealtimeGrant({ apiKey: process.env.SNOWCONE_API_KEY!, shop });
|
|
2525
|
+
* return Response.json(grant);
|
|
2526
|
+
*/
|
|
2527
|
+
declare function mintRealtimeGrant(opts: {
|
|
2528
|
+
/** Secret API key (sk_) with the `mockups:realtime` or `mockups` scope. */
|
|
2529
|
+
apiKey: string;
|
|
2530
|
+
/** Target shop id (= shop.id). Must belong to the key's organization. */
|
|
2531
|
+
shop: string;
|
|
2532
|
+
/** Backend base URL. Defaults to {@link DEFAULT_GRANT_BASE}. */
|
|
2533
|
+
base?: string;
|
|
2534
|
+
/** Override fetch (e.g. in tests / non-global-fetch runtimes). */
|
|
2535
|
+
fetch?: typeof fetch;
|
|
2536
|
+
}): Promise<RealtimeGrant>;
|
|
2537
|
+
/**
|
|
2538
|
+
* BROWSER: fetch a grant from your own proxy endpoint, which calls
|
|
2539
|
+
* {@link mintRealtimeGrant} server-side (so the secret key never reaches the
|
|
2540
|
+
* browser). The proxy receives `POST { shop }` and returns `{ token, expiresAt }`.
|
|
2541
|
+
* This is the default token provider {@link RenderSession} uses when given a
|
|
2542
|
+
* `grantUrl`.
|
|
2543
|
+
*/
|
|
2544
|
+
declare function fetchRealtimeGrant(grantUrl: string, shop: string, fetchImpl?: typeof fetch): Promise<RealtimeGrant>;
|
|
2545
|
+
|
|
2546
|
+
/**
|
|
2547
|
+
* RenderSession — a high-level facade over {@link RealtimeMockupService} for the
|
|
2548
|
+
* server-side canvas render flow (ADR-0079, Phase 2).
|
|
2549
|
+
*
|
|
2550
|
+
* It hides the connect → grant → config → renew → canvas_state choreography so a
|
|
2551
|
+
* 3rd party can do what the www PDP does in a few calls, without holding the
|
|
2552
|
+
* artwork bytes or rendering each placement client-side:
|
|
2553
|
+
*
|
|
2554
|
+
* @example
|
|
2555
|
+
* const session = new RenderSession({
|
|
2556
|
+
* shop: 'YOUR_SHOP_ID',
|
|
2557
|
+
* grantUrl: '/api/realtime/grant', // your proxy → mintRealtimeGrant (server)
|
|
2558
|
+
* product: { productId: 'BEEB77', mockupIds: ['front'] },
|
|
2559
|
+
* });
|
|
2560
|
+
* session.onMockups((results) => { img.src = results[0].imageUrl; });
|
|
2561
|
+
* await session.connect();
|
|
2562
|
+
* session.renderState('Front', serializeStateForServer(canvasState));
|
|
2563
|
+
*
|
|
2564
|
+
* For the low-level escape hatch, use {@link RealtimeMockupService} directly.
|
|
2565
|
+
*/
|
|
2566
|
+
|
|
2567
|
+
/**
|
|
2568
|
+
* The server-render canvas state — the JSON produced by `serializeStateForServer()`
|
|
2569
|
+
* in `@snowcone-app/canvas` (its `ServerRenderRequest`). Typed structurally here
|
|
2570
|
+
* so the SDK stays dependency-free; if you have `@snowcone-app/canvas`, its
|
|
2571
|
+
* `ServerRenderRequest` is assignable to this. `schemaVersion` is the wire
|
|
2572
|
+
* contract version (`CANVAS_STATE_SCHEMA_VERSION`); a missing value is treated
|
|
2573
|
+
* as `1` by the renderer.
|
|
2574
|
+
*/
|
|
2575
|
+
interface RenderState {
|
|
2576
|
+
schemaVersion?: number;
|
|
2577
|
+
artboards?: Array<Record<string, unknown>>;
|
|
2578
|
+
elements?: Array<Record<string, unknown>>;
|
|
2579
|
+
[key: string]: unknown;
|
|
2580
|
+
}
|
|
2581
|
+
/** Product the session renders against (Snowcone catalog ids). */
|
|
2582
|
+
interface RenderProduct {
|
|
2583
|
+
productId: string;
|
|
2584
|
+
mockupIds: string[];
|
|
2585
|
+
/** Optional variant (gvid). Omit if the product has no variant axis. */
|
|
2586
|
+
variantId?: string;
|
|
2587
|
+
/** Render width in px (default 1000). */
|
|
2588
|
+
width?: number;
|
|
2589
|
+
/** Per-placement settings (tiling, scale mode). */
|
|
2590
|
+
placementSettings?: Record<string, PlacementSettings>;
|
|
2591
|
+
}
|
|
2592
|
+
interface RenderSessionOptions {
|
|
2593
|
+
/** Publishable shop id (= shop.id, like Stripe pk_). */
|
|
2594
|
+
shop: string;
|
|
2595
|
+
/** Product config. Can also be set later via {@link RenderSession.setProduct}. */
|
|
2596
|
+
product?: RenderProduct;
|
|
2597
|
+
/** Realtime WS endpoint. Defaults to {@link REALTIME_WS_URL}. */
|
|
2598
|
+
wsUrl?: string;
|
|
2599
|
+
/**
|
|
2600
|
+
* How to authorize the session. Provide exactly one:
|
|
2601
|
+
* - `grantUrl`: your endpoint that returns `{ token, expiresAt }` for
|
|
2602
|
+
* `POST { shop }` (recommended — a same-origin proxy to `mintRealtimeGrant`).
|
|
2603
|
+
* - `getToken`: full control over fetching the grant.
|
|
2604
|
+
*/
|
|
2605
|
+
grantUrl?: string;
|
|
2606
|
+
getToken?: () => Promise<RealtimeGrant>;
|
|
2607
|
+
/** Override fetch (used with `grantUrl`). */
|
|
2608
|
+
fetch?: typeof fetch;
|
|
2609
|
+
}
|
|
2610
|
+
declare class RenderSession {
|
|
2611
|
+
private readonly svc;
|
|
2612
|
+
private readonly opts;
|
|
2613
|
+
private product;
|
|
2614
|
+
private mockupCb;
|
|
2615
|
+
private errorCb;
|
|
2616
|
+
private ready;
|
|
2617
|
+
constructor(opts: RenderSessionOptions);
|
|
2618
|
+
/** Register a callback fired whenever rendered mockup URLs update. */
|
|
2619
|
+
onMockups(cb: (results: MockupResult[]) => void): this;
|
|
2620
|
+
/** Register an error callback (server/transport errors). */
|
|
2621
|
+
onError(cb: (error: string) => void): this;
|
|
2622
|
+
/** Set or update the product. Sends config immediately if already connected. */
|
|
2623
|
+
setProduct(product: RenderProduct): void;
|
|
2624
|
+
/**
|
|
2625
|
+
* Connect, authorize, and configure. Resolves once the session is ready to
|
|
2626
|
+
* accept {@link RenderSession.renderState}. Idempotent.
|
|
2627
|
+
*/
|
|
2628
|
+
connect(): Promise<void>;
|
|
2629
|
+
/**
|
|
2630
|
+
* Render a canvas state for a placement. The server rasterizes it and fetches
|
|
2631
|
+
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
2632
|
+
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
2633
|
+
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
2634
|
+
*/
|
|
2635
|
+
renderState(placement: string, state: RenderState, throttleMs?: number): Promise<void>;
|
|
2636
|
+
/** Update only the mockup ids to render (reuses the current state). */
|
|
2637
|
+
updateMockupIds(mockupIds: string[]): void;
|
|
2638
|
+
/** Current rendered results. */
|
|
2639
|
+
getMockups(): MockupResult[];
|
|
2640
|
+
/** Close the WebSocket and stop auto-renew. */
|
|
2641
|
+
close(): void;
|
|
2642
|
+
/** Escape hatch: the underlying low-level service. */
|
|
2643
|
+
get service(): RealtimeMockupService;
|
|
2644
|
+
private toConfig;
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2484
2647
|
interface ProductPlacement {
|
|
2485
2648
|
label: string;
|
|
2486
2649
|
x: number;
|
|
@@ -2535,4 +2698,4 @@ declare function getProduct(idOrSlug: string, config?: Partial<SdkConfig>): Prom
|
|
|
2535
2698
|
*/
|
|
2536
2699
|
declare function createClient(config: SdkConfig): SnowconeClient;
|
|
2537
2700
|
|
|
2538
|
-
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_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, type MockupService, type MockupServiceConfig, OptionAttribute, type OptionChoice, type OptionChoiceRenderData, type OptionRenderData, OptionSelection, type Placement, type PlacementDesign, 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, type RateLimitState, type RegularArtwork, 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, filterImagePlacements, findClosestSnapPoint, findVariantForSelection, formatPrice, formatValidationErrors, getDefaultVariantId, getEffectiveAlignment, getIncompleteSelectionMessage, getMissingSelections, getMockupUrl, getOptionRenderType, getProduct, getSelectionDisplayText, getSnapPoints, getVariant, handleOptionChange, isSelectionComplete, isValidAlignment, isValidTileCount, listProducts, 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
createDevFetcher
|
|
3
3
|
} from "./chunk-7VO4EL2V.js";
|
|
4
4
|
import {
|
|
5
|
+
REALTIME_WS_URL,
|
|
5
6
|
RealtimeMockupService
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RPA3B6I3.js";
|
|
7
8
|
|
|
8
9
|
// src/validation.ts
|
|
9
10
|
import { z } from "zod";
|
|
@@ -4648,6 +4649,154 @@ function createSvelteComponent(descriptor, svelte) {
|
|
|
4648
4649
|
};
|
|
4649
4650
|
}
|
|
4650
4651
|
|
|
4652
|
+
// src/realtime/grant.ts
|
|
4653
|
+
var DEFAULT_GRANT_BASE = "https://api.snowcone.app";
|
|
4654
|
+
async function mintRealtimeGrant(opts) {
|
|
4655
|
+
const f = opts.fetch ?? globalThis.fetch;
|
|
4656
|
+
const res = await f(`${opts.base ?? DEFAULT_GRANT_BASE}/realtime/grant`, {
|
|
4657
|
+
method: "POST",
|
|
4658
|
+
headers: {
|
|
4659
|
+
"Content-Type": "application/json",
|
|
4660
|
+
Authorization: `Bearer ${opts.apiKey}`
|
|
4661
|
+
},
|
|
4662
|
+
body: JSON.stringify({ shop: opts.shop })
|
|
4663
|
+
});
|
|
4664
|
+
if (!res.ok) {
|
|
4665
|
+
const detail = await res.text().catch(() => "");
|
|
4666
|
+
throw new Error(`realtime grant failed: ${res.status}${detail ? ` ${detail}` : ""}`);
|
|
4667
|
+
}
|
|
4668
|
+
return await res.json();
|
|
4669
|
+
}
|
|
4670
|
+
async function fetchRealtimeGrant(grantUrl, shop, fetchImpl) {
|
|
4671
|
+
const f = fetchImpl ?? globalThis.fetch;
|
|
4672
|
+
const res = await f(grantUrl, {
|
|
4673
|
+
method: "POST",
|
|
4674
|
+
headers: { "Content-Type": "application/json" },
|
|
4675
|
+
body: JSON.stringify({ shop })
|
|
4676
|
+
});
|
|
4677
|
+
if (!res.ok) throw new Error(`realtime grant failed: ${res.status}`);
|
|
4678
|
+
return await res.json();
|
|
4679
|
+
}
|
|
4680
|
+
|
|
4681
|
+
// src/realtime/session.ts
|
|
4682
|
+
var RenderSession = class {
|
|
4683
|
+
svc;
|
|
4684
|
+
opts;
|
|
4685
|
+
product;
|
|
4686
|
+
mockupCb = null;
|
|
4687
|
+
errorCb = null;
|
|
4688
|
+
ready = null;
|
|
4689
|
+
constructor(opts) {
|
|
4690
|
+
if (!opts.shop) throw new Error("RenderSession: `shop` is required");
|
|
4691
|
+
if (!opts.getToken && !opts.grantUrl) {
|
|
4692
|
+
throw new Error("RenderSession: provide `grantUrl` or `getToken` to authorize the session");
|
|
4693
|
+
}
|
|
4694
|
+
this.opts = opts;
|
|
4695
|
+
this.product = opts.product ?? null;
|
|
4696
|
+
this.svc = new RealtimeMockupService(opts.wsUrl ?? REALTIME_WS_URL);
|
|
4697
|
+
const getToken = opts.getToken ?? (() => fetchRealtimeGrant(opts.grantUrl, opts.shop, opts.fetch));
|
|
4698
|
+
this.svc.setTokenProvider(getToken);
|
|
4699
|
+
}
|
|
4700
|
+
/** Register a callback fired whenever rendered mockup URLs update. */
|
|
4701
|
+
onMockups(cb) {
|
|
4702
|
+
this.mockupCb = cb;
|
|
4703
|
+
return this;
|
|
4704
|
+
}
|
|
4705
|
+
/** Register an error callback (server/transport errors). */
|
|
4706
|
+
onError(cb) {
|
|
4707
|
+
this.errorCb = cb;
|
|
4708
|
+
return this;
|
|
4709
|
+
}
|
|
4710
|
+
/** Set or update the product. Sends config immediately if already connected. */
|
|
4711
|
+
setProduct(product) {
|
|
4712
|
+
this.product = product;
|
|
4713
|
+
this.svc.sendConfig(this.toConfig(product));
|
|
4714
|
+
}
|
|
4715
|
+
/**
|
|
4716
|
+
* Connect, authorize, and configure. Resolves once the session is ready to
|
|
4717
|
+
* accept {@link RenderSession.renderState}. Idempotent.
|
|
4718
|
+
*/
|
|
4719
|
+
connect() {
|
|
4720
|
+
if (this.ready) return this.ready;
|
|
4721
|
+
if (!this.product) {
|
|
4722
|
+
return Promise.reject(
|
|
4723
|
+
new Error("RenderSession: set a product (via options.product or setProduct) before connect()")
|
|
4724
|
+
);
|
|
4725
|
+
}
|
|
4726
|
+
const product = this.product;
|
|
4727
|
+
this.ready = new Promise((resolve, reject) => {
|
|
4728
|
+
let settled = false;
|
|
4729
|
+
this.svc.setCallbacks({
|
|
4730
|
+
onConnected: () => {
|
|
4731
|
+
this.svc.sendConfig(this.toConfig(product));
|
|
4732
|
+
},
|
|
4733
|
+
onConfigReceived: () => {
|
|
4734
|
+
if (!settled) {
|
|
4735
|
+
settled = true;
|
|
4736
|
+
resolve();
|
|
4737
|
+
}
|
|
4738
|
+
},
|
|
4739
|
+
onMockupRendered: () => {
|
|
4740
|
+
this.mockupCb?.(this.svc.getState().mockupResults);
|
|
4741
|
+
},
|
|
4742
|
+
onAllMockupsRendered: (results) => {
|
|
4743
|
+
this.mockupCb?.(results);
|
|
4744
|
+
},
|
|
4745
|
+
onError: (error) => {
|
|
4746
|
+
this.errorCb?.(error);
|
|
4747
|
+
if (!settled) {
|
|
4748
|
+
settled = true;
|
|
4749
|
+
reject(new Error(error));
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4752
|
+
});
|
|
4753
|
+
this.svc.sendConfig(this.toConfig(product));
|
|
4754
|
+
this.svc.connect();
|
|
4755
|
+
});
|
|
4756
|
+
return this.ready;
|
|
4757
|
+
}
|
|
4758
|
+
/**
|
|
4759
|
+
* Render a canvas state for a placement. The server rasterizes it and fetches
|
|
4760
|
+
* the assets referenced inside — no pixels are uploaded. Results arrive via
|
|
4761
|
+
* {@link RenderSession.onMockups}. Safe to call repeatedly (e.g. on every
|
|
4762
|
+
* canvas edit); pass `throttleMs` to debounce during live dragging.
|
|
4763
|
+
*/
|
|
4764
|
+
async renderState(placement, state, throttleMs = 0) {
|
|
4765
|
+
await this.connect();
|
|
4766
|
+
this.svc.sendCanvasState(placement, state, this.product?.mockupIds.length ?? 1, throttleMs);
|
|
4767
|
+
}
|
|
4768
|
+
/** Update only the mockup ids to render (reuses the current state). */
|
|
4769
|
+
updateMockupIds(mockupIds) {
|
|
4770
|
+
if (this.product) this.product = { ...this.product, mockupIds };
|
|
4771
|
+
this.svc.updateMockupIds(mockupIds);
|
|
4772
|
+
}
|
|
4773
|
+
/** Current rendered results. */
|
|
4774
|
+
getMockups() {
|
|
4775
|
+
return this.svc.getState().mockupResults;
|
|
4776
|
+
}
|
|
4777
|
+
/** Close the WebSocket and stop auto-renew. */
|
|
4778
|
+
close() {
|
|
4779
|
+
this.svc.disconnect();
|
|
4780
|
+
this.ready = null;
|
|
4781
|
+
}
|
|
4782
|
+
/** Escape hatch: the underlying low-level service. */
|
|
4783
|
+
get service() {
|
|
4784
|
+
return this.svc;
|
|
4785
|
+
}
|
|
4786
|
+
toConfig(product) {
|
|
4787
|
+
return {
|
|
4788
|
+
productId: product.productId,
|
|
4789
|
+
mockupIds: product.mockupIds,
|
|
4790
|
+
// shop comes from the grant token server-side; sent for completeness.
|
|
4791
|
+
shop: this.opts.shop,
|
|
4792
|
+
// WebSocketConfig requires these; the server treats empty variant as "none".
|
|
4793
|
+
variantId: product.variantId ?? "",
|
|
4794
|
+
width: product.width ?? 1e3,
|
|
4795
|
+
...product.placementSettings ? { placementSettings: product.placementSettings } : {}
|
|
4796
|
+
};
|
|
4797
|
+
}
|
|
4798
|
+
};
|
|
4799
|
+
|
|
4651
4800
|
// src/index.ts
|
|
4652
4801
|
function getFetcher(config) {
|
|
4653
4802
|
return config?.fetcher || globalThis.fetch.bind(globalThis);
|
|
@@ -4734,6 +4883,7 @@ export {
|
|
|
4734
4883
|
DEFAULT_ARTWORK_URL,
|
|
4735
4884
|
DEFAULT_ASPECT_RATIO,
|
|
4736
4885
|
DEFAULT_COLOR,
|
|
4886
|
+
DEFAULT_GRANT_BASE,
|
|
4737
4887
|
DEFAULT_MOCKUP_BASE,
|
|
4738
4888
|
DEFAULT_PLACEMENT_DIMENSIONS,
|
|
4739
4889
|
Elements,
|
|
@@ -4747,7 +4897,9 @@ export {
|
|
|
4747
4897
|
ProductLoader,
|
|
4748
4898
|
ProductProps,
|
|
4749
4899
|
PropertyManager,
|
|
4900
|
+
REALTIME_WS_URL,
|
|
4750
4901
|
RealtimeMockupService,
|
|
4902
|
+
RenderSession,
|
|
4751
4903
|
StandardComponents,
|
|
4752
4904
|
StandardEvents,
|
|
4753
4905
|
StateManager,
|
|
@@ -4791,6 +4943,7 @@ export {
|
|
|
4791
4943
|
describeProductPrice,
|
|
4792
4944
|
describeProductTitle,
|
|
4793
4945
|
extractProductId,
|
|
4946
|
+
fetchRealtimeGrant,
|
|
4794
4947
|
filterImagePlacements,
|
|
4795
4948
|
findBestCombination,
|
|
4796
4949
|
findClosestSnapPoint,
|
|
@@ -4814,6 +4967,7 @@ export {
|
|
|
4814
4967
|
isValidAlignment,
|
|
4815
4968
|
isValidTileCount,
|
|
4816
4969
|
listProducts,
|
|
4970
|
+
mintRealtimeGrant,
|
|
4817
4971
|
mockupUrl,
|
|
4818
4972
|
normalizeChoice,
|
|
4819
4973
|
prepareOptionRenderData,
|
package/dist/react.cjs
CHANGED
|
@@ -30,9 +30,12 @@ module.exports = __toCommonJS(react_exports);
|
|
|
30
30
|
// src/realtime/react.ts
|
|
31
31
|
var import_react = require("react");
|
|
32
32
|
|
|
33
|
+
// src/realtime/constants.ts
|
|
34
|
+
var REALTIME_WS_URL = "wss://cdn.snowcone.app/realtime";
|
|
35
|
+
|
|
33
36
|
// src/realtime/websocket.ts
|
|
34
37
|
var RealtimeMockupService = class {
|
|
35
|
-
constructor(wsUrl =
|
|
38
|
+
constructor(wsUrl = REALTIME_WS_URL) {
|
|
36
39
|
this.wsUrl = wsUrl;
|
|
37
40
|
}
|
|
38
41
|
ws = null;
|
package/dist/react.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MockupResult, W as WebSocketConfig,
|
|
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-BQH1HYJp.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,
|
|
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-BQH1HYJp.js';
|
|
2
2
|
|
|
3
3
|
interface UseRealtimeMockupOptions {
|
|
4
4
|
wsUrl?: string;
|
package/dist/react.js
CHANGED
|
@@ -385,4 +385,4 @@ declare class RealtimeMockupService {
|
|
|
385
385
|
clearMockups(): void;
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
export { AdapterRegistry as A, type Combination as C, type EventHandler as E, type FrameworkAdapter as F, type MockupResult as M, type OptionAttribute as O, type
|
|
388
|
+
export { AdapterRegistry as A, type Combination as C, type EventHandler as E, type FrameworkAdapter as F, type MockupResult as M, type OptionAttribute as O, type PlacementSettings as P, RealtimeMockupService as R, type WebSocketConfig as W, type OptionSelection as a, type ComponentProps as b, type ComponentDescriptor as c, type ComponentState as d, type ComponentContext as e, type ComponentLifecycleHooks as f, type FrameworkUtilities as g, type ProductComponentContext as h, type RealtimeMockupCallbacks as i, type RealtimeMockupState as j, type RenderResult as k, type WebSocketMessage as l, adapterRegistry as m, computeDisabledChoices as n, createComponent as o, defineComponent as p, deriveDefaultSelection as q, findBestCombination as r, getPricePreview as s, isOptionAvailable as t, resolveBestCombination as u };
|
|
@@ -385,4 +385,4 @@ declare class RealtimeMockupService {
|
|
|
385
385
|
clearMockups(): void;
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
export { AdapterRegistry as A, type Combination as C, type EventHandler as E, type FrameworkAdapter as F, type MockupResult as M, type OptionAttribute as O, type
|
|
388
|
+
export { AdapterRegistry as A, type Combination as C, type EventHandler as E, type FrameworkAdapter as F, type MockupResult as M, type OptionAttribute as O, type PlacementSettings as P, RealtimeMockupService as R, type WebSocketConfig as W, type OptionSelection as a, type ComponentProps as b, type ComponentDescriptor as c, type ComponentState as d, type ComponentContext as e, type ComponentLifecycleHooks as f, type FrameworkUtilities as g, type ProductComponentContext as h, type RealtimeMockupCallbacks as i, type RealtimeMockupState as j, type RenderResult as k, type WebSocketMessage as l, adapterRegistry as m, computeDisabledChoices as n, createComponent as o, defineComponent as p, deriveDefaultSelection as q, findBestCombination as r, getPricePreview as s, isOptionAvailable as t, resolveBestCombination as u };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowcone-app/sdk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.15",
|
|
4
|
+
"description": "Snowcone SDK for product mockups and print-on-demand",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"merch",
|
|
7
7
|
"mockup",
|
|
@@ -14,10 +14,13 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
|
17
|
-
"url": "https://github.com/snowcone-app/
|
|
17
|
+
"url": "https://github.com/snowcone-app/snowcone-monorepo.git",
|
|
18
18
|
"directory": "packages/sdk"
|
|
19
19
|
},
|
|
20
|
-
"
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/snowcone-app/snowcone-monorepo/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://developers.snowcone.app/sdk",
|
|
21
24
|
"private": false,
|
|
22
25
|
"type": "module",
|
|
23
26
|
"main": "dist/index.cjs",
|