perspectapi-ts-sdk 6.1.2 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +80 -1
- package/dist/index.d.ts +80 -1
- package/dist/index.js +231 -9
- package/dist/index.mjs +225 -8
- package/package.json +1 -1
- package/src/ab/ab-client.ts +262 -0
- package/src/ab/bucketing.ts +56 -0
- package/src/index.ts +14 -1
- package/src/types/index.ts +14 -0
- package/src/utils/http-client.ts +8 -7
- package/src/v2/client/collections-client.ts +29 -5
package/dist/index.d.mts
CHANGED
|
@@ -1079,6 +1079,12 @@ interface ApiError {
|
|
|
1079
1079
|
status?: number;
|
|
1080
1080
|
details?: any;
|
|
1081
1081
|
}
|
|
1082
|
+
declare class PerspectApiError extends Error implements ApiError {
|
|
1083
|
+
code?: string;
|
|
1084
|
+
status?: number;
|
|
1085
|
+
details?: any;
|
|
1086
|
+
constructor({ message, code, status, details }: ApiError);
|
|
1087
|
+
}
|
|
1082
1088
|
interface PerspectApiConfig {
|
|
1083
1089
|
baseUrl: string;
|
|
1084
1090
|
apiKey?: string;
|
|
@@ -4129,6 +4135,21 @@ declare class CloudflareKVCacheAdapter implements CacheAdapter {
|
|
|
4129
4135
|
clear(): Promise<void>;
|
|
4130
4136
|
}
|
|
4131
4137
|
|
|
4138
|
+
/**
|
|
4139
|
+
* Simple in-memory cache adapter primarily suited for development and testing.
|
|
4140
|
+
*/
|
|
4141
|
+
|
|
4142
|
+
declare class InMemoryCacheAdapter implements CacheAdapter {
|
|
4143
|
+
private store;
|
|
4144
|
+
get(key: string): Promise<string | undefined>;
|
|
4145
|
+
set(key: string, value: string, options?: {
|
|
4146
|
+
ttlSeconds?: number;
|
|
4147
|
+
}): Promise<void>;
|
|
4148
|
+
delete(key: string): Promise<void>;
|
|
4149
|
+
deleteMany(keys: string[]): Promise<void>;
|
|
4150
|
+
clear(): Promise<void>;
|
|
4151
|
+
}
|
|
4152
|
+
|
|
4132
4153
|
/**
|
|
4133
4154
|
* No-op cache adapter that disables caching while preserving the cache contract.
|
|
4134
4155
|
*/
|
|
@@ -4141,6 +4162,64 @@ declare class NoopCacheAdapter implements CacheAdapter {
|
|
|
4141
4162
|
clear(): Promise<void>;
|
|
4142
4163
|
}
|
|
4143
4164
|
|
|
4165
|
+
interface CreatePerspectAbOptions {
|
|
4166
|
+
apiKey: string;
|
|
4167
|
+
siteName: string;
|
|
4168
|
+
baseUrl?: string;
|
|
4169
|
+
/** Pluggable cache adapter — CloudflareKVCacheAdapter, InMemoryCacheAdapter, or NoopCacheAdapter. */
|
|
4170
|
+
cache?: CacheAdapter;
|
|
4171
|
+
/** ExecutionContext (CF Workers) or any object with waitUntil — enables background tasks. */
|
|
4172
|
+
ctx?: {
|
|
4173
|
+
waitUntil(p: Promise<unknown>): void;
|
|
4174
|
+
};
|
|
4175
|
+
}
|
|
4176
|
+
interface AbForRequestResult {
|
|
4177
|
+
ab: AbClient;
|
|
4178
|
+
/** Merge into the outgoing response — may carry a freshly minted perspect_vid cookie. */
|
|
4179
|
+
responseHeaders: Headers;
|
|
4180
|
+
}
|
|
4181
|
+
interface AbVariantResult {
|
|
4182
|
+
variant: string | null;
|
|
4183
|
+
enrolled: boolean;
|
|
4184
|
+
config: Record<string, unknown> | null;
|
|
4185
|
+
}
|
|
4186
|
+
interface AbClient {
|
|
4187
|
+
getVariant(flagKey: string): Promise<AbVariantResult>;
|
|
4188
|
+
track(event: string, properties?: Record<string, unknown>): Promise<void>;
|
|
4189
|
+
}
|
|
4190
|
+
interface PerspectAb {
|
|
4191
|
+
forRequest(request: Request): Promise<AbForRequestResult>;
|
|
4192
|
+
refreshConfig(): Promise<void>;
|
|
4193
|
+
}
|
|
4194
|
+
declare function createPerspectAb(options: CreatePerspectAbOptions): PerspectAb;
|
|
4195
|
+
|
|
4196
|
+
/**
|
|
4197
|
+
* Deterministic bucketing for A/B assignments.
|
|
4198
|
+
*
|
|
4199
|
+
* Both the site SDK (local assignment) and the platform event endpoint
|
|
4200
|
+
* (server-side validation) compute the same hash → variant mapping.
|
|
4201
|
+
* Any change here must ship to both simultaneously, or assignments and
|
|
4202
|
+
* validation will diverge.
|
|
4203
|
+
*/
|
|
4204
|
+
/**
|
|
4205
|
+
* FNV-1a 32-bit over UTF-8 bytes, reduced mod 10000.
|
|
4206
|
+
* Pure function, no crypto — determinism and portability beat pre-image
|
|
4207
|
+
* resistance here. The attack surface on the mapping is the same for
|
|
4208
|
+
* both sides; what matters is that site and platform agree bit-for-bit.
|
|
4209
|
+
*/
|
|
4210
|
+
declare function bucketFor(visitorId: string, flagKey: string, version: number): number;
|
|
4211
|
+
/**
|
|
4212
|
+
* Resolve a bucket to a variant using cumulative weightBp ranges.
|
|
4213
|
+
* Variants are consumed in the order given — callers must sort variants
|
|
4214
|
+
* consistently on both sides (we sort by key).
|
|
4215
|
+
*
|
|
4216
|
+
* Returns null iff bucket >= trafficAllocationBp (visitor not enrolled).
|
|
4217
|
+
*/
|
|
4218
|
+
declare function variantForBucket(bucket: number, variants: {
|
|
4219
|
+
key: string;
|
|
4220
|
+
weightBp: number;
|
|
4221
|
+
}[], trafficAllocationBp: number): string | null;
|
|
4222
|
+
|
|
4144
4223
|
/**
|
|
4145
4224
|
* Cloudflare Image Resizing Integration
|
|
4146
4225
|
* Transforms images on-the-fly using Cloudflare's Image Resizing service
|
|
@@ -4445,4 +4524,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
|
|
|
4445
4524
|
error: string;
|
|
4446
4525
|
}>;
|
|
4447
4526
|
|
|
4448
|
-
export { type AddCollectionItemRequest, type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, BaseClient, type BlogPost, type BundleCollection, type BundleCollectionItem, type BundleCollectionItemWithProduct, BundlesClient, type CacheConfig, CacheManager, type CancelSubscriptionRequest, type CancelSubscriptionResponse, CategoriesClient, type Category, type CategorySummary, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, CloudflareKVCacheAdapter, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, type ContentCategoryResponse, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateBundleCollectionRequest, type CreateBundleGroupRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateProductSkuRequest, type CreateSiteRequest, type CreateWebhookRequest, type CreditBalance, type CreditBalanceWithTransactions, type CreditTransaction, DEFAULT_IMAGE_SIZES, type GrantCreditRequest, HttpClient, type HttpMethod, type ImageTransformOptions, type LoadBlockBySlugOptions, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, type NewsletterCampaignDetail, type NewsletterCampaignListResponse, type NewsletterCampaignSummary, type NewsletterCampaignTestSendRequest, type NewsletterCampaignTestSendResponse, NewsletterClient, type NewsletterConfirmResponse, type NewsletterExportCreateRequest, type NewsletterExportCreateResponse, type NewsletterList, type NewsletterManagementCampaign, type NewsletterManagementCampaignListResponse, NewsletterManagementClient, type NewsletterManagementList, type NewsletterManagementListMembership, type NewsletterManagementPagination, type NewsletterManagementSeries, type NewsletterManagementStatsResponse, type NewsletterManagementSubscription, type NewsletterManagementSubscriptionsListResponse, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterSubscriptionImportRowRequest, type NewsletterSubscriptionMembershipUpdateRequest, type NewsletterSubscriptionSyncRequest, type NewsletterSubscriptionSyncResponse, type NewsletterSubscriptionsBulkAction, type NewsletterSubscriptionsBulkOutcome, type NewsletterSubscriptionsBulkUpdateRequest, type NewsletterSubscriptionsBulkUpdateResponse, type NewsletterSubscriptionsImportRequest, type NewsletterSubscriptionsImportResponse, type NewsletterSubscriptionsImportRowResult, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, PerspectApiV2Client, PerspectV2Error, type Product, type ProductBundleGroup, type ProductQueryParams, type ProductSku, type ProductSkuMediaItem, type ProductSkuOption, ProductsClient, type RequestOptions, type RequestOtpRequest, type ResponsiveImageSizes, type SetProfileValueRequest, type Site, type SiteUser, type SiteUserOrder, type SiteUserProfile, type SiteUserSubscription, SiteUsersClient, SitesClient, type SubscriptionCancellationMode, type UpdateApiKeyRequest, type UpdateContentRequest, type UpdateSiteUserRequest, type User, V1_DEPRECATION_NOTICE, V1_SUNSET_DATE, type V2ApiKey, type V2CancelSubscriptionResult, type V2Category, type V2CategoryCreateParams, type V2CategoryUpdateParams, type V2Collection, type V2CollectionCreateParams, type V2CollectionItem, type V2CollectionUpdateParams, type V2ContactSubmission, type V2Content, type V2ContentCreateParams, type V2ContentListParams, type V2ContentUpdateParams, type V2CreditBalance, type V2CreditTransaction, type V2Deleted, type V2Error, type V2ErrorType, type V2GrantCreditParams, type V2GrantCreditResult, type V2List, type V2Media, type V2NewsletterCampaign, type V2NewsletterImportRequest, type V2NewsletterImportResult, type V2NewsletterList, type V2NewsletterListCreateParams, type V2NewsletterListUpdateParams, type V2NewsletterSubscription, type V2NewsletterSubscriptionListMembershipUpdate, type V2NewsletterSyncInput, type V2NewsletterSyncResult, type V2NewsletterTrackingResponse, type V2Object, type V2Order, type V2OrderAddress, type V2OrderCreateParams, type V2OrderCreateResult, type V2OrderFulfillmentUpdate, type V2OrderLineItem, type V2OrderLineItemPriceData, type V2OrderListParams, type V2OrderTaxRequest, type V2Organization, type V2PaginationParams, type V2Product, type V2ProductCreateParams, type V2ProductListParams, type V2ProductUpdateParams, type V2Site, type V2SiteUser, type V2SiteUserListParams, type V2SiteUserMeUpdateParams, type V2SiteUserProfile, type V2SiteUserSubscription, type V2SiteUserUpdateParams, type V2SiteUserWithProfile, type V2SubscriptionCancelParams, type V2SubscriptionChangePlanParams, type V2SubscriptionPauseParams, type V2Webhook, type V2WebhookCreateParams, type V2WebhookUpdateParams, type VerifyOtpRequest, type VerifyOtpResponse, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, createPerspectApiV2Client, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadBlockBySlug, loadBlocks, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
|
|
4527
|
+
export { type AbClient, type AbForRequestResult, type AbVariantResult, type AddCollectionItemRequest, type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, BaseClient, type BlogPost, type BundleCollection, type BundleCollectionItem, type BundleCollectionItemWithProduct, BundlesClient, type CacheAdapter, type CacheConfig, CacheManager, type CancelSubscriptionRequest, type CancelSubscriptionResponse, CategoriesClient, type Category, type CategorySummary, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, CloudflareKVCacheAdapter, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, type ContentCategoryResponse, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateBundleCollectionRequest, type CreateBundleGroupRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreatePerspectAbOptions, type CreateProductRequest, type CreateProductSkuRequest, type CreateSiteRequest, type CreateWebhookRequest, type CreditBalance, type CreditBalanceWithTransactions, type CreditTransaction, DEFAULT_IMAGE_SIZES, type GrantCreditRequest, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadBlockBySlugOptions, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, type NewsletterCampaignDetail, type NewsletterCampaignListResponse, type NewsletterCampaignSummary, type NewsletterCampaignTestSendRequest, type NewsletterCampaignTestSendResponse, NewsletterClient, type NewsletterConfirmResponse, type NewsletterExportCreateRequest, type NewsletterExportCreateResponse, type NewsletterList, type NewsletterManagementCampaign, type NewsletterManagementCampaignListResponse, NewsletterManagementClient, type NewsletterManagementList, type NewsletterManagementListMembership, type NewsletterManagementPagination, type NewsletterManagementSeries, type NewsletterManagementStatsResponse, type NewsletterManagementSubscription, type NewsletterManagementSubscriptionsListResponse, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterSubscriptionImportRowRequest, type NewsletterSubscriptionMembershipUpdateRequest, type NewsletterSubscriptionSyncRequest, type NewsletterSubscriptionSyncResponse, type NewsletterSubscriptionsBulkAction, type NewsletterSubscriptionsBulkOutcome, type NewsletterSubscriptionsBulkUpdateRequest, type NewsletterSubscriptionsBulkUpdateResponse, type NewsletterSubscriptionsImportRequest, type NewsletterSubscriptionsImportResponse, type NewsletterSubscriptionsImportRowResult, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, type PerspectAb, PerspectApiClient, type PerspectApiConfig, PerspectApiError, PerspectApiV2Client, PerspectV2Error, type Product, type ProductBundleGroup, type ProductQueryParams, type ProductSku, type ProductSkuMediaItem, type ProductSkuOption, ProductsClient, type RequestOptions, type RequestOtpRequest, type ResponsiveImageSizes, type SetProfileValueRequest, type Site, type SiteUser, type SiteUserOrder, type SiteUserProfile, type SiteUserSubscription, SiteUsersClient, SitesClient, type SubscriptionCancellationMode, type UpdateApiKeyRequest, type UpdateContentRequest, type UpdateSiteUserRequest, type User, V1_DEPRECATION_NOTICE, V1_SUNSET_DATE, type V2ApiKey, type V2CancelSubscriptionResult, type V2Category, type V2CategoryCreateParams, type V2CategoryUpdateParams, type V2Collection, type V2CollectionCreateParams, type V2CollectionItem, type V2CollectionUpdateParams, type V2ContactSubmission, type V2Content, type V2ContentCreateParams, type V2ContentListParams, type V2ContentUpdateParams, type V2CreditBalance, type V2CreditTransaction, type V2Deleted, type V2Error, type V2ErrorType, type V2GrantCreditParams, type V2GrantCreditResult, type V2List, type V2Media, type V2NewsletterCampaign, type V2NewsletterImportRequest, type V2NewsletterImportResult, type V2NewsletterList, type V2NewsletterListCreateParams, type V2NewsletterListUpdateParams, type V2NewsletterSubscription, type V2NewsletterSubscriptionListMembershipUpdate, type V2NewsletterSyncInput, type V2NewsletterSyncResult, type V2NewsletterTrackingResponse, type V2Object, type V2Order, type V2OrderAddress, type V2OrderCreateParams, type V2OrderCreateResult, type V2OrderFulfillmentUpdate, type V2OrderLineItem, type V2OrderLineItemPriceData, type V2OrderListParams, type V2OrderTaxRequest, type V2Organization, type V2PaginationParams, type V2Product, type V2ProductCreateParams, type V2ProductListParams, type V2ProductUpdateParams, type V2Site, type V2SiteUser, type V2SiteUserListParams, type V2SiteUserMeUpdateParams, type V2SiteUserProfile, type V2SiteUserSubscription, type V2SiteUserUpdateParams, type V2SiteUserWithProfile, type V2SubscriptionCancelParams, type V2SubscriptionChangePlanParams, type V2SubscriptionPauseParams, type V2Webhook, type V2WebhookCreateParams, type V2WebhookUpdateParams, type VerifyOtpRequest, type VerifyOtpResponse, type Webhook, WebhooksClient, bucketFor, buildImageUrl, createApiError, createCheckoutSession, createPerspectAb, createPerspectApiClient, createPerspectApiV2Client, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadBlockBySlug, loadBlocks, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct, variantForBucket };
|
package/dist/index.d.ts
CHANGED
|
@@ -1079,6 +1079,12 @@ interface ApiError {
|
|
|
1079
1079
|
status?: number;
|
|
1080
1080
|
details?: any;
|
|
1081
1081
|
}
|
|
1082
|
+
declare class PerspectApiError extends Error implements ApiError {
|
|
1083
|
+
code?: string;
|
|
1084
|
+
status?: number;
|
|
1085
|
+
details?: any;
|
|
1086
|
+
constructor({ message, code, status, details }: ApiError);
|
|
1087
|
+
}
|
|
1082
1088
|
interface PerspectApiConfig {
|
|
1083
1089
|
baseUrl: string;
|
|
1084
1090
|
apiKey?: string;
|
|
@@ -4129,6 +4135,21 @@ declare class CloudflareKVCacheAdapter implements CacheAdapter {
|
|
|
4129
4135
|
clear(): Promise<void>;
|
|
4130
4136
|
}
|
|
4131
4137
|
|
|
4138
|
+
/**
|
|
4139
|
+
* Simple in-memory cache adapter primarily suited for development and testing.
|
|
4140
|
+
*/
|
|
4141
|
+
|
|
4142
|
+
declare class InMemoryCacheAdapter implements CacheAdapter {
|
|
4143
|
+
private store;
|
|
4144
|
+
get(key: string): Promise<string | undefined>;
|
|
4145
|
+
set(key: string, value: string, options?: {
|
|
4146
|
+
ttlSeconds?: number;
|
|
4147
|
+
}): Promise<void>;
|
|
4148
|
+
delete(key: string): Promise<void>;
|
|
4149
|
+
deleteMany(keys: string[]): Promise<void>;
|
|
4150
|
+
clear(): Promise<void>;
|
|
4151
|
+
}
|
|
4152
|
+
|
|
4132
4153
|
/**
|
|
4133
4154
|
* No-op cache adapter that disables caching while preserving the cache contract.
|
|
4134
4155
|
*/
|
|
@@ -4141,6 +4162,64 @@ declare class NoopCacheAdapter implements CacheAdapter {
|
|
|
4141
4162
|
clear(): Promise<void>;
|
|
4142
4163
|
}
|
|
4143
4164
|
|
|
4165
|
+
interface CreatePerspectAbOptions {
|
|
4166
|
+
apiKey: string;
|
|
4167
|
+
siteName: string;
|
|
4168
|
+
baseUrl?: string;
|
|
4169
|
+
/** Pluggable cache adapter — CloudflareKVCacheAdapter, InMemoryCacheAdapter, or NoopCacheAdapter. */
|
|
4170
|
+
cache?: CacheAdapter;
|
|
4171
|
+
/** ExecutionContext (CF Workers) or any object with waitUntil — enables background tasks. */
|
|
4172
|
+
ctx?: {
|
|
4173
|
+
waitUntil(p: Promise<unknown>): void;
|
|
4174
|
+
};
|
|
4175
|
+
}
|
|
4176
|
+
interface AbForRequestResult {
|
|
4177
|
+
ab: AbClient;
|
|
4178
|
+
/** Merge into the outgoing response — may carry a freshly minted perspect_vid cookie. */
|
|
4179
|
+
responseHeaders: Headers;
|
|
4180
|
+
}
|
|
4181
|
+
interface AbVariantResult {
|
|
4182
|
+
variant: string | null;
|
|
4183
|
+
enrolled: boolean;
|
|
4184
|
+
config: Record<string, unknown> | null;
|
|
4185
|
+
}
|
|
4186
|
+
interface AbClient {
|
|
4187
|
+
getVariant(flagKey: string): Promise<AbVariantResult>;
|
|
4188
|
+
track(event: string, properties?: Record<string, unknown>): Promise<void>;
|
|
4189
|
+
}
|
|
4190
|
+
interface PerspectAb {
|
|
4191
|
+
forRequest(request: Request): Promise<AbForRequestResult>;
|
|
4192
|
+
refreshConfig(): Promise<void>;
|
|
4193
|
+
}
|
|
4194
|
+
declare function createPerspectAb(options: CreatePerspectAbOptions): PerspectAb;
|
|
4195
|
+
|
|
4196
|
+
/**
|
|
4197
|
+
* Deterministic bucketing for A/B assignments.
|
|
4198
|
+
*
|
|
4199
|
+
* Both the site SDK (local assignment) and the platform event endpoint
|
|
4200
|
+
* (server-side validation) compute the same hash → variant mapping.
|
|
4201
|
+
* Any change here must ship to both simultaneously, or assignments and
|
|
4202
|
+
* validation will diverge.
|
|
4203
|
+
*/
|
|
4204
|
+
/**
|
|
4205
|
+
* FNV-1a 32-bit over UTF-8 bytes, reduced mod 10000.
|
|
4206
|
+
* Pure function, no crypto — determinism and portability beat pre-image
|
|
4207
|
+
* resistance here. The attack surface on the mapping is the same for
|
|
4208
|
+
* both sides; what matters is that site and platform agree bit-for-bit.
|
|
4209
|
+
*/
|
|
4210
|
+
declare function bucketFor(visitorId: string, flagKey: string, version: number): number;
|
|
4211
|
+
/**
|
|
4212
|
+
* Resolve a bucket to a variant using cumulative weightBp ranges.
|
|
4213
|
+
* Variants are consumed in the order given — callers must sort variants
|
|
4214
|
+
* consistently on both sides (we sort by key).
|
|
4215
|
+
*
|
|
4216
|
+
* Returns null iff bucket >= trafficAllocationBp (visitor not enrolled).
|
|
4217
|
+
*/
|
|
4218
|
+
declare function variantForBucket(bucket: number, variants: {
|
|
4219
|
+
key: string;
|
|
4220
|
+
weightBp: number;
|
|
4221
|
+
}[], trafficAllocationBp: number): string | null;
|
|
4222
|
+
|
|
4144
4223
|
/**
|
|
4145
4224
|
* Cloudflare Image Resizing Integration
|
|
4146
4225
|
* Transforms images on-the-fly using Cloudflare's Image Resizing service
|
|
@@ -4445,4 +4524,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
|
|
|
4445
4524
|
error: string;
|
|
4446
4525
|
}>;
|
|
4447
4526
|
|
|
4448
|
-
export { type AddCollectionItemRequest, type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, BaseClient, type BlogPost, type BundleCollection, type BundleCollectionItem, type BundleCollectionItemWithProduct, BundlesClient, type CacheConfig, CacheManager, type CancelSubscriptionRequest, type CancelSubscriptionResponse, CategoriesClient, type Category, type CategorySummary, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, CloudflareKVCacheAdapter, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, type ContentCategoryResponse, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateBundleCollectionRequest, type CreateBundleGroupRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateProductSkuRequest, type CreateSiteRequest, type CreateWebhookRequest, type CreditBalance, type CreditBalanceWithTransactions, type CreditTransaction, DEFAULT_IMAGE_SIZES, type GrantCreditRequest, HttpClient, type HttpMethod, type ImageTransformOptions, type LoadBlockBySlugOptions, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, type NewsletterCampaignDetail, type NewsletterCampaignListResponse, type NewsletterCampaignSummary, type NewsletterCampaignTestSendRequest, type NewsletterCampaignTestSendResponse, NewsletterClient, type NewsletterConfirmResponse, type NewsletterExportCreateRequest, type NewsletterExportCreateResponse, type NewsletterList, type NewsletterManagementCampaign, type NewsletterManagementCampaignListResponse, NewsletterManagementClient, type NewsletterManagementList, type NewsletterManagementListMembership, type NewsletterManagementPagination, type NewsletterManagementSeries, type NewsletterManagementStatsResponse, type NewsletterManagementSubscription, type NewsletterManagementSubscriptionsListResponse, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterSubscriptionImportRowRequest, type NewsletterSubscriptionMembershipUpdateRequest, type NewsletterSubscriptionSyncRequest, type NewsletterSubscriptionSyncResponse, type NewsletterSubscriptionsBulkAction, type NewsletterSubscriptionsBulkOutcome, type NewsletterSubscriptionsBulkUpdateRequest, type NewsletterSubscriptionsBulkUpdateResponse, type NewsletterSubscriptionsImportRequest, type NewsletterSubscriptionsImportResponse, type NewsletterSubscriptionsImportRowResult, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, PerspectApiV2Client, PerspectV2Error, type Product, type ProductBundleGroup, type ProductQueryParams, type ProductSku, type ProductSkuMediaItem, type ProductSkuOption, ProductsClient, type RequestOptions, type RequestOtpRequest, type ResponsiveImageSizes, type SetProfileValueRequest, type Site, type SiteUser, type SiteUserOrder, type SiteUserProfile, type SiteUserSubscription, SiteUsersClient, SitesClient, type SubscriptionCancellationMode, type UpdateApiKeyRequest, type UpdateContentRequest, type UpdateSiteUserRequest, type User, V1_DEPRECATION_NOTICE, V1_SUNSET_DATE, type V2ApiKey, type V2CancelSubscriptionResult, type V2Category, type V2CategoryCreateParams, type V2CategoryUpdateParams, type V2Collection, type V2CollectionCreateParams, type V2CollectionItem, type V2CollectionUpdateParams, type V2ContactSubmission, type V2Content, type V2ContentCreateParams, type V2ContentListParams, type V2ContentUpdateParams, type V2CreditBalance, type V2CreditTransaction, type V2Deleted, type V2Error, type V2ErrorType, type V2GrantCreditParams, type V2GrantCreditResult, type V2List, type V2Media, type V2NewsletterCampaign, type V2NewsletterImportRequest, type V2NewsletterImportResult, type V2NewsletterList, type V2NewsletterListCreateParams, type V2NewsletterListUpdateParams, type V2NewsletterSubscription, type V2NewsletterSubscriptionListMembershipUpdate, type V2NewsletterSyncInput, type V2NewsletterSyncResult, type V2NewsletterTrackingResponse, type V2Object, type V2Order, type V2OrderAddress, type V2OrderCreateParams, type V2OrderCreateResult, type V2OrderFulfillmentUpdate, type V2OrderLineItem, type V2OrderLineItemPriceData, type V2OrderListParams, type V2OrderTaxRequest, type V2Organization, type V2PaginationParams, type V2Product, type V2ProductCreateParams, type V2ProductListParams, type V2ProductUpdateParams, type V2Site, type V2SiteUser, type V2SiteUserListParams, type V2SiteUserMeUpdateParams, type V2SiteUserProfile, type V2SiteUserSubscription, type V2SiteUserUpdateParams, type V2SiteUserWithProfile, type V2SubscriptionCancelParams, type V2SubscriptionChangePlanParams, type V2SubscriptionPauseParams, type V2Webhook, type V2WebhookCreateParams, type V2WebhookUpdateParams, type VerifyOtpRequest, type VerifyOtpResponse, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, createPerspectApiV2Client, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadBlockBySlug, loadBlocks, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
|
|
4527
|
+
export { type AbClient, type AbForRequestResult, type AbVariantResult, type AddCollectionItemRequest, type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, BaseClient, type BlogPost, type BundleCollection, type BundleCollectionItem, type BundleCollectionItemWithProduct, BundlesClient, type CacheAdapter, type CacheConfig, CacheManager, type CancelSubscriptionRequest, type CancelSubscriptionResponse, CategoriesClient, type Category, type CategorySummary, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, CloudflareKVCacheAdapter, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, type ContentCategoryResponse, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateBundleCollectionRequest, type CreateBundleGroupRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreatePerspectAbOptions, type CreateProductRequest, type CreateProductSkuRequest, type CreateSiteRequest, type CreateWebhookRequest, type CreditBalance, type CreditBalanceWithTransactions, type CreditTransaction, DEFAULT_IMAGE_SIZES, type GrantCreditRequest, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadBlockBySlugOptions, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, type NewsletterCampaignDetail, type NewsletterCampaignListResponse, type NewsletterCampaignSummary, type NewsletterCampaignTestSendRequest, type NewsletterCampaignTestSendResponse, NewsletterClient, type NewsletterConfirmResponse, type NewsletterExportCreateRequest, type NewsletterExportCreateResponse, type NewsletterList, type NewsletterManagementCampaign, type NewsletterManagementCampaignListResponse, NewsletterManagementClient, type NewsletterManagementList, type NewsletterManagementListMembership, type NewsletterManagementPagination, type NewsletterManagementSeries, type NewsletterManagementStatsResponse, type NewsletterManagementSubscription, type NewsletterManagementSubscriptionsListResponse, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterSubscriptionImportRowRequest, type NewsletterSubscriptionMembershipUpdateRequest, type NewsletterSubscriptionSyncRequest, type NewsletterSubscriptionSyncResponse, type NewsletterSubscriptionsBulkAction, type NewsletterSubscriptionsBulkOutcome, type NewsletterSubscriptionsBulkUpdateRequest, type NewsletterSubscriptionsBulkUpdateResponse, type NewsletterSubscriptionsImportRequest, type NewsletterSubscriptionsImportResponse, type NewsletterSubscriptionsImportRowResult, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, type PerspectAb, PerspectApiClient, type PerspectApiConfig, PerspectApiError, PerspectApiV2Client, PerspectV2Error, type Product, type ProductBundleGroup, type ProductQueryParams, type ProductSku, type ProductSkuMediaItem, type ProductSkuOption, ProductsClient, type RequestOptions, type RequestOtpRequest, type ResponsiveImageSizes, type SetProfileValueRequest, type Site, type SiteUser, type SiteUserOrder, type SiteUserProfile, type SiteUserSubscription, SiteUsersClient, SitesClient, type SubscriptionCancellationMode, type UpdateApiKeyRequest, type UpdateContentRequest, type UpdateSiteUserRequest, type User, V1_DEPRECATION_NOTICE, V1_SUNSET_DATE, type V2ApiKey, type V2CancelSubscriptionResult, type V2Category, type V2CategoryCreateParams, type V2CategoryUpdateParams, type V2Collection, type V2CollectionCreateParams, type V2CollectionItem, type V2CollectionUpdateParams, type V2ContactSubmission, type V2Content, type V2ContentCreateParams, type V2ContentListParams, type V2ContentUpdateParams, type V2CreditBalance, type V2CreditTransaction, type V2Deleted, type V2Error, type V2ErrorType, type V2GrantCreditParams, type V2GrantCreditResult, type V2List, type V2Media, type V2NewsletterCampaign, type V2NewsletterImportRequest, type V2NewsletterImportResult, type V2NewsletterList, type V2NewsletterListCreateParams, type V2NewsletterListUpdateParams, type V2NewsletterSubscription, type V2NewsletterSubscriptionListMembershipUpdate, type V2NewsletterSyncInput, type V2NewsletterSyncResult, type V2NewsletterTrackingResponse, type V2Object, type V2Order, type V2OrderAddress, type V2OrderCreateParams, type V2OrderCreateResult, type V2OrderFulfillmentUpdate, type V2OrderLineItem, type V2OrderLineItemPriceData, type V2OrderListParams, type V2OrderTaxRequest, type V2Organization, type V2PaginationParams, type V2Product, type V2ProductCreateParams, type V2ProductListParams, type V2ProductUpdateParams, type V2Site, type V2SiteUser, type V2SiteUserListParams, type V2SiteUserMeUpdateParams, type V2SiteUserProfile, type V2SiteUserSubscription, type V2SiteUserUpdateParams, type V2SiteUserWithProfile, type V2SubscriptionCancelParams, type V2SubscriptionChangePlanParams, type V2SubscriptionPauseParams, type V2Webhook, type V2WebhookCreateParams, type V2WebhookUpdateParams, type VerifyOtpRequest, type VerifyOtpResponse, type Webhook, WebhooksClient, bucketFor, buildImageUrl, createApiError, createCheckoutSession, createPerspectAb, createPerspectApiClient, createPerspectApiV2Client, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadBlockBySlug, loadBlocks, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct, variantForBucket };
|
package/dist/index.js
CHANGED
|
@@ -32,11 +32,13 @@ __export(index_exports, {
|
|
|
32
32
|
ContentClient: () => ContentClient,
|
|
33
33
|
DEFAULT_IMAGE_SIZES: () => DEFAULT_IMAGE_SIZES,
|
|
34
34
|
HttpClient: () => HttpClient,
|
|
35
|
+
InMemoryCacheAdapter: () => InMemoryCacheAdapter,
|
|
35
36
|
NewsletterClient: () => NewsletterClient,
|
|
36
37
|
NewsletterManagementClient: () => NewsletterManagementClient,
|
|
37
38
|
NoopCacheAdapter: () => NoopCacheAdapter,
|
|
38
39
|
OrganizationsClient: () => OrganizationsClient,
|
|
39
40
|
PerspectApiClient: () => PerspectApiClient,
|
|
41
|
+
PerspectApiError: () => PerspectApiError,
|
|
40
42
|
PerspectApiV2Client: () => PerspectApiV2Client,
|
|
41
43
|
PerspectV2Error: () => PerspectV2Error,
|
|
42
44
|
ProductsClient: () => ProductsClient,
|
|
@@ -45,9 +47,11 @@ __export(index_exports, {
|
|
|
45
47
|
V1_DEPRECATION_NOTICE: () => V1_DEPRECATION_NOTICE,
|
|
46
48
|
V1_SUNSET_DATE: () => V1_SUNSET_DATE,
|
|
47
49
|
WebhooksClient: () => WebhooksClient,
|
|
50
|
+
bucketFor: () => bucketFor,
|
|
48
51
|
buildImageUrl: () => buildImageUrl,
|
|
49
52
|
createApiError: () => createApiError,
|
|
50
53
|
createCheckoutSession: () => createCheckoutSession,
|
|
54
|
+
createPerspectAb: () => createPerspectAb,
|
|
51
55
|
createPerspectApiClient: () => createPerspectApiClient,
|
|
52
56
|
createPerspectApiV2Client: () => createPerspectApiV2Client,
|
|
53
57
|
default: () => perspect_api_client_default,
|
|
@@ -65,7 +69,8 @@ __export(index_exports, {
|
|
|
65
69
|
loadProducts: () => loadProducts,
|
|
66
70
|
transformContent: () => transformContent,
|
|
67
71
|
transformMediaItem: () => transformMediaItem,
|
|
68
|
-
transformProduct: () => transformProduct
|
|
72
|
+
transformProduct: () => transformProduct,
|
|
73
|
+
variantForBucket: () => variantForBucket
|
|
69
74
|
});
|
|
70
75
|
module.exports = __toCommonJS(index_exports);
|
|
71
76
|
|
|
@@ -79,6 +84,20 @@ function warnV1Deprecated() {
|
|
|
79
84
|
console.warn(`[perspectapi-ts-sdk] ${V1_DEPRECATION_NOTICE}`);
|
|
80
85
|
}
|
|
81
86
|
|
|
87
|
+
// src/types/index.ts
|
|
88
|
+
var PerspectApiError = class extends Error {
|
|
89
|
+
code;
|
|
90
|
+
status;
|
|
91
|
+
details;
|
|
92
|
+
constructor({ message, code, status, details }) {
|
|
93
|
+
super(message);
|
|
94
|
+
this.name = "PerspectApiError";
|
|
95
|
+
this.code = code;
|
|
96
|
+
this.status = status;
|
|
97
|
+
this.details = details;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
82
101
|
// src/utils/http-client.ts
|
|
83
102
|
var HttpClient = class {
|
|
84
103
|
baseUrl;
|
|
@@ -282,12 +301,12 @@ var HttpClient = class {
|
|
|
282
301
|
}
|
|
283
302
|
if (!response.ok) {
|
|
284
303
|
console.error(`[HTTP Client - Response] Error response received`);
|
|
285
|
-
const error = {
|
|
304
|
+
const error = new PerspectApiError({
|
|
286
305
|
message: data?.error || data?.message || `HTTP ${response.status}: ${response.statusText}`,
|
|
287
306
|
status: response.status,
|
|
288
307
|
code: data?.code,
|
|
289
308
|
details: data
|
|
290
|
-
};
|
|
309
|
+
});
|
|
291
310
|
console.error(`[HTTP Client - Response] Throwing error:`, error);
|
|
292
311
|
throw error;
|
|
293
312
|
}
|
|
@@ -896,13 +915,29 @@ var CollectionsV2Client = class extends BaseV2Client {
|
|
|
896
915
|
return this.getOne(this.sitePath(siteName, "collections", id));
|
|
897
916
|
}
|
|
898
917
|
async create(siteName, data) {
|
|
899
|
-
|
|
918
|
+
const result = await this.post(this.sitePath(siteName, "collections"), data);
|
|
919
|
+
await this.invalidateCache({ keys: [this.sitePath(siteName, "collections")] });
|
|
920
|
+
return result;
|
|
900
921
|
}
|
|
901
922
|
async update(siteName, id, data) {
|
|
902
|
-
|
|
923
|
+
const result = await this.patchOne(this.sitePath(siteName, "collections", id), data);
|
|
924
|
+
await this.invalidateCache({
|
|
925
|
+
keys: [
|
|
926
|
+
this.sitePath(siteName, "collections"),
|
|
927
|
+
this.sitePath(siteName, "collections", id)
|
|
928
|
+
]
|
|
929
|
+
});
|
|
930
|
+
return result;
|
|
903
931
|
}
|
|
904
932
|
async del(siteName, id) {
|
|
905
|
-
|
|
933
|
+
const result = await this.deleteOne(this.sitePath(siteName, "collections", id));
|
|
934
|
+
await this.invalidateCache({
|
|
935
|
+
keys: [
|
|
936
|
+
this.sitePath(siteName, "collections"),
|
|
937
|
+
this.sitePath(siteName, "collections", id)
|
|
938
|
+
]
|
|
939
|
+
});
|
|
940
|
+
return result;
|
|
906
941
|
}
|
|
907
942
|
// --- Items ---
|
|
908
943
|
async listItems(siteName, collectionId) {
|
|
@@ -911,15 +946,23 @@ var CollectionsV2Client = class extends BaseV2Client {
|
|
|
911
946
|
);
|
|
912
947
|
}
|
|
913
948
|
async addItem(siteName, collectionId, data) {
|
|
914
|
-
|
|
949
|
+
const result = await this.post(
|
|
915
950
|
this.sitePath(siteName, "collections", `${collectionId}/items`),
|
|
916
951
|
data
|
|
917
952
|
);
|
|
953
|
+
await this.invalidateCache({
|
|
954
|
+
keys: [this.sitePath(siteName, "collections", `${collectionId}/items`)]
|
|
955
|
+
});
|
|
956
|
+
return result;
|
|
918
957
|
}
|
|
919
958
|
async removeItem(siteName, collectionId, itemId) {
|
|
920
|
-
|
|
959
|
+
const result = await this.deleteOne(
|
|
921
960
|
this.sitePath(siteName, "collections", `${collectionId}/items/${itemId}`)
|
|
922
961
|
);
|
|
962
|
+
await this.invalidateCache({
|
|
963
|
+
keys: [this.sitePath(siteName, "collections", `${collectionId}/items`)]
|
|
964
|
+
});
|
|
965
|
+
return result;
|
|
923
966
|
}
|
|
924
967
|
};
|
|
925
968
|
|
|
@@ -4139,6 +4182,180 @@ var CloudflareKVCacheAdapter = class {
|
|
|
4139
4182
|
}
|
|
4140
4183
|
};
|
|
4141
4184
|
|
|
4185
|
+
// src/cache/in-memory-adapter.ts
|
|
4186
|
+
var InMemoryCacheAdapter = class {
|
|
4187
|
+
store = /* @__PURE__ */ new Map();
|
|
4188
|
+
async get(key) {
|
|
4189
|
+
const entry = this.store.get(key);
|
|
4190
|
+
if (!entry) {
|
|
4191
|
+
return void 0;
|
|
4192
|
+
}
|
|
4193
|
+
if (entry.expiresAt && entry.expiresAt <= Date.now()) {
|
|
4194
|
+
this.store.delete(key);
|
|
4195
|
+
return void 0;
|
|
4196
|
+
}
|
|
4197
|
+
return entry.value;
|
|
4198
|
+
}
|
|
4199
|
+
async set(key, value, options) {
|
|
4200
|
+
const expiresAt = options?.ttlSeconds && options.ttlSeconds > 0 ? Date.now() + options.ttlSeconds * 1e3 : void 0;
|
|
4201
|
+
this.store.set(key, { value, expiresAt });
|
|
4202
|
+
}
|
|
4203
|
+
async delete(key) {
|
|
4204
|
+
this.store.delete(key);
|
|
4205
|
+
}
|
|
4206
|
+
async deleteMany(keys) {
|
|
4207
|
+
keys.forEach((key) => this.store.delete(key));
|
|
4208
|
+
}
|
|
4209
|
+
async clear() {
|
|
4210
|
+
this.store.clear();
|
|
4211
|
+
}
|
|
4212
|
+
};
|
|
4213
|
+
|
|
4214
|
+
// src/ab/bucketing.ts
|
|
4215
|
+
var BUCKET_SPACE = 1e4;
|
|
4216
|
+
function bucketFor(visitorId, flagKey, version) {
|
|
4217
|
+
const input = `${visitorId}|${flagKey}|${version}`;
|
|
4218
|
+
const bytes = new TextEncoder().encode(input);
|
|
4219
|
+
let hash = 2166136261;
|
|
4220
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
4221
|
+
hash ^= bytes[i];
|
|
4222
|
+
hash = Math.imul(hash, 16777619);
|
|
4223
|
+
}
|
|
4224
|
+
return (hash >>> 0) % BUCKET_SPACE;
|
|
4225
|
+
}
|
|
4226
|
+
function variantForBucket(bucket, variants, trafficAllocationBp) {
|
|
4227
|
+
if (bucket >= trafficAllocationBp) return null;
|
|
4228
|
+
const sorted = [...variants].sort((a, b) => a.key < b.key ? -1 : 1);
|
|
4229
|
+
const totalWeight = sorted.reduce((acc, v) => acc + v.weightBp, 0);
|
|
4230
|
+
if (totalWeight <= 0) return null;
|
|
4231
|
+
const scaled = Math.floor(bucket * totalWeight / trafficAllocationBp);
|
|
4232
|
+
let cursor = 0;
|
|
4233
|
+
for (const v of sorted) {
|
|
4234
|
+
cursor += v.weightBp;
|
|
4235
|
+
if (scaled < cursor) return v.key;
|
|
4236
|
+
}
|
|
4237
|
+
return sorted[sorted.length - 1].key;
|
|
4238
|
+
}
|
|
4239
|
+
|
|
4240
|
+
// src/ab/ab-client.ts
|
|
4241
|
+
var CONFIG_TTL_SECONDS = 3600;
|
|
4242
|
+
var VID_COOKIE = "perspect_vid";
|
|
4243
|
+
var VID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 2;
|
|
4244
|
+
var BASE_URL_DEFAULT = "https://api.perspect.com";
|
|
4245
|
+
function createPerspectAb(options) {
|
|
4246
|
+
const { apiKey, siteName, ctx } = options;
|
|
4247
|
+
const baseUrl = (options.baseUrl ?? BASE_URL_DEFAULT).replace(/\/$/, "");
|
|
4248
|
+
return {
|
|
4249
|
+
async forRequest(request) {
|
|
4250
|
+
const { visitorId, mintedNew } = readOrMintVid(request);
|
|
4251
|
+
const responseHeaders = new Headers();
|
|
4252
|
+
if (mintedNew) {
|
|
4253
|
+
responseHeaders.append(
|
|
4254
|
+
"Set-Cookie",
|
|
4255
|
+
`${VID_COOKIE}=${visitorId}; Path=/; Max-Age=${VID_COOKIE_MAX_AGE}; SameSite=Lax; Secure; HttpOnly`
|
|
4256
|
+
);
|
|
4257
|
+
}
|
|
4258
|
+
const config = await getConfig(options.cache, apiKey, siteName, baseUrl);
|
|
4259
|
+
return { ab: buildAbClient(apiKey, siteName, baseUrl, ctx, config, visitorId), responseHeaders };
|
|
4260
|
+
},
|
|
4261
|
+
async refreshConfig() {
|
|
4262
|
+
await fetchAndStoreConfig(options.cache, apiKey, siteName, baseUrl);
|
|
4263
|
+
}
|
|
4264
|
+
};
|
|
4265
|
+
}
|
|
4266
|
+
function buildAbClient(apiKey, siteName, baseUrl, ctx, config, visitorId) {
|
|
4267
|
+
return {
|
|
4268
|
+
async getVariant(flagKey) {
|
|
4269
|
+
const flag = config.flags[flagKey];
|
|
4270
|
+
if (!flag || flag.status !== "running") {
|
|
4271
|
+
return { variant: flag?.defaultVariant ?? null, enrolled: false, config: null };
|
|
4272
|
+
}
|
|
4273
|
+
const bucket = bucketFor(visitorId, flagKey, flag.currentVersion);
|
|
4274
|
+
const assigned = variantForBucket(bucket, flag.variants, flag.trafficAllocationBp);
|
|
4275
|
+
if (assigned === null) {
|
|
4276
|
+
return { variant: flag.defaultVariant, enrolled: false, config: null };
|
|
4277
|
+
}
|
|
4278
|
+
const variantCfg = flag.variants.find((v) => v.key === assigned)?.config ?? null;
|
|
4279
|
+
emit(apiKey, baseUrl, ctx, {
|
|
4280
|
+
site: siteName,
|
|
4281
|
+
kind: "exposure",
|
|
4282
|
+
flag: flagKey,
|
|
4283
|
+
version: flag.currentVersion,
|
|
4284
|
+
variant: assigned,
|
|
4285
|
+
visitorId,
|
|
4286
|
+
dedup: await dedupFor(visitorId, flagKey, flag.currentVersion, assigned, "exposure"),
|
|
4287
|
+
ts: Math.floor(Date.now() / 1e3)
|
|
4288
|
+
});
|
|
4289
|
+
return { variant: assigned, enrolled: true, config: variantCfg };
|
|
4290
|
+
},
|
|
4291
|
+
async track(event, properties) {
|
|
4292
|
+
for (const [flagKey, flag] of Object.entries(config.flags)) {
|
|
4293
|
+
if (flag.status !== "running") continue;
|
|
4294
|
+
const goals = flag.goalsByVersion[String(flag.currentVersion)] ?? [];
|
|
4295
|
+
if (!goals.includes(event)) continue;
|
|
4296
|
+
const bucket = bucketFor(visitorId, flagKey, flag.currentVersion);
|
|
4297
|
+
const assigned = variantForBucket(bucket, flag.variants, flag.trafficAllocationBp);
|
|
4298
|
+
if (assigned === null) continue;
|
|
4299
|
+
emit(apiKey, baseUrl, ctx, {
|
|
4300
|
+
site: siteName,
|
|
4301
|
+
kind: "conversion",
|
|
4302
|
+
flag: flagKey,
|
|
4303
|
+
version: flag.currentVersion,
|
|
4304
|
+
variant: assigned,
|
|
4305
|
+
visitorId,
|
|
4306
|
+
event,
|
|
4307
|
+
dedup: await dedupFor(visitorId, flagKey, flag.currentVersion, assigned, event),
|
|
4308
|
+
ts: Math.floor(Date.now() / 1e3),
|
|
4309
|
+
properties
|
|
4310
|
+
});
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
function configCacheKey(siteName) {
|
|
4316
|
+
return `ab:config:${siteName}`;
|
|
4317
|
+
}
|
|
4318
|
+
async function getConfig(cache, apiKey, siteName, baseUrl) {
|
|
4319
|
+
if (cache) {
|
|
4320
|
+
const raw = await cache.get(configCacheKey(siteName));
|
|
4321
|
+
if (raw) return JSON.parse(raw);
|
|
4322
|
+
}
|
|
4323
|
+
return fetchAndStoreConfig(cache, apiKey, siteName, baseUrl);
|
|
4324
|
+
}
|
|
4325
|
+
async function fetchAndStoreConfig(cache, apiKey, siteName, baseUrl) {
|
|
4326
|
+
const res = await fetch(`${baseUrl}/_ab/config?site=${encodeURIComponent(siteName)}`, {
|
|
4327
|
+
headers: { "x-api-key": apiKey }
|
|
4328
|
+
});
|
|
4329
|
+
if (!res.ok) return { schemaVersion: 1, flags: {} };
|
|
4330
|
+
const config = await res.json();
|
|
4331
|
+
if (cache) {
|
|
4332
|
+
await cache.set(configCacheKey(siteName), JSON.stringify(config), { ttlSeconds: CONFIG_TTL_SECONDS });
|
|
4333
|
+
}
|
|
4334
|
+
return config;
|
|
4335
|
+
}
|
|
4336
|
+
function emit(apiKey, baseUrl, ctx, body) {
|
|
4337
|
+
const task = fetch(`${baseUrl}/_ab/event`, {
|
|
4338
|
+
method: "POST",
|
|
4339
|
+
headers: { "content-type": "application/json", "x-api-key": apiKey },
|
|
4340
|
+
body: JSON.stringify(body)
|
|
4341
|
+
}).then(() => void 0).catch(() => void 0);
|
|
4342
|
+
if (ctx) ctx.waitUntil(task);
|
|
4343
|
+
}
|
|
4344
|
+
function readOrMintVid(request) {
|
|
4345
|
+
const cookie = request.headers.get("cookie") ?? "";
|
|
4346
|
+
const match = cookie.match(/(?:^|; )perspect_vid=([^;]+)/);
|
|
4347
|
+
if (match) return { visitorId: decodeURIComponent(match[1]), mintedNew: false };
|
|
4348
|
+
return { visitorId: crypto.randomUUID().replace(/-/g, ""), mintedNew: true };
|
|
4349
|
+
}
|
|
4350
|
+
async function dedupFor(visitorId, flagKey, version, variant, event) {
|
|
4351
|
+
const input = `${visitorId}|${flagKey}|${version}|${variant}|${event}`;
|
|
4352
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
4353
|
+
const bytes = new Uint8Array(digest);
|
|
4354
|
+
let hex = "";
|
|
4355
|
+
for (let i = 0; i < 16; i++) hex += bytes[i].toString(16).padStart(2, "0");
|
|
4356
|
+
return hex;
|
|
4357
|
+
}
|
|
4358
|
+
|
|
4142
4359
|
// src/utils/image-transform.ts
|
|
4143
4360
|
var DEFAULT_IMAGE_SIZES = {
|
|
4144
4361
|
thumbnail: {
|
|
@@ -4810,11 +5027,13 @@ async function createCheckoutSession(options) {
|
|
|
4810
5027
|
ContentClient,
|
|
4811
5028
|
DEFAULT_IMAGE_SIZES,
|
|
4812
5029
|
HttpClient,
|
|
5030
|
+
InMemoryCacheAdapter,
|
|
4813
5031
|
NewsletterClient,
|
|
4814
5032
|
NewsletterManagementClient,
|
|
4815
5033
|
NoopCacheAdapter,
|
|
4816
5034
|
OrganizationsClient,
|
|
4817
5035
|
PerspectApiClient,
|
|
5036
|
+
PerspectApiError,
|
|
4818
5037
|
PerspectApiV2Client,
|
|
4819
5038
|
PerspectV2Error,
|
|
4820
5039
|
ProductsClient,
|
|
@@ -4823,9 +5042,11 @@ async function createCheckoutSession(options) {
|
|
|
4823
5042
|
V1_DEPRECATION_NOTICE,
|
|
4824
5043
|
V1_SUNSET_DATE,
|
|
4825
5044
|
WebhooksClient,
|
|
5045
|
+
bucketFor,
|
|
4826
5046
|
buildImageUrl,
|
|
4827
5047
|
createApiError,
|
|
4828
5048
|
createCheckoutSession,
|
|
5049
|
+
createPerspectAb,
|
|
4829
5050
|
createPerspectApiClient,
|
|
4830
5051
|
createPerspectApiV2Client,
|
|
4831
5052
|
generateResponsiveImageHtml,
|
|
@@ -4842,5 +5063,6 @@ async function createCheckoutSession(options) {
|
|
|
4842
5063
|
loadProducts,
|
|
4843
5064
|
transformContent,
|
|
4844
5065
|
transformMediaItem,
|
|
4845
|
-
transformProduct
|
|
5066
|
+
transformProduct,
|
|
5067
|
+
variantForBucket
|
|
4846
5068
|
});
|