@drip-apex/sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/README.md +5 -0
  2. package/dist/bundle-report.json +584 -226
  3. package/dist/define.cjs +123 -0
  4. package/dist/define.cjs.map +7 -0
  5. package/dist/define.mjs +102 -0
  6. package/dist/define.mjs.map +7 -0
  7. package/dist/drip.cjs +19262 -0
  8. package/dist/drip.cjs.map +7 -0
  9. package/dist/drip.debug.js +1 -1
  10. package/dist/drip.debug.js.map +1 -1
  11. package/dist/drip.heatmap.js +1 -1
  12. package/dist/drip.heatmap.js.map +1 -1
  13. package/dist/drip.js +1 -1
  14. package/dist/drip.js.map +1 -1
  15. package/dist/drip.live.js +1 -1
  16. package/dist/drip.live.js.map +1 -1
  17. package/dist/drip.mjs +19246 -0
  18. package/dist/drip.mjs.map +7 -0
  19. package/dist/drip.replay-recorder.js +2 -0
  20. package/dist/drip.replay-recorder.js.map +1 -0
  21. package/dist/editor.js +147 -142
  22. package/dist/editor.js.map +4 -4
  23. package/dist/flags.cjs +1788 -0
  24. package/dist/flags.cjs.map +7 -0
  25. package/dist/flags.mjs +1765 -0
  26. package/dist/flags.mjs.map +7 -0
  27. package/dist/index.mjs +12 -0
  28. package/dist/index.mjs.map +2 -2
  29. package/dist/metafiles/define.cjs.meta.json +28 -0
  30. package/dist/metafiles/define.mjs.meta.json +32 -0
  31. package/dist/metafiles/drip.cjs.meta.json +3193 -0
  32. package/dist/metafiles/drip.debug.meta.json +2859 -574
  33. package/dist/metafiles/drip.heatmap.meta.json +2732 -460
  34. package/dist/metafiles/drip.live.meta.json +2732 -460
  35. package/dist/metafiles/drip.meta.json +2859 -574
  36. package/dist/metafiles/drip.mjs.meta.json +3235 -0
  37. package/dist/metafiles/drip.replay-recorder.meta.json +82 -0
  38. package/dist/metafiles/editor.meta.json +67 -27
  39. package/dist/metafiles/flags.cjs.meta.json +220 -0
  40. package/dist/metafiles/flags.mjs.meta.json +225 -0
  41. package/dist/metafiles/index.meta.json +2717 -491
  42. package/dist/metafiles/index.mjs.meta.json +14 -4
  43. package/dist/react/index.js +16621 -13539
  44. package/dist/react/index.js.map +4 -4
  45. package/dist/sri.json +20 -15
  46. package/dist/types/activation-runtime.d.ts +91 -0
  47. package/dist/types/analytics-runtime.d.ts +166 -0
  48. package/dist/types/antiflicker.d.ts +9 -3
  49. package/dist/types/assignment-cookie-sync.d.ts +31 -0
  50. package/dist/types/assignment-runtime.d.ts +257 -0
  51. package/dist/types/assignment-store.d.ts +4 -8
  52. package/dist/types/bucket.d.ts +1 -2
  53. package/dist/types/compact-store.d.ts +1 -0
  54. package/dist/types/config-runtime.d.ts +313 -0
  55. package/dist/types/consent-evaluation.d.ts +27 -0
  56. package/dist/types/css.d.ts +5 -3
  57. package/dist/types/debug-loader.d.ts +2 -0
  58. package/dist/types/decide-assignments.d.ts +31 -0
  59. package/dist/types/delivery-timing.d.ts +8 -0
  60. package/dist/types/early-interaction-capture.d.ts +79 -0
  61. package/dist/types/early-reassert.d.ts +32 -0
  62. package/dist/types/edge-runtime.d.ts +11 -0
  63. package/dist/types/editor/api.d.ts +3 -0
  64. package/dist/types/editor/controller.d.ts +3 -1
  65. package/dist/types/editor/publication-result.d.ts +11 -0
  66. package/dist/types/editor/types.d.ts +2 -1
  67. package/dist/types/editor/view-kit.d.ts +1 -1
  68. package/dist/types/endpoint.d.ts +8 -0
  69. package/dist/types/exclusion-groups.d.ts +4 -7
  70. package/dist/types/flags.d.ts +2 -0
  71. package/dist/types/goal-eligibility.d.ts +4 -0
  72. package/dist/types/goals.d.ts +10 -1
  73. package/dist/types/guards.d.ts +7 -7
  74. package/dist/types/handover.d.ts +12 -1
  75. package/dist/types/hash.d.ts +8 -4
  76. package/dist/types/hydration.d.ts +2 -1
  77. package/dist/types/index.d.ts +24 -128
  78. package/dist/types/init-test-helpers.d.ts +48 -0
  79. package/dist/types/inline-bootstrap.d.ts +26 -0
  80. package/dist/types/js.d.ts +3 -1
  81. package/dist/types/money.d.ts +12 -0
  82. package/dist/types/mutate.d.ts +45 -6
  83. package/dist/types/performance.d.ts +2 -0
  84. package/dist/types/persistence-decoders.d.ts +12 -0
  85. package/dist/types/public-api.d.ts +209 -0
  86. package/dist/types/qa-assistant-state.d.ts +34 -0
  87. package/dist/types/react/index.d.ts +28 -3
  88. package/dist/types/reassert-sentinel.d.ts +6 -0
  89. package/dist/types/redirect.d.ts +48 -0
  90. package/dist/types/replay-recorder-entry.d.ts +1 -0
  91. package/dist/types/replay-signal-state.d.ts +6 -0
  92. package/dist/types/replay-signals.d.ts +13 -0
  93. package/dist/types/replay.d.ts +110 -0
  94. package/dist/types/router.d.ts +12 -2
  95. package/dist/types/runtime-state.d.ts +166 -0
  96. package/dist/types/sanitize.d.ts +1 -0
  97. package/dist/types/shadow.d.ts +3 -0
  98. package/dist/types/shopify-cart.d.ts +25 -1
  99. package/dist/types/storefront-vitals.d.ts +24 -0
  100. package/dist/types/targeting-diagnostics.d.ts +1 -0
  101. package/dist/types/targeting.d.ts +16 -2
  102. package/dist/types/track.d.ts +15 -1
  103. package/dist/types/types.d.ts +115 -9
  104. package/dist/types/wait.d.ts +14 -1
  105. package/dist/types/weekday-schedule.d.ts +3 -0
  106. package/package.json +17 -8
  107. package/src/activation-runtime.ts +2737 -0
  108. package/src/analytics-runtime.ts +2175 -0
  109. package/src/antiflicker.test.ts +216 -44
  110. package/src/antiflicker.ts +103 -28
  111. package/src/artifact-concurrency.test.ts +1091 -0
  112. package/src/assignment-cookie-sync.test.ts +202 -0
  113. package/src/assignment-cookie-sync.ts +189 -0
  114. package/src/assignment-runtime.ts +3204 -0
  115. package/src/assignment-store.test.ts +56 -0
  116. package/src/assignment-store.ts +7 -38
  117. package/src/bucket.ts +3 -18
  118. package/src/commerce-analytics-lifecycle.test.ts +75 -15
  119. package/src/commerce-config-lifecycle.test.ts +81 -1
  120. package/src/commerce-price-preserve.test.ts +133 -0
  121. package/src/commerce-price.test.ts +97 -0
  122. package/src/commerce-price.ts +74 -20
  123. package/src/commerce-shipping.test.ts +53 -0
  124. package/src/commerce-shipping.ts +5 -11
  125. package/src/compact-store.ts +15 -0
  126. package/src/config-fetch.test.ts +480 -9
  127. package/src/config-runtime.ts +2070 -0
  128. package/src/consent-evaluation-cookiescript.test.ts +50 -0
  129. package/src/consent-evaluation.ts +138 -0
  130. package/src/css.test.ts +30 -0
  131. package/src/css.ts +120 -6
  132. package/src/cwv.test.ts +60 -77
  133. package/src/debug-loader.test.ts +214 -0
  134. package/src/debug-loader.ts +41 -0
  135. package/src/decide-assignments.test.ts +196 -0
  136. package/src/decide-assignments.ts +204 -0
  137. package/src/delivery-timing.test.ts +104 -0
  138. package/src/delivery-timing.ts +89 -0
  139. package/src/early-interaction-capture.test.ts +451 -0
  140. package/src/early-interaction-capture.ts +230 -0
  141. package/src/early-reassert.test.ts +207 -0
  142. package/src/early-reassert.ts +152 -0
  143. package/src/edge-adoption.test.ts +435 -0
  144. package/src/edge-runtime.ts +30 -0
  145. package/src/editor/api.test.ts +109 -0
  146. package/src/editor/api.ts +34 -3
  147. package/src/editor/controller.test.ts +297 -14
  148. package/src/editor/controller.ts +69 -5
  149. package/src/editor/index.test.ts +2 -0
  150. package/src/editor/index.ts +1 -0
  151. package/src/editor/publication-result.ts +58 -0
  152. package/src/editor/types.ts +10 -1
  153. package/src/editor/view-kit.ts +2 -1
  154. package/src/editor/view.test.ts +108 -0
  155. package/src/editor/view.ts +49 -7
  156. package/src/endpoint.test.ts +15 -0
  157. package/src/endpoint.ts +10 -0
  158. package/src/exclusion-groups.ts +8 -18
  159. package/src/flags.test.ts +88 -1
  160. package/src/flags.ts +29 -29
  161. package/src/global-runtime-reconciler.test.ts +271 -0
  162. package/src/goal-eligibility.test.ts +29 -0
  163. package/src/goal-eligibility.ts +17 -0
  164. package/src/goals.test.ts +144 -1
  165. package/src/goals.ts +97 -18
  166. package/src/guards.test.ts +99 -1
  167. package/src/guards.ts +34 -15
  168. package/src/handover-cache-order.test.ts +6 -3
  169. package/src/handover.test.ts +154 -8
  170. package/src/handover.ts +122 -12
  171. package/src/hash.ts +29 -54
  172. package/src/holdout.test.ts +26 -0
  173. package/src/hydration.test.ts +73 -2
  174. package/src/hydration.ts +18 -9
  175. package/src/index.ts +130 -7287
  176. package/src/init-analytics.test.ts +1694 -0
  177. package/src/init-anti-flicker.test.ts +1211 -0
  178. package/src/init-cart-attributes.test.ts +2003 -0
  179. package/src/init-config-resolution.test.ts +999 -0
  180. package/src/init-consent.test.ts +971 -0
  181. package/src/init-empty.test.ts +11 -5406
  182. package/src/init-integrations.test.ts +846 -0
  183. package/src/init-page-activation.test.ts +5064 -0
  184. package/src/init-qa-loading.test.ts +740 -0
  185. package/src/init-redirects.test.ts +2156 -0
  186. package/src/init-test-helpers.ts +287 -0
  187. package/src/inline-bootstrap.test.ts +184 -0
  188. package/src/inline-bootstrap.ts +73 -0
  189. package/src/js.test.ts +51 -1
  190. package/src/js.ts +86 -2
  191. package/src/money.test.ts +55 -1
  192. package/src/money.ts +104 -2
  193. package/src/money.web-parity.contract.test.ts +85 -0
  194. package/src/mutate.test.ts +474 -10
  195. package/src/mutate.ts +739 -230
  196. package/src/page-trigger.test.ts +218 -8
  197. package/src/performance.ts +10 -0
  198. package/src/persistence-decoders.ts +18 -0
  199. package/src/public-api.ts +1828 -0
  200. package/src/qa-assistant-state.test.ts +249 -3
  201. package/src/qa-assistant-state.ts +146 -6
  202. package/src/qa-assistant-view.test.ts +220 -2
  203. package/src/qa-assistant-view.ts +102 -5
  204. package/src/react/index.test.tsx +37 -0
  205. package/src/react/index.tsx +19 -3
  206. package/src/reassert-sentinel.test.ts +155 -1
  207. package/src/reassert-sentinel.ts +168 -8
  208. package/src/redirect.test.ts +541 -0
  209. package/src/redirect.ts +572 -0
  210. package/src/replay-recorder-entry.ts +115 -0
  211. package/src/replay-signal-state.ts +100 -0
  212. package/src/replay-signals.test.ts +249 -0
  213. package/src/replay-signals.ts +151 -0
  214. package/src/replay.test.ts +764 -0
  215. package/src/replay.ts +514 -0
  216. package/src/router.test.ts +61 -2
  217. package/src/router.ts +50 -12
  218. package/src/runtime-state.ts +507 -0
  219. package/src/runtime.test.ts +174 -7
  220. package/src/runtime.ts +88 -14
  221. package/src/sanitize.test.ts +34 -0
  222. package/src/sanitize.ts +23 -12
  223. package/src/shadow.test.ts +187 -0
  224. package/src/shadow.ts +99 -0
  225. package/src/shopify-cart.test.ts +733 -23
  226. package/src/shopify-cart.ts +402 -49
  227. package/src/storefront-vitals.test.ts +217 -0
  228. package/src/storefront-vitals.ts +206 -0
  229. package/src/surface-signals.ts +6 -0
  230. package/src/targeting-conformance.test.ts +9 -0
  231. package/src/targeting-diagnostics.ts +38 -8
  232. package/src/targeting-parity-corpus.json +559 -0
  233. package/src/targeting-parity-corpus.test.ts +18 -0
  234. package/src/targeting.detailed.test.ts +105 -0
  235. package/src/targeting.test.ts +211 -0
  236. package/src/targeting.ts +88 -207
  237. package/src/track.test.ts +147 -0
  238. package/src/track.ts +125 -26
  239. package/src/types.ts +120 -13
  240. package/src/wait.test.ts +23 -0
  241. package/src/wait.ts +129 -13
  242. package/src/weekday-delivery.test.ts +56 -0
  243. package/src/weekday-schedule-parity-corpus.json +92 -0
  244. package/src/weekday-schedule.test.ts +69 -0
  245. package/src/weekday-schedule.ts +20 -0
