@coframe/sdk 1.1.9 → 1.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/README.md +22 -0
- package/dist/pkg/cf.cjs.js +7 -0
- package/dist/pkg/cf.esm.mjs +7 -0
- package/dist/pkg/react.cjs.js +9 -1
- package/dist/pkg/react.esm.mjs +10 -2
- package/dist/pkg/server.cjs.js +11 -4
- package/dist/pkg/server.esm.mjs +11 -4
- package/dist/pkg/types/index.d.ts +3 -1
- package/dist/pkg/types/react.d.ts +4 -2
- package/dist/pkg/types/server.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,21 @@ await init({
|
|
|
40
40
|
|
|
41
41
|
`init()` accepts `config` and optional `projectData`, so npm consumers do not need to manually populate `window.CFQ` first.
|
|
42
42
|
|
|
43
|
+
### URL controls
|
|
44
|
+
|
|
45
|
+
The npm entry uses the same browser URL controls as the script-tag and Edge
|
|
46
|
+
installations:
|
|
47
|
+
|
|
48
|
+
- `cf_disable` skips initialization and reveals any antiflicker state.
|
|
49
|
+
- `coframe_variant_id` previews one or more comma-separated variant IDs.
|
|
50
|
+
- `keep_preview_for_session=true` keeps that preview active for the tab.
|
|
51
|
+
- `coframe_should_send_events=true` allows events during preview for testing.
|
|
52
|
+
|
|
53
|
+
For SSR, pass the complete request URL, including its query string, as
|
|
54
|
+
`currentUrl`. This is required for query-sensitive targeting and allows
|
|
55
|
+
`getProjectData()` to short-circuit before any request when `cf_disable` is
|
|
56
|
+
present.
|
|
57
|
+
|
|
43
58
|
### React
|
|
44
59
|
|
|
45
60
|
```tsx
|
|
@@ -60,6 +75,8 @@ export default function App({ children }) {
|
|
|
60
75
|
```
|
|
61
76
|
|
|
62
77
|
Mount the provider once at the root of your app. It initializes the SDK on mount and keeps treatment state available to child components.
|
|
78
|
+
Keep it mounted across client-side route changes; runtime commands and the SDK's
|
|
79
|
+
navigation observer handle subsequent page changes without remounting it.
|
|
63
80
|
|
|
64
81
|
### Server prefetch
|
|
65
82
|
|
|
@@ -148,6 +165,10 @@ import { CoframeProvider } from '@coframe/sdk/react'
|
|
|
148
165
|
</CoframeProvider>
|
|
149
166
|
```
|
|
150
167
|
|
|
168
|
+
If your privacy policy permits treatment analytics before cookie consent, use
|
|
169
|
+
`onTreatmentAppliedBulkV2WithoutConsent` instead. It has the same callback
|
|
170
|
+
arguments and does not fire again when consent is later granted.
|
|
171
|
+
|
|
151
172
|
Outside React, you can also register callbacks from the main entry:
|
|
152
173
|
|
|
153
174
|
```ts
|
|
@@ -159,6 +180,7 @@ import { onLog, onTreatmentApplied } from '@coframe/sdk'
|
|
|
159
180
|
- `getProjectData()` is intended for SSR and edge runtimes that can provide a full request URL and request headers.
|
|
160
181
|
- In Pages Router or Remix, per-request server loaders are the most straightforward place to call it.
|
|
161
182
|
- In App Router, keep the provider mounted in a persistent shell, but be careful about request URL handling in `layout.tsx` if you need query-sensitive SSR targeting.
|
|
183
|
+
- The npm runtime reveals antiflicker styles but cannot insert them early enough to protect the initial paint. Render `antiflickerCSS` from `getProjectData()` in the server document head, or place equivalent static CSS and a timeout fallback there before application content.
|
|
162
184
|
|
|
163
185
|
## Package layout
|
|
164
186
|
|
package/dist/pkg/cf.cjs.js
CHANGED
|
@@ -1823,6 +1823,7 @@ const waitForBody = (timeout = 10000) => {
|
|
|
1823
1823
|
function revealPage() {
|
|
1824
1824
|
document.dispatchEvent(new CustomEvent('coframe:show', {}));
|
|
1825
1825
|
document.documentElement.style.setProperty('--cf-show', '1');
|
|
1826
|
+
document.documentElement.style.setProperty('--cf-visibility', 'visible');
|
|
1826
1827
|
}
|
|
1827
1828
|
async function replaceVariants(variants, orgId, logger, nonce) {
|
|
1828
1829
|
const failedReplacements = [];
|
|
@@ -3646,6 +3647,12 @@ const Coframe = {
|
|
|
3646
3647
|
};
|
|
3647
3648
|
Coframe.logger = createLogger(() => Coframe);
|
|
3648
3649
|
async function init(options) {
|
|
3650
|
+
if (typeof window !== 'undefined' &&
|
|
3651
|
+
/cf_disable/.test(window.location.search)) {
|
|
3652
|
+
console.warn('[Coframe] Disabled via URL parameter');
|
|
3653
|
+
revealPage();
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3649
3656
|
if (options)
|
|
3650
3657
|
injectOptions(options);
|
|
3651
3658
|
const gracefulExit = (msg) => {
|
package/dist/pkg/cf.esm.mjs
CHANGED
|
@@ -1821,6 +1821,7 @@ const waitForBody = (timeout = 10000) => {
|
|
|
1821
1821
|
function revealPage() {
|
|
1822
1822
|
document.dispatchEvent(new CustomEvent('coframe:show', {}));
|
|
1823
1823
|
document.documentElement.style.setProperty('--cf-show', '1');
|
|
1824
|
+
document.documentElement.style.setProperty('--cf-visibility', 'visible');
|
|
1824
1825
|
}
|
|
1825
1826
|
async function replaceVariants(variants, orgId, logger, nonce) {
|
|
1826
1827
|
const failedReplacements = [];
|
|
@@ -3644,6 +3645,12 @@ const Coframe = {
|
|
|
3644
3645
|
};
|
|
3645
3646
|
Coframe.logger = createLogger(() => Coframe);
|
|
3646
3647
|
async function init(options) {
|
|
3648
|
+
if (typeof window !== 'undefined' &&
|
|
3649
|
+
/cf_disable/.test(window.location.search)) {
|
|
3650
|
+
console.warn('[Coframe] Disabled via URL parameter');
|
|
3651
|
+
revealPage();
|
|
3652
|
+
return;
|
|
3653
|
+
}
|
|
3647
3654
|
if (options)
|
|
3648
3655
|
injectOptions(options);
|
|
3649
3656
|
const gracefulExit = (msg) => {
|
package/dist/pkg/react.cjs.js
CHANGED
|
@@ -5,10 +5,17 @@ var sdk = require('@coframe/sdk');
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
|
|
7
7
|
const CoframeContext = React.createContext({ treatments: null });
|
|
8
|
-
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onLog: onLogProp, children, }) {
|
|
8
|
+
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onTreatmentAppliedBulkV2WithoutConsent, onLog: onLogProp, children, }) {
|
|
9
9
|
const [treatments, setTreatments] = React.useState(null);
|
|
10
10
|
React.useEffect(() => {
|
|
11
11
|
var _a, _b;
|
|
12
|
+
if (/cf_disable/.test(window.location.search)) {
|
|
13
|
+
sdk.init().catch((e) => {
|
|
14
|
+
console.error('[Coframe] Error disabling SDK', e);
|
|
15
|
+
});
|
|
16
|
+
setTreatments([]);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
12
19
|
sdk.onTreatmentApplied({
|
|
13
20
|
callback: onTreatmentAppliedProp,
|
|
14
21
|
bulkCallback: (data) => {
|
|
@@ -16,6 +23,7 @@ function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTre
|
|
|
16
23
|
onTreatmentAppliedBulkProp === null || onTreatmentAppliedBulkProp === void 0 ? void 0 : onTreatmentAppliedBulkProp(data);
|
|
17
24
|
},
|
|
18
25
|
bulkCallbackV2: onTreatmentAppliedBulkV2,
|
|
26
|
+
bulkCallbackV2WithoutConsent: onTreatmentAppliedBulkV2WithoutConsent,
|
|
19
27
|
});
|
|
20
28
|
if (onLogProp) {
|
|
21
29
|
sdk.onLog(onLogProp);
|
package/dist/pkg/react.esm.mjs
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { onTreatmentApplied, onLog
|
|
2
|
+
import { init, onTreatmentApplied, onLog } from '@coframe/sdk';
|
|
3
3
|
export { init, onLog, onTreatmentApplied, setConsent, setFeatureFlag, setPageHydrated, setUserToken, trackConversion } from '@coframe/sdk';
|
|
4
4
|
import React, { createContext, useState, useEffect, useContext } from 'react';
|
|
5
5
|
|
|
6
6
|
const CoframeContext = createContext({ treatments: null });
|
|
7
|
-
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onLog: onLogProp, children, }) {
|
|
7
|
+
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onTreatmentAppliedBulkV2WithoutConsent, onLog: onLogProp, children, }) {
|
|
8
8
|
const [treatments, setTreatments] = useState(null);
|
|
9
9
|
useEffect(() => {
|
|
10
10
|
var _a, _b;
|
|
11
|
+
if (/cf_disable/.test(window.location.search)) {
|
|
12
|
+
init().catch((e) => {
|
|
13
|
+
console.error('[Coframe] Error disabling SDK', e);
|
|
14
|
+
});
|
|
15
|
+
setTreatments([]);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
11
18
|
onTreatmentApplied({
|
|
12
19
|
callback: onTreatmentAppliedProp,
|
|
13
20
|
bulkCallback: (data) => {
|
|
@@ -15,6 +22,7 @@ function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTre
|
|
|
15
22
|
onTreatmentAppliedBulkProp === null || onTreatmentAppliedBulkProp === void 0 ? void 0 : onTreatmentAppliedBulkProp(data);
|
|
16
23
|
},
|
|
17
24
|
bulkCallbackV2: onTreatmentAppliedBulkV2,
|
|
25
|
+
bulkCallbackV2WithoutConsent: onTreatmentAppliedBulkV2WithoutConsent,
|
|
18
26
|
});
|
|
19
27
|
if (onLogProp) {
|
|
20
28
|
onLog(onLogProp);
|
package/dist/pkg/server.cjs.js
CHANGED
|
@@ -45,14 +45,14 @@ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext,
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext,
|
|
48
|
+
async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, antiflickerMode, headers) {
|
|
49
49
|
try {
|
|
50
50
|
const payload = { projectId, currentUrl };
|
|
51
51
|
if (userContext) {
|
|
52
52
|
payload.userContext = userContext;
|
|
53
53
|
}
|
|
54
|
-
if (
|
|
55
|
-
payload.
|
|
54
|
+
if (antiflickerMode) {
|
|
55
|
+
payload.antiflickerMode = antiflickerMode;
|
|
56
56
|
}
|
|
57
57
|
const config = encodeURIComponent(JSON.stringify(payload));
|
|
58
58
|
const edgeUrl = new URL(`${"https://edge.cofra.me"}/cf.css`);
|
|
@@ -69,6 +69,13 @@ async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, enab
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
async function getProjectData(options) {
|
|
72
|
+
try {
|
|
73
|
+
if (/cf_disable/.test(new URL(options.currentUrl).search)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (_a) {
|
|
78
|
+
}
|
|
72
79
|
const includeProject = options.includeProject !== false;
|
|
73
80
|
const includeCSS = options.includeCSS !== false;
|
|
74
81
|
const [projectResult, antiflickerCSS] = await Promise.all([
|
|
@@ -76,7 +83,7 @@ async function getProjectData(options) {
|
|
|
76
83
|
? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, undefined, options.headers)
|
|
77
84
|
: Promise.resolve(null),
|
|
78
85
|
includeCSS
|
|
79
|
-
? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.
|
|
86
|
+
? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.antiflickerMode, options.headers)
|
|
80
87
|
: Promise.resolve(null),
|
|
81
88
|
]);
|
|
82
89
|
const config = {};
|
package/dist/pkg/server.esm.mjs
CHANGED
|
@@ -43,14 +43,14 @@ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext,
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext,
|
|
46
|
+
async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, antiflickerMode, headers) {
|
|
47
47
|
try {
|
|
48
48
|
const payload = { projectId, currentUrl };
|
|
49
49
|
if (userContext) {
|
|
50
50
|
payload.userContext = userContext;
|
|
51
51
|
}
|
|
52
|
-
if (
|
|
53
|
-
payload.
|
|
52
|
+
if (antiflickerMode) {
|
|
53
|
+
payload.antiflickerMode = antiflickerMode;
|
|
54
54
|
}
|
|
55
55
|
const config = encodeURIComponent(JSON.stringify(payload));
|
|
56
56
|
const edgeUrl = new URL(`${"https://edge.cofra.me"}/cf.css`);
|
|
@@ -67,6 +67,13 @@ async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, enab
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
async function getProjectData(options) {
|
|
70
|
+
try {
|
|
71
|
+
if (/cf_disable/.test(new URL(options.currentUrl).search)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (_a) {
|
|
76
|
+
}
|
|
70
77
|
const includeProject = options.includeProject !== false;
|
|
71
78
|
const includeCSS = options.includeCSS !== false;
|
|
72
79
|
const [projectResult, antiflickerCSS] = await Promise.all([
|
|
@@ -74,7 +81,7 @@ async function getProjectData(options) {
|
|
|
74
81
|
? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, undefined, options.headers)
|
|
75
82
|
: Promise.resolve(null),
|
|
76
83
|
includeCSS
|
|
77
|
-
? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.
|
|
84
|
+
? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.antiflickerMode, options.headers)
|
|
78
85
|
: Promise.resolve(null),
|
|
79
86
|
]);
|
|
80
87
|
const config = {};
|
|
@@ -230,12 +230,13 @@ type ActivationCondition = {
|
|
|
230
230
|
allocation?: ActivationConditionAllocation;
|
|
231
231
|
js_function?: string;
|
|
232
232
|
};
|
|
233
|
+
type AntiflickerMode = 'body' | 'include' | 'exclude';
|
|
233
234
|
type CoframeConfig = {
|
|
234
235
|
projectId: string;
|
|
235
236
|
previewVariantId?: string;
|
|
236
237
|
trackingOnly?: boolean;
|
|
237
238
|
enableAntiFlickering?: boolean;
|
|
238
|
-
|
|
239
|
+
antiflickerMode?: AntiflickerMode;
|
|
239
240
|
waitForHydration?: boolean;
|
|
240
241
|
waitForCookiesEnabled?: boolean;
|
|
241
242
|
waitForFeatureFlag?: boolean;
|
|
@@ -295,6 +296,7 @@ interface TreatmentAppliedHandlers {
|
|
|
295
296
|
callback?: (data: TreatmentData) => void;
|
|
296
297
|
bulkCallback?: (data: TreatmentData[]) => void;
|
|
297
298
|
bulkCallbackV2?: (data: TreatmentDataV2[], rawIds: ExperimentInfo[]) => void;
|
|
299
|
+
bulkCallbackV2WithoutConsent?: (data: TreatmentDataV2[], rawIds: ExperimentInfo[]) => void;
|
|
298
300
|
}
|
|
299
301
|
declare function setConsent(enabled: boolean): void;
|
|
300
302
|
declare function setUserToken(token: string): void;
|
|
@@ -233,12 +233,13 @@ type ActivationCondition = {
|
|
|
233
233
|
allocation?: ActivationConditionAllocation;
|
|
234
234
|
js_function?: string;
|
|
235
235
|
};
|
|
236
|
+
type AntiflickerMode = 'body' | 'include' | 'exclude';
|
|
236
237
|
type CoframeConfig = {
|
|
237
238
|
projectId: string;
|
|
238
239
|
previewVariantId?: string;
|
|
239
240
|
trackingOnly?: boolean;
|
|
240
241
|
enableAntiFlickering?: boolean;
|
|
241
|
-
|
|
242
|
+
antiflickerMode?: AntiflickerMode;
|
|
242
243
|
waitForHydration?: boolean;
|
|
243
244
|
waitForCookiesEnabled?: boolean;
|
|
244
245
|
waitForFeatureFlag?: boolean;
|
|
@@ -290,13 +291,14 @@ interface CoframeProviderProps {
|
|
|
290
291
|
onTreatmentApplied?: (data: TreatmentData) => void;
|
|
291
292
|
onTreatmentAppliedBulk?: (data: TreatmentData[]) => void;
|
|
292
293
|
onTreatmentAppliedBulkV2?: (data: TreatmentDataV2[], rawIds: ExperimentInfo[]) => void;
|
|
294
|
+
onTreatmentAppliedBulkV2WithoutConsent?: (data: TreatmentDataV2[], rawIds: ExperimentInfo[]) => void;
|
|
293
295
|
onLog?: (payload: LogPayload) => void;
|
|
294
296
|
children: ReactNode;
|
|
295
297
|
}
|
|
296
298
|
interface CoframeContextValue {
|
|
297
299
|
treatments: TreatmentData[] | null;
|
|
298
300
|
}
|
|
299
|
-
declare function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onLog: onLogProp, children, }: CoframeProviderProps): React.FunctionComponentElement<React.ProviderProps<CoframeContextValue>>;
|
|
301
|
+
declare function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onTreatmentAppliedBulkV2WithoutConsent, onLog: onLogProp, children, }: CoframeProviderProps): React.FunctionComponentElement<React.ProviderProps<CoframeContextValue>>;
|
|
300
302
|
declare function useCoframeTreatments(): TreatmentData[] | null;
|
|
301
303
|
declare function useCoframeTreatment(experimentId: string): TreatmentData | undefined;
|
|
302
304
|
declare function useCoframeVariant(experimentId: string): string | undefined;
|
|
@@ -196,6 +196,7 @@ type ActivationCondition = {
|
|
|
196
196
|
allocation?: ActivationConditionAllocation;
|
|
197
197
|
js_function?: string;
|
|
198
198
|
};
|
|
199
|
+
type AntiflickerMode = 'body' | 'include' | 'exclude';
|
|
199
200
|
type BotReason = 'none' | 'cf_bot_score' | 'cf_verified_bot' | 'force_bot_param';
|
|
200
201
|
type PersonalizationHeaders = {
|
|
201
202
|
'x-device-type': string;
|
|
@@ -215,7 +216,7 @@ interface GetProjectDataOptions {
|
|
|
215
216
|
currentUrl: string;
|
|
216
217
|
userContext?: Record<string, unknown>;
|
|
217
218
|
headers: Headers | Record<string, string>;
|
|
218
|
-
|
|
219
|
+
antiflickerMode?: AntiflickerMode;
|
|
219
220
|
includeProject?: boolean;
|
|
220
221
|
includeCSS?: boolean;
|
|
221
222
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coframe/sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10",
|
|
4
4
|
"description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
|
|
5
5
|
"main": "dist/pkg/cf.cjs.js",
|
|
6
6
|
"module": "dist/pkg/cf.esm.mjs",
|