@snowcone-app/sdk 0.1.10
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 +136 -0
- package/README.md +195 -0
- package/dist/chunk-7VO4EL2V.js +12 -0
- package/dist/chunk-HOYSZQET.js +476 -0
- package/dist/chunk-IIUCW2O4.js +457 -0
- package/dist/chunk-UJFJ7REN.js +485 -0
- package/dist/dev-fetcher.cjs +36 -0
- package/dist/dev-fetcher.d.cts +3 -0
- package/dist/dev-fetcher.d.ts +3 -0
- package/dist/dev-fetcher.js +6 -0
- package/dist/index.cjs +5055 -0
- package/dist/index.d.cts +2437 -0
- package/dist/index.d.ts +2437 -0
- package/dist/index.js +4424 -0
- package/dist/react.cjs +755 -0
- package/dist/react.d.cts +96 -0
- package/dist/react.d.ts +96 -0
- package/dist/react.js +245 -0
- package/dist/websocket-B8_XAwWx.d.cts +336 -0
- package/dist/websocket-B8_XAwWx.d.ts +336 -0
- package/dist/websocket-GXMYofWp.d.cts +330 -0
- package/dist/websocket-GXMYofWp.d.ts +330 -0
- package/package.json +72 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
type OptionSelection = Record<string, string>;
|
|
2
|
+
interface OptionAttribute {
|
|
3
|
+
key: string;
|
|
4
|
+
affectsCombinations: boolean;
|
|
5
|
+
choices: string[];
|
|
6
|
+
type?: string;
|
|
7
|
+
}
|
|
8
|
+
interface Combination {
|
|
9
|
+
variantId: string;
|
|
10
|
+
price?: number;
|
|
11
|
+
[key: string]: string | number | undefined;
|
|
12
|
+
}
|
|
13
|
+
declare function resolveBestCombination(selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): Combination | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Computes which choices should be disabled for each attribute based on the current selection
|
|
16
|
+
* and the list of valid combinations. Non-affecting attributes never disable choices.
|
|
17
|
+
*/
|
|
18
|
+
declare function computeDisabledChoices(selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): Record<string, string[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Derives a reasonable default selection based on the best combination.
|
|
21
|
+
* - For attributes that affect combinations, choose the value from the best combo.
|
|
22
|
+
* - For non-affecting attributes, leave unset (caller may choose first choice if desired).
|
|
23
|
+
*/
|
|
24
|
+
declare function deriveDefaultSelection(attributes: Record<string, OptionAttribute>, combinations: Combination[]): OptionSelection;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the price (if any) of the current best combination for the given selection.
|
|
27
|
+
*/
|
|
28
|
+
declare function getPricePreview(selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): number | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Finds the best matching combination for a given selection.
|
|
31
|
+
* Filters selection to only include attributes that affect combinations.
|
|
32
|
+
* @param selection Current selection state
|
|
33
|
+
* @param combinations All valid combinations
|
|
34
|
+
* @param attributes All product attributes
|
|
35
|
+
* @returns The best matching combination or undefined
|
|
36
|
+
*/
|
|
37
|
+
declare function findBestCombination(selection: OptionSelection, combinations: Combination[], attributes?: Record<string, OptionAttribute>): Combination | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a specific option is available based on the current selection and combinations.
|
|
40
|
+
* This is useful for checking individual options without computing all disabled choices.
|
|
41
|
+
* @param optionName The specific option/choice to check
|
|
42
|
+
* @param attributeName The attribute this option belongs to
|
|
43
|
+
* @param selection Current selection state
|
|
44
|
+
* @param attributes All product attributes
|
|
45
|
+
* @param combinations All valid combinations
|
|
46
|
+
* @returns true if the option is available, false if disabled
|
|
47
|
+
*/
|
|
48
|
+
declare function isOptionAvailable(optionName: string, attributeName: string, selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): boolean;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Framework adapter pattern for supporting multiple UI frameworks
|
|
52
|
+
* Provides a common interface for React, Web Components, Vue, Svelte, etc.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Common component properties that all frameworks must support
|
|
57
|
+
*/
|
|
58
|
+
interface ComponentProps {
|
|
59
|
+
className?: string;
|
|
60
|
+
style?: Record<string, any>;
|
|
61
|
+
children?: any;
|
|
62
|
+
[key: string]: any;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Event handler definition
|
|
66
|
+
*/
|
|
67
|
+
interface EventHandler<T = any> {
|
|
68
|
+
name: string;
|
|
69
|
+
handler: (event: T) => void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Component lifecycle hooks
|
|
73
|
+
*/
|
|
74
|
+
interface ComponentLifecycleHooks {
|
|
75
|
+
onMount?: () => void;
|
|
76
|
+
onUnmount?: () => void;
|
|
77
|
+
onUpdate?: (prevProps: ComponentProps) => void;
|
|
78
|
+
onError?: (error: Error) => void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Component state management
|
|
82
|
+
*/
|
|
83
|
+
interface ComponentState<T = any> {
|
|
84
|
+
get(): T;
|
|
85
|
+
set(value: T | ((prev: T) => T)): void;
|
|
86
|
+
subscribe(callback: (value: T) => void): () => void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Component context interface
|
|
90
|
+
*/
|
|
91
|
+
interface ComponentContext<T = any> {
|
|
92
|
+
provide(value: T): void;
|
|
93
|
+
consume(): T | undefined;
|
|
94
|
+
subscribe(callback: (value: T) => void): () => void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Framework-specific rendering result
|
|
98
|
+
*/
|
|
99
|
+
type RenderResult = any;
|
|
100
|
+
/**
|
|
101
|
+
* Framework adapter interface
|
|
102
|
+
*/
|
|
103
|
+
interface FrameworkAdapter<TProps = ComponentProps> {
|
|
104
|
+
/**
|
|
105
|
+
* Framework name for identification
|
|
106
|
+
*/
|
|
107
|
+
name: 'react' | 'vue' | 'svelte' | 'lit' | 'vanilla' | string;
|
|
108
|
+
/**
|
|
109
|
+
* Create a stateful value
|
|
110
|
+
*/
|
|
111
|
+
createState<T>(initialValue: T): ComponentState<T>;
|
|
112
|
+
/**
|
|
113
|
+
* Create a context provider/consumer
|
|
114
|
+
*/
|
|
115
|
+
createContext<T>(name: string): ComponentContext<T>;
|
|
116
|
+
/**
|
|
117
|
+
* Register lifecycle hooks
|
|
118
|
+
*/
|
|
119
|
+
useLifecycle(lifecycle: ComponentLifecycleHooks): void;
|
|
120
|
+
/**
|
|
121
|
+
* Register event handlers
|
|
122
|
+
*/
|
|
123
|
+
useEvents(handlers: EventHandler[]): void;
|
|
124
|
+
/**
|
|
125
|
+
* Create a ref to a DOM element
|
|
126
|
+
*/
|
|
127
|
+
createRef<T extends HTMLElement>(): {
|
|
128
|
+
current: T | null;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Render method for the framework
|
|
132
|
+
*/
|
|
133
|
+
render(component: ComponentDescriptor, props: TProps): RenderResult;
|
|
134
|
+
/**
|
|
135
|
+
* Get framework-specific utilities
|
|
136
|
+
*/
|
|
137
|
+
getUtilities(): FrameworkUtilities;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Framework-specific utilities
|
|
141
|
+
*/
|
|
142
|
+
interface FrameworkUtilities {
|
|
143
|
+
/**
|
|
144
|
+
* Batch multiple state updates
|
|
145
|
+
*/
|
|
146
|
+
batchUpdates?: (callback: () => void) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Schedule an update for the next tick
|
|
149
|
+
*/
|
|
150
|
+
nextTick?: (callback: () => void) => void;
|
|
151
|
+
/**
|
|
152
|
+
* Create a computed/derived value
|
|
153
|
+
*/
|
|
154
|
+
computed?: <T>(deps: any[], compute: () => T) => T;
|
|
155
|
+
/**
|
|
156
|
+
* Create a memoized value
|
|
157
|
+
*/
|
|
158
|
+
memo?: <T>(value: T, deps: any[]) => T;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Component descriptor for cross-framework components
|
|
162
|
+
*/
|
|
163
|
+
interface ComponentDescriptor {
|
|
164
|
+
name: string;
|
|
165
|
+
props: ComponentProps;
|
|
166
|
+
state?: Record<string, any>;
|
|
167
|
+
methods?: Record<string, Function>;
|
|
168
|
+
lifecycle?: ComponentLifecycleHooks;
|
|
169
|
+
render: (adapter: FrameworkAdapter) => RenderResult;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Product-specific component context
|
|
173
|
+
*/
|
|
174
|
+
interface ProductComponentContext {
|
|
175
|
+
product?: any;
|
|
176
|
+
optionAttributes: Record<string, OptionAttribute>;
|
|
177
|
+
combinations: Combination[];
|
|
178
|
+
selection: OptionSelection;
|
|
179
|
+
updateSelection: (selection: OptionSelection) => void;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Base component factory
|
|
183
|
+
*/
|
|
184
|
+
declare function createComponent<TProps extends ComponentProps = ComponentProps>(descriptor: ComponentDescriptor, adapter: FrameworkAdapter<TProps>): any;
|
|
185
|
+
/**
|
|
186
|
+
* Create a framework-agnostic component definition
|
|
187
|
+
*/
|
|
188
|
+
declare function defineComponent<TProps extends ComponentProps = ComponentProps>(definition: {
|
|
189
|
+
name: string;
|
|
190
|
+
props?: Record<string, any>;
|
|
191
|
+
state?: Record<string, any>;
|
|
192
|
+
methods?: Record<string, Function>;
|
|
193
|
+
lifecycle?: ComponentLifecycleHooks;
|
|
194
|
+
render: (props: TProps, adapter: FrameworkAdapter<TProps>) => RenderResult;
|
|
195
|
+
}): ComponentDescriptor;
|
|
196
|
+
/**
|
|
197
|
+
* Adapter registry for managing multiple frameworks
|
|
198
|
+
*/
|
|
199
|
+
declare class AdapterRegistry {
|
|
200
|
+
private adapters;
|
|
201
|
+
register(adapter: FrameworkAdapter): void;
|
|
202
|
+
get(name: string): FrameworkAdapter | undefined;
|
|
203
|
+
getAll(): FrameworkAdapter[];
|
|
204
|
+
}
|
|
205
|
+
declare const adapterRegistry: AdapterRegistry;
|
|
206
|
+
|
|
207
|
+
interface PlacementSettings {
|
|
208
|
+
tiles?: 0.25 | 0.5 | 1 | 2 | 4 | 8 | 16;
|
|
209
|
+
}
|
|
210
|
+
interface WebSocketConfig {
|
|
211
|
+
productId: string;
|
|
212
|
+
mockupIds: string[];
|
|
213
|
+
variantId: string;
|
|
214
|
+
accountId: string;
|
|
215
|
+
sig: string;
|
|
216
|
+
width: number;
|
|
217
|
+
/** Aspect ratio for mockup rendering (e.g. '2:3' for portrait). Server default: '16:9' */
|
|
218
|
+
ar?: string;
|
|
219
|
+
placementSettings?: Record<string, PlacementSettings>;
|
|
220
|
+
}
|
|
221
|
+
interface MockupResult {
|
|
222
|
+
mockupId: string;
|
|
223
|
+
imageUrl: string;
|
|
224
|
+
renderUrl: string;
|
|
225
|
+
imageSize: number;
|
|
226
|
+
/** The request version this mockup corresponds to (for stale detection) */
|
|
227
|
+
requestVersion?: number;
|
|
228
|
+
/** The placement this mockup corresponds to */
|
|
229
|
+
placement?: string;
|
|
230
|
+
}
|
|
231
|
+
interface WebSocketMessage {
|
|
232
|
+
type: string;
|
|
233
|
+
sessionId?: string;
|
|
234
|
+
mockups?: MockupResult[];
|
|
235
|
+
imageUrl?: string;
|
|
236
|
+
renderUrl?: string;
|
|
237
|
+
mockupId?: string;
|
|
238
|
+
imageSize?: number;
|
|
239
|
+
message?: string;
|
|
240
|
+
placement?: string;
|
|
241
|
+
missingPlacements?: string[];
|
|
242
|
+
/** The request version this response corresponds to (for stale detection) */
|
|
243
|
+
requestVersion?: number;
|
|
244
|
+
}
|
|
245
|
+
interface RealtimeMockupState {
|
|
246
|
+
isConnected: boolean;
|
|
247
|
+
sessionId: string | null;
|
|
248
|
+
isConfigured: boolean;
|
|
249
|
+
mockupResults: MockupResult[];
|
|
250
|
+
status: string;
|
|
251
|
+
logs: string[];
|
|
252
|
+
lastError: string | null;
|
|
253
|
+
}
|
|
254
|
+
interface RealtimeMockupCallbacks {
|
|
255
|
+
onConnected?: (sessionId: string) => void;
|
|
256
|
+
onDisconnected?: () => void;
|
|
257
|
+
onConfigReceived?: () => void;
|
|
258
|
+
/** Called when server confirms it received a blob for a placement */
|
|
259
|
+
onBlobReceived?: (placement: string) => void;
|
|
260
|
+
/** Called when a blob is actually sent to server (after throttle completes) */
|
|
261
|
+
onBlobSent?: (placement: string) => void;
|
|
262
|
+
onMockupRendered?: (result: MockupResult) => void;
|
|
263
|
+
onAllMockupsRendered?: (results: MockupResult[]) => void;
|
|
264
|
+
onError?: (error: string) => void;
|
|
265
|
+
onLog?: (message: string, type: 'info' | 'sent' | 'received') => void;
|
|
266
|
+
}
|
|
267
|
+
declare class RealtimeMockupService {
|
|
268
|
+
private wsUrl;
|
|
269
|
+
private ws;
|
|
270
|
+
private config;
|
|
271
|
+
private configSent;
|
|
272
|
+
private sessionId;
|
|
273
|
+
private isConfigured;
|
|
274
|
+
private mockupResults;
|
|
275
|
+
private status;
|
|
276
|
+
private logs;
|
|
277
|
+
private lastError;
|
|
278
|
+
private callbacks;
|
|
279
|
+
private canvasBlobs;
|
|
280
|
+
private colors;
|
|
281
|
+
private lastSendTime;
|
|
282
|
+
private throttleTimeouts;
|
|
283
|
+
private requestVersion;
|
|
284
|
+
private lastSentVersion;
|
|
285
|
+
private latestSentVersionByPlacement;
|
|
286
|
+
private sendVersionInBlob;
|
|
287
|
+
constructor(wsUrl?: string);
|
|
288
|
+
setCallbacks(callbacks: RealtimeMockupCallbacks): void;
|
|
289
|
+
getState(): RealtimeMockupState;
|
|
290
|
+
private addLog;
|
|
291
|
+
connect(): void;
|
|
292
|
+
private handleMessage;
|
|
293
|
+
disconnect(): void;
|
|
294
|
+
sendConfig(config: WebSocketConfig): boolean;
|
|
295
|
+
/**
|
|
296
|
+
* Update only the mockupIds without changing other config.
|
|
297
|
+
* Server will use already-cached blobs to render the requested mockups.
|
|
298
|
+
* This is the preferred method for priority-based rendering.
|
|
299
|
+
*/
|
|
300
|
+
updateMockupIds(mockupIds: string[]): boolean;
|
|
301
|
+
sendCanvasBlob(placement: string, blob: Blob, mockupCount?: number, baseThrottleMs?: number, notifyCallback?: boolean): boolean;
|
|
302
|
+
private sendBlobImmediately;
|
|
303
|
+
/**
|
|
304
|
+
* Enable sending version number in blob messages.
|
|
305
|
+
* Call this once the server supports the new format: <placement>\n<version>\n<blob>
|
|
306
|
+
*/
|
|
307
|
+
enableVersionInBlob(enabled?: boolean): void;
|
|
308
|
+
/**
|
|
309
|
+
* Flush all pending throttled blobs immediately.
|
|
310
|
+
* Call this when the user finishes an action (e.g., mouse up after drag/flip)
|
|
311
|
+
* to ensure the final state is sent without waiting for throttle.
|
|
312
|
+
*/
|
|
313
|
+
flushPendingBlobs(): void;
|
|
314
|
+
/**
|
|
315
|
+
* Check if there are pending blobs waiting to be sent (in throttle queue)
|
|
316
|
+
*/
|
|
317
|
+
hasPendingBlobs(): boolean;
|
|
318
|
+
sendColorBlob(placement: string, hexColor: string): boolean;
|
|
319
|
+
createEmptyCanvasBlob(width?: number, height?: number): Promise<Blob>;
|
|
320
|
+
sendInitialEmptyCanvases(placements: Array<{
|
|
321
|
+
label: string;
|
|
322
|
+
width?: number;
|
|
323
|
+
height?: number;
|
|
324
|
+
}>): Promise<void>;
|
|
325
|
+
setInitialData(canvasBlobs: Map<string, Blob>, colors: Map<string, string>): void;
|
|
326
|
+
clearLogs(): void;
|
|
327
|
+
clearMockups(): void;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
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 ProductComponentContext as P, type RenderResult 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, createComponent as h, defineComponent as i, adapterRegistry as j, RealtimeMockupService as k, type WebSocketMessage as l, type RealtimeMockupState as m, type RealtimeMockupCallbacks as n, computeDisabledChoices as o, deriveDefaultSelection as p, getPricePreview as q, resolveBestCombination as r, findBestCombination as s, isOptionAvailable as t };
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
type OptionSelection = Record<string, string>;
|
|
2
|
+
interface OptionAttribute {
|
|
3
|
+
key: string;
|
|
4
|
+
affectsCombinations: boolean;
|
|
5
|
+
choices: string[];
|
|
6
|
+
type?: string;
|
|
7
|
+
}
|
|
8
|
+
interface Combination {
|
|
9
|
+
variantId: string;
|
|
10
|
+
price?: number;
|
|
11
|
+
[key: string]: string | number | undefined;
|
|
12
|
+
}
|
|
13
|
+
declare function resolveBestCombination(selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): Combination | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Computes which choices should be disabled for each attribute based on the current selection
|
|
16
|
+
* and the list of valid combinations. Non-affecting attributes never disable choices.
|
|
17
|
+
*/
|
|
18
|
+
declare function computeDisabledChoices(selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): Record<string, string[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Derives a reasonable default selection based on the best combination.
|
|
21
|
+
* - For attributes that affect combinations, choose the value from the best combo.
|
|
22
|
+
* - For non-affecting attributes, leave unset (caller may choose first choice if desired).
|
|
23
|
+
*/
|
|
24
|
+
declare function deriveDefaultSelection(attributes: Record<string, OptionAttribute>, combinations: Combination[]): OptionSelection;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the price (if any) of the current best combination for the given selection.
|
|
27
|
+
*/
|
|
28
|
+
declare function getPricePreview(selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): number | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Finds the best matching combination for a given selection.
|
|
31
|
+
* Filters selection to only include attributes that affect combinations.
|
|
32
|
+
* @param selection Current selection state
|
|
33
|
+
* @param combinations All valid combinations
|
|
34
|
+
* @param attributes All product attributes
|
|
35
|
+
* @returns The best matching combination or undefined
|
|
36
|
+
*/
|
|
37
|
+
declare function findBestCombination(selection: OptionSelection, combinations: Combination[], attributes?: Record<string, OptionAttribute>): Combination | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a specific option is available based on the current selection and combinations.
|
|
40
|
+
* This is useful for checking individual options without computing all disabled choices.
|
|
41
|
+
* @param optionName The specific option/choice to check
|
|
42
|
+
* @param attributeName The attribute this option belongs to
|
|
43
|
+
* @param selection Current selection state
|
|
44
|
+
* @param attributes All product attributes
|
|
45
|
+
* @param combinations All valid combinations
|
|
46
|
+
* @returns true if the option is available, false if disabled
|
|
47
|
+
*/
|
|
48
|
+
declare function isOptionAvailable(optionName: string, attributeName: string, selection: OptionSelection, attributes: Record<string, OptionAttribute>, combinations: Combination[]): boolean;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Framework adapter pattern for supporting multiple UI frameworks
|
|
52
|
+
* Provides a common interface for React, Web Components, Vue, Svelte, etc.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Common component properties that all frameworks must support
|
|
57
|
+
*/
|
|
58
|
+
interface ComponentProps {
|
|
59
|
+
className?: string;
|
|
60
|
+
style?: Record<string, any>;
|
|
61
|
+
children?: any;
|
|
62
|
+
[key: string]: any;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Event handler definition
|
|
66
|
+
*/
|
|
67
|
+
interface EventHandler<T = any> {
|
|
68
|
+
name: string;
|
|
69
|
+
handler: (event: T) => void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Component lifecycle hooks
|
|
73
|
+
*/
|
|
74
|
+
interface ComponentLifecycleHooks {
|
|
75
|
+
onMount?: () => void;
|
|
76
|
+
onUnmount?: () => void;
|
|
77
|
+
onUpdate?: (prevProps: ComponentProps) => void;
|
|
78
|
+
onError?: (error: Error) => void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Component state management
|
|
82
|
+
*/
|
|
83
|
+
interface ComponentState<T = any> {
|
|
84
|
+
get(): T;
|
|
85
|
+
set(value: T | ((prev: T) => T)): void;
|
|
86
|
+
subscribe(callback: (value: T) => void): () => void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Component context interface
|
|
90
|
+
*/
|
|
91
|
+
interface ComponentContext<T = any> {
|
|
92
|
+
provide(value: T): void;
|
|
93
|
+
consume(): T | undefined;
|
|
94
|
+
subscribe(callback: (value: T) => void): () => void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Framework-specific rendering result
|
|
98
|
+
*/
|
|
99
|
+
type RenderResult = any;
|
|
100
|
+
/**
|
|
101
|
+
* Framework adapter interface
|
|
102
|
+
*/
|
|
103
|
+
interface FrameworkAdapter<TProps = ComponentProps> {
|
|
104
|
+
/**
|
|
105
|
+
* Framework name for identification
|
|
106
|
+
*/
|
|
107
|
+
name: 'react' | 'vue' | 'svelte' | 'lit' | 'vanilla' | string;
|
|
108
|
+
/**
|
|
109
|
+
* Create a stateful value
|
|
110
|
+
*/
|
|
111
|
+
createState<T>(initialValue: T): ComponentState<T>;
|
|
112
|
+
/**
|
|
113
|
+
* Create a context provider/consumer
|
|
114
|
+
*/
|
|
115
|
+
createContext<T>(name: string): ComponentContext<T>;
|
|
116
|
+
/**
|
|
117
|
+
* Register lifecycle hooks
|
|
118
|
+
*/
|
|
119
|
+
useLifecycle(lifecycle: ComponentLifecycleHooks): void;
|
|
120
|
+
/**
|
|
121
|
+
* Register event handlers
|
|
122
|
+
*/
|
|
123
|
+
useEvents(handlers: EventHandler[]): void;
|
|
124
|
+
/**
|
|
125
|
+
* Create a ref to a DOM element
|
|
126
|
+
*/
|
|
127
|
+
createRef<T extends HTMLElement>(): {
|
|
128
|
+
current: T | null;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Render method for the framework
|
|
132
|
+
*/
|
|
133
|
+
render(component: ComponentDescriptor, props: TProps): RenderResult;
|
|
134
|
+
/**
|
|
135
|
+
* Get framework-specific utilities
|
|
136
|
+
*/
|
|
137
|
+
getUtilities(): FrameworkUtilities;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Framework-specific utilities
|
|
141
|
+
*/
|
|
142
|
+
interface FrameworkUtilities {
|
|
143
|
+
/**
|
|
144
|
+
* Batch multiple state updates
|
|
145
|
+
*/
|
|
146
|
+
batchUpdates?: (callback: () => void) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Schedule an update for the next tick
|
|
149
|
+
*/
|
|
150
|
+
nextTick?: (callback: () => void) => void;
|
|
151
|
+
/**
|
|
152
|
+
* Create a computed/derived value
|
|
153
|
+
*/
|
|
154
|
+
computed?: <T>(deps: any[], compute: () => T) => T;
|
|
155
|
+
/**
|
|
156
|
+
* Create a memoized value
|
|
157
|
+
*/
|
|
158
|
+
memo?: <T>(value: T, deps: any[]) => T;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Component descriptor for cross-framework components
|
|
162
|
+
*/
|
|
163
|
+
interface ComponentDescriptor {
|
|
164
|
+
name: string;
|
|
165
|
+
props: ComponentProps;
|
|
166
|
+
state?: Record<string, any>;
|
|
167
|
+
methods?: Record<string, Function>;
|
|
168
|
+
lifecycle?: ComponentLifecycleHooks;
|
|
169
|
+
render: (adapter: FrameworkAdapter) => RenderResult;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Product-specific component context
|
|
173
|
+
*/
|
|
174
|
+
interface ProductComponentContext {
|
|
175
|
+
product?: any;
|
|
176
|
+
optionAttributes: Record<string, OptionAttribute>;
|
|
177
|
+
combinations: Combination[];
|
|
178
|
+
selection: OptionSelection;
|
|
179
|
+
updateSelection: (selection: OptionSelection) => void;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Base component factory
|
|
183
|
+
*/
|
|
184
|
+
declare function createComponent<TProps extends ComponentProps = ComponentProps>(descriptor: ComponentDescriptor, adapter: FrameworkAdapter<TProps>): any;
|
|
185
|
+
/**
|
|
186
|
+
* Create a framework-agnostic component definition
|
|
187
|
+
*/
|
|
188
|
+
declare function defineComponent<TProps extends ComponentProps = ComponentProps>(definition: {
|
|
189
|
+
name: string;
|
|
190
|
+
props?: Record<string, any>;
|
|
191
|
+
state?: Record<string, any>;
|
|
192
|
+
methods?: Record<string, Function>;
|
|
193
|
+
lifecycle?: ComponentLifecycleHooks;
|
|
194
|
+
render: (props: TProps, adapter: FrameworkAdapter<TProps>) => RenderResult;
|
|
195
|
+
}): ComponentDescriptor;
|
|
196
|
+
/**
|
|
197
|
+
* Adapter registry for managing multiple frameworks
|
|
198
|
+
*/
|
|
199
|
+
declare class AdapterRegistry {
|
|
200
|
+
private adapters;
|
|
201
|
+
register(adapter: FrameworkAdapter): void;
|
|
202
|
+
get(name: string): FrameworkAdapter | undefined;
|
|
203
|
+
getAll(): FrameworkAdapter[];
|
|
204
|
+
}
|
|
205
|
+
declare const adapterRegistry: AdapterRegistry;
|
|
206
|
+
|
|
207
|
+
interface PlacementSettings {
|
|
208
|
+
tiles?: 0.25 | 0.5 | 1 | 2 | 4 | 8 | 16;
|
|
209
|
+
}
|
|
210
|
+
interface WebSocketConfig {
|
|
211
|
+
productId: string;
|
|
212
|
+
mockupIds: string[];
|
|
213
|
+
variantId: string;
|
|
214
|
+
accountId: string;
|
|
215
|
+
sig: string;
|
|
216
|
+
width: number;
|
|
217
|
+
/** Aspect ratio for mockup rendering (e.g. '2:3' for portrait). Server default: '16:9' */
|
|
218
|
+
ar?: string;
|
|
219
|
+
placementSettings?: Record<string, PlacementSettings>;
|
|
220
|
+
}
|
|
221
|
+
interface MockupResult {
|
|
222
|
+
mockupId: string;
|
|
223
|
+
imageUrl: string;
|
|
224
|
+
renderUrl: string;
|
|
225
|
+
imageSize: number;
|
|
226
|
+
/** The request version this mockup corresponds to (for stale detection) */
|
|
227
|
+
requestVersion?: number;
|
|
228
|
+
/** The placement this mockup corresponds to */
|
|
229
|
+
placement?: string;
|
|
230
|
+
}
|
|
231
|
+
interface WebSocketMessage {
|
|
232
|
+
type: string;
|
|
233
|
+
sessionId?: string;
|
|
234
|
+
mockups?: MockupResult[];
|
|
235
|
+
imageUrl?: string;
|
|
236
|
+
renderUrl?: string;
|
|
237
|
+
mockupId?: string;
|
|
238
|
+
imageSize?: number;
|
|
239
|
+
message?: string;
|
|
240
|
+
placement?: string;
|
|
241
|
+
missingPlacements?: string[];
|
|
242
|
+
/** The request version this response corresponds to (for stale detection) */
|
|
243
|
+
requestVersion?: number;
|
|
244
|
+
}
|
|
245
|
+
interface RealtimeMockupState {
|
|
246
|
+
isConnected: boolean;
|
|
247
|
+
sessionId: string | null;
|
|
248
|
+
isConfigured: boolean;
|
|
249
|
+
mockupResults: MockupResult[];
|
|
250
|
+
status: string;
|
|
251
|
+
logs: string[];
|
|
252
|
+
lastError: string | null;
|
|
253
|
+
}
|
|
254
|
+
interface RealtimeMockupCallbacks {
|
|
255
|
+
onConnected?: (sessionId: string) => void;
|
|
256
|
+
onDisconnected?: () => void;
|
|
257
|
+
onConfigReceived?: () => void;
|
|
258
|
+
/** Called when server confirms it received a blob for a placement */
|
|
259
|
+
onBlobReceived?: (placement: string) => void;
|
|
260
|
+
/** Called when a blob is actually sent to server (after throttle completes) */
|
|
261
|
+
onBlobSent?: (placement: string) => void;
|
|
262
|
+
onMockupRendered?: (result: MockupResult) => void;
|
|
263
|
+
onAllMockupsRendered?: (results: MockupResult[]) => void;
|
|
264
|
+
onError?: (error: string) => void;
|
|
265
|
+
onLog?: (message: string, type: 'info' | 'sent' | 'received') => void;
|
|
266
|
+
}
|
|
267
|
+
declare class RealtimeMockupService {
|
|
268
|
+
private wsUrl;
|
|
269
|
+
private ws;
|
|
270
|
+
private config;
|
|
271
|
+
private configSent;
|
|
272
|
+
private sessionId;
|
|
273
|
+
private isConfigured;
|
|
274
|
+
private mockupResults;
|
|
275
|
+
private status;
|
|
276
|
+
private logs;
|
|
277
|
+
private lastError;
|
|
278
|
+
private callbacks;
|
|
279
|
+
private canvasBlobs;
|
|
280
|
+
private colors;
|
|
281
|
+
private lastSendTime;
|
|
282
|
+
private throttleTimeouts;
|
|
283
|
+
private requestVersion;
|
|
284
|
+
private lastSentVersion;
|
|
285
|
+
private latestSentVersionByPlacement;
|
|
286
|
+
private sendVersionInBlob;
|
|
287
|
+
constructor(wsUrl?: string);
|
|
288
|
+
setCallbacks(callbacks: RealtimeMockupCallbacks): void;
|
|
289
|
+
getState(): RealtimeMockupState;
|
|
290
|
+
private addLog;
|
|
291
|
+
connect(): void;
|
|
292
|
+
private handleMessage;
|
|
293
|
+
disconnect(): void;
|
|
294
|
+
sendConfig(config: WebSocketConfig): boolean;
|
|
295
|
+
/**
|
|
296
|
+
* Update only the mockupIds without changing other config.
|
|
297
|
+
* Server will use already-cached blobs to render the requested mockups.
|
|
298
|
+
* This is the preferred method for priority-based rendering.
|
|
299
|
+
*/
|
|
300
|
+
updateMockupIds(mockupIds: string[]): boolean;
|
|
301
|
+
sendCanvasBlob(placement: string, blob: Blob, mockupCount?: number, baseThrottleMs?: number, notifyCallback?: boolean): boolean;
|
|
302
|
+
private sendBlobImmediately;
|
|
303
|
+
/**
|
|
304
|
+
* Enable sending version number in blob messages.
|
|
305
|
+
* Call this once the server supports the new format: <placement>\n<version>\n<blob>
|
|
306
|
+
*/
|
|
307
|
+
enableVersionInBlob(enabled?: boolean): void;
|
|
308
|
+
/**
|
|
309
|
+
* Flush all pending throttled blobs immediately.
|
|
310
|
+
* Call this when the user finishes an action (e.g., mouse up after drag/flip)
|
|
311
|
+
* to ensure the final state is sent without waiting for throttle.
|
|
312
|
+
*/
|
|
313
|
+
flushPendingBlobs(): void;
|
|
314
|
+
/**
|
|
315
|
+
* Check if there are pending blobs waiting to be sent (in throttle queue)
|
|
316
|
+
*/
|
|
317
|
+
hasPendingBlobs(): boolean;
|
|
318
|
+
sendColorBlob(placement: string, hexColor: string): boolean;
|
|
319
|
+
createEmptyCanvasBlob(width?: number, height?: number): Promise<Blob>;
|
|
320
|
+
sendInitialEmptyCanvases(placements: Array<{
|
|
321
|
+
label: string;
|
|
322
|
+
width?: number;
|
|
323
|
+
height?: number;
|
|
324
|
+
}>): Promise<void>;
|
|
325
|
+
setInitialData(canvasBlobs: Map<string, Blob>, colors: Map<string, string>): void;
|
|
326
|
+
clearLogs(): void;
|
|
327
|
+
clearMockups(): void;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
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 ProductComponentContext as P, type RenderResult 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, createComponent as h, defineComponent as i, adapterRegistry as j, RealtimeMockupService as k, type WebSocketMessage as l, type RealtimeMockupState as m, type RealtimeMockupCallbacks as n, computeDisabledChoices as o, deriveDefaultSelection as p, getPricePreview as q, resolveBestCombination as r, findBestCombination as s, isOptionAvailable as t };
|