@@ -0,0 +1,313 @@
1
+ import type { CompactGroupSelections } from "./persistence-decoders";
2
+ import { getSignals as getStoredSignals } from "./signals";
3
+ import { ActivationMode, AntiFlickerMode, Assignment, ActivationGateDiagnostic, CustomJsPolicy, ExecutionMode, Experiment, InitConfig, PageTargetingRule, PageTriggerMode, PlatformHint, SegmentCondition, RuntimeSignalDefinition, SdkDiagnostics, DataProtectionSettings, DataLayerSignalMapping, DataLayerTriggerSettings, TrackingStart } from "./types";
4
+ export declare function applyRuntimeAntiFlicker(mode: AntiFlickerMode, timeoutMs: number, scopedSelectors?: string[], customCss?: string): boolean;
5
+ export declare const SDK_SCRIPT_SRC: string | undefined;
6
+ export type HeatmapController = {
7
+ stop: () => void;
8
+ update: (assignments: Assignment[], experiments: Experiment[]) => void;
9
+ };
10
+ export type SemanticController = {
11
+ stop: () => void;
12
+ };
13
+ export type FetchAttemptInfo = {
14
+ attempt: number;
15
+ elapsedMs: number;
16
+ error?: string;
17
+ status?: number;
18
+ timedOut?: boolean;
19
+ };
20
+ export type FetchRetryOptions = {
21
+ timeoutMs?: number;
22
+ firstAttemptTimeoutMs?: number;
23
+ slowMs?: number;
24
+ onAttemptStart?: (attempt: number) => void;
25
+ onAttemptEnd?: (info: FetchAttemptInfo) => void;
26
+ onSlow?: (info: {
27
+ attempt: number;
28
+ elapsedMs: number;
29
+ }) => void;
30
+ };
31
+ export declare const DEFAULT_CONFIG_FETCH_TIMEOUT_MS = 4500;
32
+ export declare const DEFAULT_CONFIG_FETCH_SLOW_MS = 1500;
33
+ export declare const CONFIG_FETCH_RETRY_COUNT = 2;
34
+ export declare const CONFIG_FETCH_RETRY_DELAY_MS = 500;
35
+ export declare const CONFIG_FETCH_MAX_WAIT_MS: number;
36
+ export declare const CACHED_REDIRECT_HIDE_TIMEOUT_MS: number;
37
+ export declare function createFetchTimeoutError(): Error | DOMException;
38
+ export declare function fetchWithTimeout(url: string, timeoutMs: number): Promise<Response>;
39
+ export declare function fetchWithRetry(url: string, retries?: number, delayMs?: number, options?: FetchRetryOptions): Promise<Response>;
40
+ export declare const CONFIG_CACHE_KEY_PREFIX = "drip_cfg:";
41
+ export declare const DEFAULT_CONFIG_CACHE_TTL_MS: number;
42
+ export declare const DEFAULT_ANTI_FLICKER_TIMEOUT_MS = 1200;
43
+ export declare const DEFAULT_TRACKING_IDLE_TIMEOUT_MS = 2000;
44
+ export declare const DEFAULT_EXECUTION_MODE: ExecutionMode;
45
+ export declare const DEFAULT_TRACKING_START: TrackingStart;
46
+ export declare const DEFAULT_JS_POLICY: CustomJsPolicy;
47
+ export declare const PAGE_RULE_POLL_WINDOW_MS = 2000;
48
+ export declare const PAGE_RULE_POLL_INTERVAL_MS = 50;
49
+ export declare const CONSENT_COOKIE_NAME = "drip_consent";
50
+ export declare const IDENTITY_CONTEXT_COOKIE_NAME = "drip_ctx";
51
+ export declare const IDENTITY_CONTEXT_COOKIE_MAX_AGE_SECONDS: number;
52
+ export declare const IDENTITY_CONTEXT_COOKIE_MAX_ENCODED_BYTES = 1024;
53
+ export declare const SESSION_STORAGE_KEY = "drip_sid";
54
+ export declare function collectScopedSelectors(experiments: Experiment[], config?: InitConfig, assignments?: Assignment[]): string[];
55
+ export type ResolvedRuntimeConfig = {
56
+ executionMode: ExecutionMode;
57
+ antiFlickerMode: AntiFlickerMode;
58
+ antiFlickerTimeoutMs: number;
59
+ antiFlickerCustomCss?: string;
60
+ trackingStart: TrackingStart;
61
+ trackingIdleTimeoutMs: number;
62
+ customJsPolicy: CustomJsPolicy;
63
+ proxyEventDelivery?: {
64
+ enabled: boolean;
65
+ path?: string;
66
+ };
67
+ assetFallback?: boolean;
68
+ };
69
+ export type UrlDiffNeeds = {
70
+ path: boolean;
71
+ search: boolean;
72
+ hash: boolean;
73
+ };
74
+ export type ConfigSource = "inline" | "cache" | "network" | "none";
75
+ export type PendingPerfEvent = {
76
+ perf_event_kind: "init" | "route_change";
77
+ assignment_ready_ms: number;
78
+ init_total_ms?: number;
79
+ guard_resolve_ms?: number;
80
+ consent_identity_ms?: number;
81
+ runtime_setup_ms?: number;
82
+ targeting_assignment_ms?: number;
83
+ mutation_finalize_ms?: number;
84
+ predecision_mismatch_count?: number;
85
+ unattributed_init_ms?: number;
86
+ dom_content_loaded_ms: number;
87
+ /** @deprecated One-release alias for dom_content_loaded_ms. */
88
+ blank_screen_ms: number;
89
+ platform: PlatformHint;
90
+ config_source: ConfigSource;
91
+ activation_mode: ActivationMode;
92
+ sdk_version: string;
93
+ sdk_delivery_mode: string;
94
+ sdk_delivery_source: string;
95
+ sdk_policy_revision: string;
96
+ snippet_revision?: number;
97
+ runtime_profile: string;
98
+ sdk_variant: string;
99
+ snippet_fetch_ms: number;
100
+ snippet_transfer_size: number;
101
+ sdk_bundle_fetch_ms: number;
102
+ sdk_bundle_transfer_size: number;
103
+ time_to_sdk_ready_ms?: number;
104
+ experiment_count?: number;
105
+ assignment_count?: number;
106
+ mutation_count?: number;
107
+ script_exec_start?: number;
108
+ anti_flicker_inserted_at?: number;
109
+ assignment_ready_at?: number;
110
+ first_mutation_at?: number;
111
+ reveal_at?: number;
112
+ hidden_duration_ms?: number;
113
+ current_page_hide_selector_count?: number;
114
+ delivery_state?: string;
115
+ script_cache_source?: string;
116
+ install_surface?: string;
117
+ first_install_surface?: string;
118
+ config_fetch_ms?: number;
119
+ config_fetch_attempts?: number;
120
+ config_fetch_status?: RuntimeLoadDiagnostic["configFetchStatus"];
121
+ config_fetch_status_code?: number;
122
+ mutation_apply_pending?: number;
123
+ mutation_apply_applied?: number;
124
+ mutation_apply_missed?: number;
125
+ cls_total?: number;
126
+ cls_after_reveal?: number;
127
+ hydration_detected_at?: number;
128
+ apply_delayed_ms?: number;
129
+ hydration_timeout?: boolean;
130
+ hold_timeout?: boolean;
131
+ reapply_count?: number;
132
+ reassert_loop_detected?: boolean;
133
+ early_apply_at?: number;
134
+ reasserts_count?: number;
135
+ revert_loops_detected?: number;
136
+ };
137
+ export type InitPhaseKey = "guard_resolve_ms" | "consent_identity_ms" | "runtime_setup_ms" | "targeting_assignment_ms" | "mutation_finalize_ms";
138
+ export type InitPerfContext = {
139
+ startedAt: number;
140
+ phases: Partial<Record<InitPhaseKey, number>>;
141
+ includesConfigFetch: boolean;
142
+ predecisionMismatches: number;
143
+ };
144
+ export declare const MAX_PERF_DURATION_MS = 60000;
145
+ export declare function monotonicNow(): number;
146
+ export declare function boundedPerfDuration(value: number): number;
147
+ export declare function createInitPerfContext(): InitPerfContext;
148
+ export type BootstrapPredecision = {
149
+ decision: Array<[experimentId: string, variationId: string]>;
150
+ configRevision: number;
151
+ visitorId: string;
152
+ groups: CompactGroupSelections;
153
+ };
154
+ export declare function bootstrapPredecision(config: InitConfig, perf: InitPerfContext): BootstrapPredecision | null;
155
+ export declare function addInitPhase(context: InitPerfContext, phase: InitPhaseKey, startedAt: number): void;
156
+ export type DeliveryHealthStatus = "applied" | "partial" | "miss" | "control" | "no_mutations";
157
+ export type DeliveryHealthTracker = {
158
+ assignment: Assignment;
159
+ expected: number;
160
+ applied: Set<number>;
161
+ missed: Set<number>;
162
+ emitted: boolean;
163
+ };
164
+ export type RouteDiagnostic = {
165
+ previousUrl: string;
166
+ nextUrl: string;
167
+ reason: string;
168
+ at: number;
169
+ reEvaluated: boolean;
170
+ };
171
+ export type DataLayerDiagnostic = {
172
+ eventName: string;
173
+ dataLayerName: string;
174
+ at: number;
175
+ mappedSignals: string[];
176
+ gtagNormalized?: boolean;
177
+ };
178
+ export type ShopifySyncDiagnostic = {
179
+ at: number;
180
+ status: "pending" | "sent" | "skipped" | "failed";
181
+ reason?: string;
182
+ assignmentCount: number;
183
+ };
184
+ export type ShopifyAssignmentSyncDiagnostic = Omit<ShopifySyncDiagnostic, "status"> & {
185
+ status: ShopifySyncDiagnostic["status"] | "cookie_fallback";
186
+ truncatedAssignmentCount?: number;
187
+ };
188
+ export type ExposureDestinationDiagnostic = {
189
+ type: string;
190
+ status: "sent" | "skipped" | "failed";
191
+ at: number;
192
+ reason?: string;
193
+ };
194
+ export type RuntimeLoadDiagnostic = SdkDiagnostics["load"];
195
+ export type DripPerfWindow = Window & {
196
+ __dripPerf?: Record<string, unknown>;
197
+ };
198
+ export declare function normalizeNumber(value: unknown, fallback: number): number;
199
+ export declare function resolveRuntimeConfig(config: InitConfig): ResolvedRuntimeConfig;
200
+ export declare function resolvePageTriggerMode(config: InitConfig): PageTriggerMode;
201
+ export declare function resolveDomPageTrigger(config: InitConfig, pageTriggerMode: PageTriggerMode): boolean;
202
+ export declare function dtLog(type: string, label: string, detail?: Record<string, unknown>): void;
203
+ export declare function traceName(id: string, name?: string): string;
204
+ export declare function traceStep(message: string, data?: Record<string, unknown>): void;
205
+ export declare function traceGate(experiment: Experiment, gate: ActivationGateDiagnostic): void;
206
+ export declare function browserDoNotTrackValue(): string;
207
+ export declare function trackingBlocked(): boolean;
208
+ export declare let storefrontVitalsGateOpen: boolean | null;
209
+ export declare function syncStorefrontVitals(): void;
210
+ export declare function doNotTrackEnabled(config: InitConfig): boolean;
211
+ export declare function storageAllowed(consentRequired: boolean, consentGranted: boolean, trackingDisabledByDnt: boolean): boolean;
212
+ export declare function readWindowPath(path: string | undefined): unknown;
213
+ export declare function configuredConsentGranted(config: InitConfig): boolean | null;
214
+ export declare function syncConfiguredConsent(config: InitConfig): void;
215
+ export declare const CUSTOM_CONSENT_POLL_INTERVAL_MS = 1000;
216
+ export declare const CUSTOM_CONSENT_POLL_MAX_MS: number;
217
+ export declare const MANUAL_CALLBACK_TRIGGER_RERUN_INTERVAL_MS = 1000;
218
+ export declare const MANUAL_CALLBACK_TRIGGER_RERUN_MAX_MS = 10000;
219
+ export declare const MANUAL_CALLBACK_TRIGGER_MAX_RERUNS = 10;
220
+ export declare const EVENT_DRIVEN_CONSENT_PROVIDERS: Set<string>;
221
+ export declare function shouldPollConfiguredConsent(config: InitConfig): boolean;
222
+ export declare function installConsentChangeListeners(config: InitConfig): (() => void) | null;
223
+ export declare function resolveConsentRequired(config: InitConfig): boolean;
224
+ export declare function resolveConsentGranted(config: InitConfig, consentRequired: boolean): boolean;
225
+ export declare function persistentStorageAllowed(): boolean;
226
+ export declare function coerceSignalValue(value: unknown, valueType?: RuntimeSignalDefinition["valueType"]): unknown;
227
+ export declare function captureUrlSignals(config: InitConfig): void;
228
+ export declare function installClickSignalCaptures(config: InitConfig): (() => void) | null;
229
+ export declare function captureEventPropertySignals(type: string, data?: Record<string, unknown>): void;
230
+ export declare function setCapturedSignal(key: string, value: unknown, opts: {
231
+ ttlDays?: number;
232
+ persist?: boolean;
233
+ source: string;
234
+ }): void;
235
+ export declare function setPublicSignal(key: string, value: unknown, ttlDays?: number, source?: string): void;
236
+ export declare function getPublicSignals(options?: {
237
+ markVisitorSeen?: boolean;
238
+ }): ReturnType<typeof getStoredSignals>;
239
+ export declare function normalizePageApiName(value: unknown): string;
240
+ export declare function pageTriggerSignal(normalizedApiName: string): string;
241
+ export declare function triggerPage(apiName: unknown, active?: unknown): void;
242
+ export declare function readElementCaptureValue(element: Element, capture: NonNullable<RuntimeSignalDefinition["capture"]>): unknown;
243
+ export declare function captureDomAndGlobalSignals(config: InitConfig): void;
244
+ export declare function consentAwareDataProtection(config: InitConfig): DataProtectionSettings | undefined;
245
+ export declare function writeConsentCookie(granted: boolean): void;
246
+ export declare function readConsentCookie(): boolean;
247
+ export declare function clearConsentStorage(): void;
248
+ export declare function applyConsentStorageMode(): void;
249
+ export declare function runWhenDomReady(callback: () => void): void;
250
+ export declare function applyProjectCode(config: InitConfig): void;
251
+ export declare function resetProjectCode(): void;
252
+ export declare function runProjectStartupCode(config: InitConfig): void;
253
+ export declare function collectJsTriggerConditions(experiments: Experiment[]): SegmentCondition[];
254
+ export declare function collectPageTriggerRules(experiments: Experiment[]): PageTargetingRule[];
255
+ export type PageDetectorMode = "history" | "polling" | "dom";
256
+ export type PageRuleReconcileScope = {
257
+ triggeredPageIds: ReadonlySet<string>;
258
+ includeImmediate: boolean;
259
+ };
260
+ export declare function collectPageDetectorRules(experiments: Experiment[]): Map<PageDetectorMode, PageTargetingRule[]>;
261
+ export declare function experimentsForGlobalRouteReevaluation(experiments: Experiment[]): Experiment[];
262
+ export declare function conditionUsesActivateTrigger(condition: SegmentCondition): boolean;
263
+ export declare function buildJsTriggerContext(condition: SegmentCondition): Record<string, unknown>;
264
+ export declare function runJsTriggerReset(condition: SegmentCondition): void;
265
+ export declare function normalizeActivationValue(next: unknown, hasArgument: boolean): boolean;
266
+ export declare function installActivateJsTrigger(condition: SegmentCondition, onChange: () => void): () => void;
267
+ export declare function installPageTriggerRule(rule: PageTargetingRule, onChange: () => void, manualInitialTrigger?: boolean): () => void;
268
+ export declare function installJsTriggerObserver(experiments: Experiment[], onChange: () => void, manualInitialTrigger: boolean): () => void;
269
+ export declare function notifyQaAssistantRuntimeListeners(): void;
270
+ export type HarnessManifest = {
271
+ version?: number;
272
+ expiresAt?: string;
273
+ externalJsUrl?: string | null;
274
+ externalCssUrl?: string | null;
275
+ manifestUrl?: string;
276
+ pollIntervalMs?: number;
277
+ };
278
+ export declare let harnessPollTimer: number | null;
279
+ export declare let harnessPollKey: string;
280
+ export declare let harnessVisibilityInstalled: boolean;
281
+ export declare function activeHarnessAssignment(assignments: Assignment[]): Assignment | null;
282
+ export declare function stopHarnessPolling(): void;
283
+ export declare function applyHarnessManifest(manifest: HarnessManifest): void;
284
+ export declare function pollHarnessManifest(manifestUrl: string): void;
285
+ export declare function startHarnessPolling(assignments: Assignment[]): void;
286
+ export declare function getEventsEndpoint(config: InitConfig): string | undefined;
287
+ export declare function mintBucketingHandoverPayload(config: InitConfig, visitorId: string, assignments: Assignment[]): Promise<string | null>;
288
+ export declare function verifyBucketingHandoverToken(config: InitConfig, token: string): Promise<unknown>;
289
+ export declare function clearScheduledAnalyticsStart(): void;
290
+ export declare function normalizeDataLayerTriggers(config: InitConfig): DataLayerTriggerSettings[];
291
+ export declare function applyDataLayerMappings(eventPayload: Record<string, unknown>, mappings: DataLayerSignalMapping[] | undefined): string[];
292
+ export declare function readNumericPath(payload: Record<string, unknown>, path: string | undefined): number | undefined;
293
+ export declare function readStringPath(payload: Record<string, unknown>, path: string | undefined): string | undefined;
294
+ export declare const RESERVED_DATA_LAYER_REVENUE_KEYS: Set<string>;
295
+ export type PendingDataLayerEvent = {
296
+ trigger: DataLayerTriggerSettings;
297
+ payload: Record<string, unknown>;
298
+ dataLayerName: string;
299
+ gtagNormalized: boolean;
300
+ rawItem: unknown;
301
+ };
302
+ export declare const MAX_PENDING_DATA_LAYER_EVENTS = 50;
303
+ export declare const pendingDataLayerEvents: PendingDataLayerEvent[];
304
+ export declare const processedDataLayerEntries: WeakSet<object>;
305
+ export declare function isDataLayerEntryObject(item: unknown): item is object;
306
+ export declare function markDataLayerEntryProcessed(item: unknown): void;
307
+ export declare function trackDataLayerRevenue(trigger: DataLayerTriggerSettings, payload: Record<string, unknown>): void;
308
+ export declare function trackDataLayerEvent(trigger: DataLayerTriggerSettings, payload: Record<string, unknown>): void;
309
+ export declare function enqueuePendingDataLayerEvent(event: PendingDataLayerEvent): void;
310
+ export declare function drainPendingDataLayerEvents(): void;
311
+ export declare function finishInitializingAssignments(): void;
312
+ export declare function handleDataLayerEvent(trigger: DataLayerTriggerSettings, payload: Record<string, unknown>, dataLayerName: string, rawItem: unknown, gtagNormalized?: boolean): void;
313
+ export declare function recordObserverError(source: "route" | "data_layer" | "dom", error: unknown): void;
@@ -0,0 +1,27 @@
1
+ export type SynchronousConsentInput = {
2
+ requireConsent?: boolean;
3
+ hasConsent?: boolean;
4
+ consentModeEnabled?: boolean;
5
+ configuredConsentGranted?: boolean | null;
6
+ consentCookieGranted: boolean;
7
+ respectDoNotTrack?: boolean;
8
+ doNotTrackValue?: string;
9
+ };
10
+ export type ConsentProvider = "custom" | "onetrust" | "usercentrics" | "cookiebot" | "ccm19" | "pandectes" | "cookiescript";
11
+ export declare function readPath(root: unknown, path?: string): unknown;
12
+ export declare function readConsentCookie(name: string): string;
13
+ /** The SDK's synchronous native-CMP readers, shared with the pre-SDK capture fragment. */
14
+ export declare function readConfiguredConsent(provider?: ConsentProvider, requiredGroup?: string, getter?: string): boolean | null;
15
+ export declare function readCookieScriptConsent(requiredGroup?: string): boolean | null;
16
+ export declare const CONSENT_REQUIRED = 1;
17
+ export declare const CONSENT_GRANTED = 2;
18
+ export declare const DNT_BLOCKED = 4;
19
+ export declare const STORAGE_ALLOWED = 8;
20
+ export declare function resolveSynchronousConsentGranted(input: SynchronousConsentInput & {
21
+ provider?: ConsentProvider;
22
+ }): boolean;
23
+ export declare function evaluateSynchronousConsentForProvider(input: SynchronousConsentInput & {
24
+ provider?: ConsentProvider;
25
+ }): number;
26
+ /** Pure synchronous consent/DNT bitmask shared by SDK init and the inline bootstrap. */
27
+ export declare function evaluateSynchronousConsent(input: SynchronousConsentInput): number;
@@ -1,5 +1,7 @@
1
- export declare function injectCss(css: string, experimentId: string, variationId: string): void;
2
- export declare function injectExperimentCss(css: string, experimentId: string): void;
1
+ export declare function injectCss(css: string, experimentId: string, variationId: string, ownerKeys?: readonly string[], artifactId?: string, epoch?: number): void;
2
+ export declare function injectExperimentCss(css: string, experimentId: string, ownerKeys?: readonly string[], artifactId?: string, epoch?: number): void;
3
3
  export declare function removeCss(experimentId: string, variationId: string): void;
4
- export declare function injectExternalCss(url: string, experimentId: string, variationId: string): Promise<void>;
4
+ export declare function injectExternalCss(url: string, experimentId: string, variationId: string, ownerKeys?: readonly string[], artifactId?: string, epoch?: number): Promise<void>;
5
+ export declare function removeCssForOwner(ownerKey: string, artifactId?: string): void;
6
+ export declare function addCssOwners(existingOwnerKeys: ReadonlySet<string>, ownerKeys: readonly string[], artifactId?: string): void;
5
7
  export declare function removeAllCss(): void;
@@ -0,0 +1,2 @@
1
+ import type { DebugSettings } from "./types";
2
+ export declare function loadDebugBuild(settings: DebugSettings | undefined, snippetUrl: string | undefined, onFallback?: () => void): boolean;
@@ -0,0 +1,31 @@
1
+ import type { PersistedAssignmentRecord } from "./assignment-store";
2
+ import type { Assignment, ExclusionGroupConfig, Experiment, Variation } from "./types";
3
+ export type StoredGroupSelection = {
4
+ experimentId: string;
5
+ epoch: number;
6
+ };
7
+ export interface DecideAssignmentsInput {
8
+ experiments: Experiment[];
9
+ visitorId: string;
10
+ storedAssignments?: Record<string, PersistedAssignmentRecord>;
11
+ storedGroupSelections?: Record<string, StoredGroupSelection>;
12
+ exclusionGroups?: ExclusionGroupConfig[];
13
+ holdout?: {
14
+ enabled?: boolean;
15
+ percentage?: number;
16
+ };
17
+ /** Supplied by the caller so the decision boundary never reads the clock. */
18
+ now: number;
19
+ /** Reserved for the Stage 2 bootstrap's already-targeted payload contract. */
20
+ url?: string;
21
+ }
22
+ export declare function buildAssignment(experiment: Experiment, variation: Variation, index: number, hashValue: string, url?: string): Assignment;
23
+ /** Worker bootstrap entrypoint after its literal status and weekday filters. */
24
+ export declare function decideVariationIdsPregated(input: DecideAssignmentsInput): Array<[string, string]>;
25
+ /** Compact projection of the same production bucketing decision for pre-paint handoff. */
26
+ export declare function decideVariationIds(input: DecideAssignmentsInput): Array<[string, string]>;
27
+ /**
28
+ * Pure assignment boundary for the SDK and the future inline bootstrap.
29
+ * The caller owns targeting, storage reads/writes, time, and exposure effects.
30
+ */
31
+ export declare function decideAssignments(input: DecideAssignmentsInput): Assignment[];
@@ -0,0 +1,8 @@
1
+ export type DeliveryTiming = {
2
+ snippet_fetch_ms: number;
3
+ snippet_transfer_size: number;
4
+ sdk_bundle_fetch_ms: number;
5
+ sdk_bundle_transfer_size: number;
6
+ time_to_sdk_ready_ms?: number;
7
+ };
8
+ export declare function collectDeliveryTiming(sdkInitStartedAt: number | undefined, sdkScriptSrc?: string): DeliveryTiming;
@@ -0,0 +1,79 @@
1
+ import type { Assignment, DataProtectionSettings, Experiment } from "./types";
2
+ export declare const EARLY_INTERACTION_STORAGE_KEY = "drip_early_interactions_v1";
3
+ export declare const EARLY_INTERACTION_TTL_MS: number;
4
+ type StorageMode = NonNullable<DataProtectionSettings["storageMode"]>;
5
+ export type EarlyInteractionEntry = {
6
+ goalId: string;
7
+ experimentId: string;
8
+ variationId: string;
9
+ assignmentEpoch: number;
10
+ kind: "click" | "submit";
11
+ data: Record<string, unknown>;
12
+ timestamp: number;
13
+ sessionId: string;
14
+ pageUrl: string;
15
+ configRevision: number;
16
+ };
17
+ type EarlyCaptureState = {
18
+ entries: EarlyInteractionEntry[];
19
+ stop: () => void;
20
+ storageMode: StorageMode;
21
+ };
22
+ declare global {
23
+ var __dripEarlyInteractions: EarlyCaptureState | undefined;
24
+ var __dripHasConsent: boolean | undefined;
25
+ var __dripInstallEarlyInteractionCapture: typeof installEarlyInteractionCapture | undefined;
26
+ var __dripPredecided: {
27
+ decision?: Array<[string, string]>;
28
+ } | undefined;
29
+ var __dripEarlyQ: Array<{
30
+ kind: "click" | "submit";
31
+ target: Element;
32
+ timestamp: number;
33
+ id: number;
34
+ pageUrl: string;
35
+ consentAllowed: boolean;
36
+ }> | undefined;
37
+ var __dripEarlyStop: (() => void) | undefined;
38
+ }
39
+ export declare function drainBootstrapEarlyInteractions(input: ConsentConfig & {
40
+ assignments: Assignment[];
41
+ experiments: Experiment[];
42
+ activePageIds?: ReadonlySet<string>;
43
+ qaMode?: boolean;
44
+ environment?: string;
45
+ now?: number;
46
+ consume: (goalId: string, assignment: Assignment, timestamp: number, kind: "click" | "submit", pageUrl: string) => void;
47
+ }): void;
48
+ export declare function clearEarlyInteractions(mode?: StorageMode): void;
49
+ type ConsentConfig = {
50
+ requireConsent?: boolean;
51
+ consentModeEnabled?: boolean;
52
+ consentProvider?: "custom" | "onetrust" | "usercentrics" | "cookiebot" | "ccm19" | "pandectes" | "cookiescript";
53
+ consentRequiredGroup?: string;
54
+ consentGetter?: string;
55
+ respectDoNotTrack?: boolean;
56
+ };
57
+ export type EarlyCaptureConfig = ConsentConfig & {
58
+ experiments: Experiment[];
59
+ assignments: Pick<Assignment, "experimentId" | "variationId" | "assignmentEpoch">[];
60
+ attributes?: Record<string, unknown>;
61
+ configRevision: number;
62
+ pageUrl: string;
63
+ storageMode?: StorageMode;
64
+ forcedExperimentIds?: string[];
65
+ now?: number;
66
+ };
67
+ export declare function installEarlyInteractionCapture(config: EarlyCaptureConfig): void;
68
+ export declare function drainEarlyInteractions(input: ConsentConfig & {
69
+ qaMode?: boolean;
70
+ environment?: string;
71
+ configRevision: number | undefined;
72
+ sessionId: string;
73
+ storageMode?: StorageMode;
74
+ experiments: Experiment[];
75
+ now?: number;
76
+ forcedExperimentIds?: string[];
77
+ consume: (entry: EarlyInteractionEntry) => void;
78
+ }): void;
79
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { Assignment } from "./types";
2
+ export type EarlyReassertDiagnostics = {
3
+ early_apply_at?: number;
4
+ reasserts_count?: number;
5
+ revert_loops_detected?: number;
6
+ };
7
+ export declare function assignmentsHaveStructuralMutations(assignments: Assignment[]): boolean;
8
+ export declare function assignmentsHaveCustomJs(assignments: Assignment[]): boolean;
9
+ export declare function shouldUseEarlyReassert(input: {
10
+ applyTiming?: string;
11
+ hasTrustedPredecision: boolean;
12
+ consentGranted: boolean;
13
+ dntBlocked: boolean;
14
+ configSource: string;
15
+ }): boolean;
16
+ /**
17
+ * Watches only treatment selectors and batches hydration repairs into the next
18
+ * animation frame. The observer is deliberately SDK-side: the inline decision
19
+ * bootstrap remains a small, synchronous decision-only artifact.
20
+ *
21
+ * The watcher never captures an assignment array. It resolves the live applied
22
+ * set through `resolveAssignments` at fire time, so a page teardown that drops
23
+ * the artifacts stops it by construction rather than through a
24
+ * `stopEarlyReassert()` call nobody makes.
25
+ */
26
+ export declare function installEarlyReassert(input: {
27
+ resolveAssignments: () => Assignment[];
28
+ reapply: (assignments: Assignment[]) => void;
29
+ diagnostics: EarlyReassertDiagnostics;
30
+ timeoutMs?: number;
31
+ cap?: number;
32
+ }): () => void;
@@ -0,0 +1,11 @@
1
+ export type EdgeRuntimeAssignment = {
2
+ experimentId: string;
3
+ variationId: string;
4
+ index: number;
5
+ };
6
+ export declare function edgeRuntimeActive(): boolean;
7
+ /**
8
+ * Reads the edge worker's authoritative assignment set.
9
+ * The adoption evaluator validates each selected variation and index.
10
+ */
11
+ export declare function readEdgeRuntimeAssignments(): Map<string, EdgeRuntimeAssignment> | null;
@@ -1,7 +1,9 @@
1
1
  import type { ActiveEditorSession, ClaimedEditorCommand, EditorArtifacts, EditorVariation } from "./types";
2
+ import { type VariationSaveOutcome } from "./publication-result";
2
3
  export declare class EditorApiError extends Error {
3
4
  readonly status: number;
4
5
  readonly payload?: (Record<string, unknown> | null) | undefined;
6
+ readonly outcome: VariationSaveOutcome | null;
5
7
  constructor(message: string, status: number, payload?: (Record<string, unknown> | null) | undefined);
6
8
  }
7
9
  type FetchLike = typeof fetch;
@@ -19,6 +21,7 @@ export declare class EditorApi {
19
21
  saveArtifacts(variationId: string, artifacts: EditorArtifacts, expectedPriorHash: string): Promise<{
20
22
  artifactHash: string;
21
23
  reviewStatus: string | null;
24
+ outcome: VariationSaveOutcome;
22
25
  warningIssues: Array<{
23
26
  code?: string;
24
27
  message?: string;
@@ -34,6 +34,7 @@ export declare class EditorController {
34
34
  readonly apiOrigin: string;
35
35
  private readonly api;
36
36
  private readonly reload;
37
+ private readonly confirmLiveSave;
37
38
  private state;
38
39
  private readonly listeners;
39
40
  private readonly history;
@@ -43,8 +44,9 @@ export declare class EditorController {
43
44
  private saveQueue;
44
45
  private revision;
45
46
  private variationRequest;
47
+ private liveSaveConfirmed;
46
48
  private readonly cleanups;
47
- constructor(session: ActiveEditorSession, apiOrigin: string, api?: EditorApi, reload?: () => void);
49
+ constructor(session: ActiveEditorSession, apiOrigin: string, api?: EditorApi, reload?: () => void, confirmLiveSave?: (message: string) => boolean);
48
50
  getState(): EditorState;
49
51
  subscribe(listener: (state: EditorState) => void): () => void;
50
52
  initialize(): Promise<void>;
@@ -0,0 +1,11 @@
1
+ export type PublicationStatus = "ok" | "pending" | "warning" | "failed";
2
+ export type VariationSaveOutcome = {
3
+ saved: boolean;
4
+ artifactHash: string | null;
5
+ publication: {
6
+ status: PublicationStatus;
7
+ code: string;
8
+ message: string;
9
+ } | null;
10
+ };
11
+ export declare function parseVariationSaveOutcome(value: unknown): VariationSaveOutcome | null;
@@ -6,6 +6,7 @@ export type ActiveEditorSession = {
6
6
  shopId: string;
7
7
  experimentId: string;
8
8
  experimentName?: string | null;
9
+ experimentStatus?: string | null;
9
10
  initialVariationId: string;
10
11
  targetUrl: string;
11
12
  targetOrigin: string;
@@ -33,7 +34,7 @@ export type ClaimedEditorCommand = {
33
34
  args: Record<string, unknown>;
34
35
  expiresAt: string | null;
35
36
  };
36
- export type EditorSaveState = "idle" | "saving" | "saved" | "conflict" | "error";
37
+ export type EditorSaveState = "idle" | "saving" | "saved" | "pending" | "warning" | "publication_failed" | "conflict" | "error";
37
38
  export type EditorDeviceState = "closed" | "loading" | "active" | "blocked";
38
39
  export type EditorState = {
39
40
  variation: EditorVariation | null;
@@ -30,4 +30,4 @@ export type IconName = keyof typeof ICONS;
30
30
  export declare function icon(name: IconName, size?: number, extra?: string): string;
31
31
  export declare function operatorMark(size?: number, color?: string): string;
32
32
  export declare function esc(value: string): string;
33
- export declare const KIT_CSS = "\n:host {\n --bg0:#08080A;--bg1:#0A0A0C;--raised:#141419;--raised-hi:#1A1A21;--inset:#0B0B0E;\n --border:rgba(255,255,255,0.06);--border-hi:rgba(255,255,255,0.10);--border-px:rgba(255,255,255,0.14);\n --text1:#FAFAFA;--text2:rgba(255,255,255,0.66);--text3:rgba(255,255,255,0.42);--text4:rgba(255,255,255,0.26);\n --purple500:#5B29FF;--purple400:#7C54FF;--purple300:#9B6FFF;--purple200:#C8B4FF;\n --purple-soft:rgba(91,41,255,0.14);--purple-bd:rgba(124,84,255,0.34);\n --positive:#3DD68C;--warning:#FACC15;--negative:#EB5252;--negative-soft:#F39797;\n all:initial;font-family:Inter,system-ui,sans-serif;color:var(--text1);letter-spacing:0;\n position:fixed;inset:0;z-index:2147483647;pointer-events:none;font-size:12.5px;line-height:1.5;\n}\n*{box-sizing:border-box;letter-spacing:0;margin:0;padding:0}\nbutton,input,select,textarea{font:inherit;color:inherit;font-family:inherit}\nbutton{cursor:pointer;background:none;border:none}\nbutton:disabled{cursor:not-allowed}\n:is(button,textarea,input,a):focus-visible{outline:2px solid var(--purple400);outline-offset:2px}\n@keyframes ee-spin{to{transform:rotate(360deg)}}\n@keyframes ee-pulse{0%{transform:scale(0.7);opacity:0.9}100%{transform:scale(1.6);opacity:0}}\n@keyframes ee-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}\n.ee-in{animation:ee-in 160ms ease-out}\n.spin{animation:ee-spin 1s linear infinite}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:0.01ms!important;animation-iteration-count:1!important;transition-duration:0.01ms!important}}\n\n/* Buttons */\n.btn{display:inline-flex;align-items:center;gap:7px;justify-content:center;padding:7px 12px;font-size:13px;font-weight:550;border-radius:8px;border:1px solid transparent;line-height:1.2;white-space:nowrap;transition:background 120ms,border-color 120ms,color 120ms;pointer-events:auto}\n.btn.sm{padding:5px 10px;font-size:12px}\n.btn:disabled{opacity:0.45}\n.btn.primary{background:var(--purple500);color:#fff;border-color:rgba(255,255,255,0.14)}\n.btn.soft{background:var(--purple-soft);color:var(--purple200);border-color:var(--purple-bd)}\n.btn.ghost{background:transparent;color:var(--text2);border-color:var(--border)}\n.btn.ghost:hover{background:var(--raised-hi);color:var(--text1)}\n.btn.bare{background:transparent;color:var(--text2);border-color:transparent}\n.btn.danger{background:rgba(235,82,82,0.14);color:var(--negative-soft);border-color:rgba(235,82,82,0.3)}\n.iconbtn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:8px;border:1px solid transparent;background:transparent;color:var(--text2);flex-shrink:0;transition:background 120ms,color 120ms;pointer-events:auto}\n.iconbtn:hover{background:var(--raised-hi);color:var(--text1)}\n.iconbtn.active{background:var(--purple-soft);color:var(--purple200);border-color:var(--purple-bd)}\n.iconbtn:disabled{opacity:0.4}\n.iconbtn.xs{width:22px;height:22px}\n\n/* Status dot */\n.dot{position:relative;width:7px;height:7px;flex-shrink:0;display:inline-block}\n.dot i{position:absolute;inset:0;border-radius:50%}\n.dot.ok i{background:var(--positive)}.dot.warn i{background:var(--warning)}.dot.err i{background:var(--negative)}.dot.purple i{background:var(--purple300)}\n.dot b{position:absolute;inset:-3px;border-radius:50%;border:1px solid currentColor}\n.dot.ok b{color:var(--positive)}.dot.warn b{color:var(--warning)}.dot.err b{color:var(--negative)}.dot.purple b{color:var(--purple300)}\n.dot b{animation:ee-pulse 1.4s ease-out infinite}\n\n/* Save chip */\n.save-chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:550;padding:4px 9px;border-radius:7px;background:rgba(255,255,255,0.04);border:1px solid var(--border);white-space:nowrap}\n.save-chip.unsaved{color:var(--warning)}\n.save-chip.saving{color:var(--purple200)}\n.save-chip.saved{color:var(--positive)}\n.save-chip.failed,.save-chip.conflict{color:var(--negative-soft);background:rgba(235,82,82,0.10);border-color:rgba(235,82,82,0.25)}\n.save-chip .retry{border:none;background:rgba(255,255,255,0.1);color:#fff;font-size:11.5px;font-weight:600;border-radius:5px;padding:2px 7px;margin-left:2px;pointer-events:auto}\n\n/* Segmented control */\n.seg{display:inline-flex;background:var(--inset);border-radius:8px;padding:2px;gap:2px;border:1px solid var(--border);pointer-events:auto}\n.seg button{display:inline-flex;align-items:center;gap:6px;justify-content:center;padding:5px 11px;border-radius:6px;border:none;background:transparent;color:var(--text3);font-size:12px;font-weight:550;transition:background 120ms,color 120ms}\n.seg button.sm{padding:4px 8px}\n.seg button[aria-checked=\"true\"]{background:var(--raised-hi);color:var(--text1);box-shadow:inset 0 0 0 1px var(--border-px)}\n\n/* Pills & chips */\n.draft-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:999px;background:rgba(250,204,21,0.10);border:1px solid rgba(250,204,21,0.3);font-size:11px;font-weight:600;color:var(--warning);white-space:nowrap}\n.session-chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:550;color:var(--warning);padding:4px 9px;border-radius:7px;border:1px solid rgba(250,204,21,0.35);background:rgba(250,204,21,0.08);white-space:nowrap;font-variant-numeric:tabular-nums}\n.session-chip .extend{border:none;background:rgba(250,204,21,0.16);color:var(--warning);font-size:11.5px;font-weight:600;border-radius:5px;padding:2px 7px;pointer-events:auto}\n.session-note{font-size:11px;color:var(--text4);white-space:nowrap}\n.conn-chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:550;white-space:nowrap;color:var(--text3)}\n.conn-chip.offline{color:var(--negative-soft)}\n.conn-chip.connecting{color:var(--warning)}\n.ctx-chip{display:inline-flex;align-items:center;gap:7px;max-width:100%;background:var(--purple-soft);border:1px solid var(--purple-bd);border-radius:8px;padding:5px 8px;font-size:11.5px;color:var(--purple200);font-weight:550}\n.ctx-chip .name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ctx-chip .replace{border:none;background:rgba(255,255,255,0.08);color:var(--text2);font-size:10.5px;font-weight:600;border-radius:5px;padding:2px 7px;pointer-events:auto}\n.ctx-chip .clear{border:none;background:none;color:var(--text3);padding:2px;display:inline-flex;pointer-events:auto}\n\n/* Fields */\n.field{width:100%;background:var(--inset);color:var(--text1);border:1px solid var(--border-hi);border-radius:8px;padding:8px 10px;font-size:12.5px;line-height:1.5;outline:none;resize:vertical;pointer-events:auto}\n.field::placeholder{color:rgba(255,255,255,0.28)}\n.field.code{white-space:pre;font-variant-numeric:tabular-nums;min-height:150px}\n.flabel{display:block;font-size:11.5px;font-weight:550;color:var(--text3);margin-bottom:5px}\n.fhint{display:block;font-size:11px;color:var(--text4);margin-top:4px}\n\n/* Banners */\n.banner{display:flex;align-items:center;gap:9px;padding:8px 12px;border-radius:10px;color:var(--text1);font-size:12.5px;box-shadow:0 12px 32px rgba(0,0,0,0.4);pointer-events:auto;max-width:560px}\n.banner .body{flex:1;min-width:0}\n.banner.info{background:linear-gradient(0deg,rgba(91,41,255,0.16),rgba(91,41,255,0.16)),var(--bg1);border:1px solid var(--purple-bd)}\n.banner.info svg{color:var(--purple200)}\n.banner.warn{background:linear-gradient(0deg,rgba(250,204,21,0.10),rgba(250,204,21,0.10)),var(--bg1);border:1px solid rgba(250,204,21,0.35)}\n.banner.warn svg{color:var(--warning)}\n.banner.error{background:linear-gradient(0deg,rgba(235,82,82,0.12),rgba(235,82,82,0.12)),var(--bg1);border:1px solid rgba(235,82,82,0.35)}\n.banner.error svg{color:var(--negative-soft)}\n\n/* Modal */\n.modal-backdrop{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center;background:rgba(5,5,8,0.55);backdrop-filter:blur(3px);pointer-events:auto}\n.modal{width:430px;max-width:calc(100vw - 40px);background:var(--bg1);border:1px solid var(--border-px);border-radius:14px;box-shadow:0 32px 80px rgba(0,0,0,0.55);overflow:hidden;color:var(--text1)}\n.modal .m-head{display:flex;gap:10px;align-items:flex-start;padding:18px 18px 0}\n.modal .m-icon{width:30px;height:30px;border-radius:8px;background:rgba(255,255,255,0.05);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.modal .m-icon.warn{color:var(--warning)}.modal .m-icon.purple{color:var(--purple300)}.modal .m-icon.ok{color:var(--positive)}\n.modal .m-title{font-size:15px;font-weight:600;letter-spacing:-0.015em;padding-top:4px}\n.modal .m-body{padding:12px 18px 4px;font-size:13px;line-height:1.6;color:var(--text2)}\n.modal .m-body p{margin:0}\n.modal .m-body p+p{margin-top:10px}\n.modal .m-actions{display:flex;justify-content:flex-end;gap:8px;padding:14px 18px 18px}\n";
33
+ export declare const KIT_CSS = "\n:host {\n --bg0:#08080A;--bg1:#0A0A0C;--raised:#141419;--raised-hi:#1A1A21;--inset:#0B0B0E;\n --border:rgba(255,255,255,0.06);--border-hi:rgba(255,255,255,0.10);--border-px:rgba(255,255,255,0.14);\n --text1:#FAFAFA;--text2:rgba(255,255,255,0.66);--text3:rgba(255,255,255,0.42);--text4:rgba(255,255,255,0.26);\n --purple500:#5B29FF;--purple400:#7C54FF;--purple300:#9B6FFF;--purple200:#C8B4FF;\n --purple-soft:rgba(91,41,255,0.14);--purple-bd:rgba(124,84,255,0.34);\n --positive:#3DD68C;--warning:#FACC15;--negative:#EB5252;--negative-soft:#F39797;\n all:initial;font-family:Inter,system-ui,sans-serif;color:var(--text1);letter-spacing:0;\n position:fixed;inset:0;z-index:2147483647;pointer-events:none;font-size:12.5px;line-height:1.5;\n}\n*{box-sizing:border-box;letter-spacing:0;margin:0;padding:0}\nbutton,input,select,textarea{font:inherit;color:inherit;font-family:inherit}\nbutton{cursor:pointer;background:none;border:none}\nbutton:disabled{cursor:not-allowed}\n:is(button,textarea,input,a):focus-visible{outline:2px solid var(--purple400);outline-offset:2px}\n@keyframes ee-spin{to{transform:rotate(360deg)}}\n@keyframes ee-pulse{0%{transform:scale(0.7);opacity:0.9}100%{transform:scale(1.6);opacity:0}}\n@keyframes ee-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}\n.ee-in{animation:ee-in 160ms ease-out}\n.spin{animation:ee-spin 1s linear infinite}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:0.01ms!important;animation-iteration-count:1!important;transition-duration:0.01ms!important}}\n\n/* Buttons */\n.btn{display:inline-flex;align-items:center;gap:7px;justify-content:center;padding:7px 12px;font-size:13px;font-weight:550;border-radius:8px;border:1px solid transparent;line-height:1.2;white-space:nowrap;transition:background 120ms,border-color 120ms,color 120ms;pointer-events:auto}\n.btn.sm{padding:5px 10px;font-size:12px}\n.btn:disabled{opacity:0.45}\n.btn.primary{background:var(--purple500);color:#fff;border-color:rgba(255,255,255,0.14)}\n.btn.soft{background:var(--purple-soft);color:var(--purple200);border-color:var(--purple-bd)}\n.btn.ghost{background:transparent;color:var(--text2);border-color:var(--border)}\n.btn.ghost:hover{background:var(--raised-hi);color:var(--text1)}\n.btn.bare{background:transparent;color:var(--text2);border-color:transparent}\n.btn.danger{background:rgba(235,82,82,0.14);color:var(--negative-soft);border-color:rgba(235,82,82,0.3)}\n.iconbtn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:8px;border:1px solid transparent;background:transparent;color:var(--text2);flex-shrink:0;transition:background 120ms,color 120ms;pointer-events:auto}\n.iconbtn:hover{background:var(--raised-hi);color:var(--text1)}\n.iconbtn.active{background:var(--purple-soft);color:var(--purple200);border-color:var(--purple-bd)}\n.iconbtn:disabled{opacity:0.4}\n.iconbtn.xs{width:22px;height:22px}\n\n/* Status dot */\n.dot{position:relative;width:7px;height:7px;flex-shrink:0;display:inline-block}\n.dot i{position:absolute;inset:0;border-radius:50%}\n.dot.ok i{background:var(--positive)}.dot.warn i{background:var(--warning)}.dot.err i{background:var(--negative)}.dot.purple i{background:var(--purple300)}\n.dot b{position:absolute;inset:-3px;border-radius:50%;border:1px solid currentColor}\n.dot.ok b{color:var(--positive)}.dot.warn b{color:var(--warning)}.dot.err b{color:var(--negative)}.dot.purple b{color:var(--purple300)}\n.dot b{animation:ee-pulse 1.4s ease-out infinite}\n\n/* Save chip */\n.save-chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:550;padding:4px 9px;border-radius:7px;background:rgba(255,255,255,0.04);border:1px solid var(--border);white-space:nowrap}\n.save-chip.unsaved{color:var(--warning)}\n.save-chip.saving{color:var(--purple200)}\n.save-chip.saved{color:var(--positive)}\n.save-chip.pending,.save-chip.warning{color:var(--warning);background:rgba(245,166,35,0.10);border-color:rgba(245,166,35,0.25)}\n.save-chip.failed,.save-chip.publication-failed,.save-chip.conflict{color:var(--negative-soft);background:rgba(235,82,82,0.10);border-color:rgba(235,82,82,0.25)}\n.save-chip .retry{border:none;background:rgba(255,255,255,0.1);color:#fff;font-size:11.5px;font-weight:600;border-radius:5px;padding:2px 7px;margin-left:2px;pointer-events:auto}\n\n/* Segmented control */\n.seg{display:inline-flex;background:var(--inset);border-radius:8px;padding:2px;gap:2px;border:1px solid var(--border);pointer-events:auto}\n.seg button{display:inline-flex;align-items:center;gap:6px;justify-content:center;padding:5px 11px;border-radius:6px;border:none;background:transparent;color:var(--text3);font-size:12px;font-weight:550;transition:background 120ms,color 120ms}\n.seg button.sm{padding:4px 8px}\n.seg button[aria-checked=\"true\"]{background:var(--raised-hi);color:var(--text1);box-shadow:inset 0 0 0 1px var(--border-px)}\n\n/* Pills & chips */\n.draft-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:999px;background:rgba(250,204,21,0.10);border:1px solid rgba(250,204,21,0.3);font-size:11px;font-weight:600;color:var(--warning);white-space:nowrap}\n.session-chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:550;color:var(--warning);padding:4px 9px;border-radius:7px;border:1px solid rgba(250,204,21,0.35);background:rgba(250,204,21,0.08);white-space:nowrap;font-variant-numeric:tabular-nums}\n.session-chip .extend{border:none;background:rgba(250,204,21,0.16);color:var(--warning);font-size:11.5px;font-weight:600;border-radius:5px;padding:2px 7px;pointer-events:auto}\n.session-note{font-size:11px;color:var(--text4);white-space:nowrap}\n.conn-chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:550;white-space:nowrap;color:var(--text3)}\n.conn-chip.offline{color:var(--negative-soft)}\n.conn-chip.connecting{color:var(--warning)}\n.ctx-chip{display:inline-flex;align-items:center;gap:7px;max-width:100%;background:var(--purple-soft);border:1px solid var(--purple-bd);border-radius:8px;padding:5px 8px;font-size:11.5px;color:var(--purple200);font-weight:550}\n.ctx-chip .name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ctx-chip .replace{border:none;background:rgba(255,255,255,0.08);color:var(--text2);font-size:10.5px;font-weight:600;border-radius:5px;padding:2px 7px;pointer-events:auto}\n.ctx-chip .clear{border:none;background:none;color:var(--text3);padding:2px;display:inline-flex;pointer-events:auto}\n\n/* Fields */\n.field{width:100%;background:var(--inset);color:var(--text1);border:1px solid var(--border-hi);border-radius:8px;padding:8px 10px;font-size:12.5px;line-height:1.5;outline:none;resize:vertical;pointer-events:auto}\n.field::placeholder{color:rgba(255,255,255,0.28)}\n.field.code{white-space:pre;font-variant-numeric:tabular-nums;min-height:150px}\n.flabel{display:block;font-size:11.5px;font-weight:550;color:var(--text3);margin-bottom:5px}\n.fhint{display:block;font-size:11px;color:var(--text4);margin-top:4px}\n\n/* Banners */\n.banner{display:flex;align-items:center;gap:9px;padding:8px 12px;border-radius:10px;color:var(--text1);font-size:12.5px;box-shadow:0 12px 32px rgba(0,0,0,0.4);pointer-events:auto;max-width:560px}\n.banner .body{flex:1;min-width:0}\n.banner.info{background:linear-gradient(0deg,rgba(91,41,255,0.16),rgba(91,41,255,0.16)),var(--bg1);border:1px solid var(--purple-bd)}\n.banner.info svg{color:var(--purple200)}\n.banner.warn{background:linear-gradient(0deg,rgba(250,204,21,0.10),rgba(250,204,21,0.10)),var(--bg1);border:1px solid rgba(250,204,21,0.35)}\n.banner.warn svg{color:var(--warning)}\n.banner.error{background:linear-gradient(0deg,rgba(235,82,82,0.12),rgba(235,82,82,0.12)),var(--bg1);border:1px solid rgba(235,82,82,0.35)}\n.banner.error svg{color:var(--negative-soft)}\n\n/* Modal */\n.modal-backdrop{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center;background:rgba(5,5,8,0.55);backdrop-filter:blur(3px);pointer-events:auto}\n.modal{width:430px;max-width:calc(100vw - 40px);background:var(--bg1);border:1px solid var(--border-px);border-radius:14px;box-shadow:0 32px 80px rgba(0,0,0,0.55);overflow:hidden;color:var(--text1)}\n.modal .m-head{display:flex;gap:10px;align-items:flex-start;padding:18px 18px 0}\n.modal .m-icon{width:30px;height:30px;border-radius:8px;background:rgba(255,255,255,0.05);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.modal .m-icon.warn{color:var(--warning)}.modal .m-icon.purple{color:var(--purple300)}.modal .m-icon.ok{color:var(--positive)}\n.modal .m-title{font-size:15px;font-weight:600;letter-spacing:-0.015em;padding-top:4px}\n.modal .m-body{padding:12px 18px 4px;font-size:13px;line-height:1.6;color:var(--text2)}\n.modal .m-body p{margin:0}\n.modal .m-body p+p{margin-top:10px}\n.modal .m-actions{display:flex;justify-content:flex-end;gap:8px;padding:14px 18px 18px}\n";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Normalize an SDK endpoint: strip trailing slashes and a trailing events path
3
+ * so configured bare, /events, and /v1/events endpoints resolve to the base.
4
+ * Single chokepoint — every SDK helper that derives a sibling route from
5
+ * config.endpoint must go through this (events, handover, order-identity,
6
+ * replay, shopify cart authorization).
7
+ */
8
+ export declare function normalizeEndpoint(endpoint: string): string;