@kerne/react 1.0.0 → 1.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.
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React, { ReactNode, Component, ErrorInfo } from 'react';
3
- import { KerneConfig, JoinWaitlistParams, ValidateTokenResponse, ValidateCodeResponse } from '@kerne/server';
3
+ import { KerneConfig, ConsumeParams, ReportUsageParams, ReportUsageBatchEvent, BatchUsageResult, JoinWaitlistParams, ValidateTokenResponse, ValidateCodeResponse } from '@kerne/server';
4
4
  export { JoinWaitlistParams, ValidateCodeResponse, ValidateTokenResponse, WaitlistEntry } from '@kerne/server';
5
5
  import * as _kerne_types from '@kerne/types';
6
- import { User, AuthResponse, ActivationContext, AuthConfig, EntitlementCheck, SubscriptionWithPlan, Subscription, PublicPlan, Entitlements, UsageRecord } from '@kerne/types';
7
- export { ActivationContext, AuthConfig, AuthResponse, EntitlementCheck, Entitlements, PublicPlan, Subscription, SubscriptionWithPlan, UsageRecord, User } from '@kerne/types';
8
- import { D as DeepPartial, K as KerneLocalization } from './i18n-Di5qlnL1.js';
9
- export { d as defaultLocalization } from './i18n-Di5qlnL1.js';
6
+ import { User, AuthResponse, ActivationContext, AuthConfig, EntitlementCheck, UsageRecord, SubscriptionWithPlan, Subscription, PublicPlan, Entitlements, PublicPlanPrice } from '@kerne/types';
7
+ export { ActivationContext, AuthConfig, AuthResponse, BatchUsageResult, EntitlementCheck, Entitlements, PublicPlan, Subscription, SubscriptionWithPlan, UsageRecord, User, ValidationFieldError } from '@kerne/types';
8
+ import { D as DeepPartial, K as KerneLocalization } from './i18n-CXEhPK58.js';
9
+ export { d as defaultLocalization } from './i18n-CXEhPK58.js';
10
10
 
11
11
  interface KerneReactConfig extends Omit<KerneConfig, 'secretKey'> {
12
12
  storage?: Storage;
@@ -166,6 +166,13 @@ declare class KerneClient {
166
166
  allows(featureKey: string, requested?: number): Promise<boolean>;
167
167
  /** Full entitlement detail (limit/used/remaining/overage) - use `allows()` for a plain boolean. */
168
168
  check(featureKey: string, requested?: number): Promise<EntitlementCheck>;
169
+ /** Atomically check a QUOTA limit and commit the consumption. Reports for the signed-in subject. */
170
+ consume(featureKey: string, params?: Omit<ConsumeParams, 'subject'>): Promise<EntitlementCheck>;
171
+ /** Report usage without a limit check, for the signed-in subject. See `reportUsageBatch()` for many at once. */
172
+ reportUsage(featureKey: string, params?: Omit<ReportUsageParams, 'subject'>): Promise<UsageRecord>;
173
+ /** Several usage events in one request instead of one call each - kills the manual request staggering. */
174
+ reportUsageBatch(events: Array<Omit<ReportUsageBatchEvent, 'subject'>>): Promise<BatchUsageResult[]>;
175
+ private requireUserId;
169
176
  createCheckout(planPriceId: string, options?: {
170
177
  successUrl?: string;
171
178
  cancelUrl?: string;
@@ -344,6 +351,51 @@ declare function useChangePlan(): {
344
351
  }) => Promise<SubscriptionWithPlan>;
345
352
  isChanging: boolean;
346
353
  };
354
+ interface PlanSwitchTarget {
355
+ plan: PublicPlan;
356
+ price: PublicPlanPrice;
357
+ }
358
+ /**
359
+ * The decision every "pick a plan" surface needs, shared so it is only
360
+ * decided once: an existing subscriber switching plans has to swap in place
361
+ * (`changePlanPrice`), never start a fresh checkout - Stripe/Polar don't know
362
+ * about the subscription already on file, so a new checkout session creates
363
+ * a SECOND, independent one instead of replacing it. The old one stays live
364
+ * and billed at the provider while Kerne only ever tracks the new one. A
365
+ * first-time subscriber has nothing to swap, so that case goes straight to
366
+ * checkout, same as before.
367
+ *
368
+ * The switch is staged rather than applied on `selectPlan` alone - it bills
369
+ * immediately on confirmation (unlike checkout, which only starts billing
370
+ * once the provider's own page is completed), so the caller's UI gets a
371
+ * chance to say so before `confirmSwitch()` commits it.
372
+ *
373
+ * @param subscription the subject's current subscription, or null - pass
374
+ * what `useSubscription()` already returned rather than fetching it again
375
+ * here, so a page showing the current plan and this hook always agree.
376
+ * @param refetchSubscription called after a successful switch, typically
377
+ * that same `useSubscription()` call's own `refetch()`.
378
+ *
379
+ * @example
380
+ * ```tsx
381
+ * const { subscription, refetch } = useSubscription();
382
+ * const { pending, switching, selectPlan, confirmSwitch, dismissSwitch } =
383
+ * usePlanSwitch(subscription, refetch);
384
+ * ```
385
+ */
386
+ declare function usePlanSwitch(subscription: SubscriptionWithPlan | null, refetchSubscription: () => void, options?: {
387
+ successUrl?: string;
388
+ cancelUrl?: string;
389
+ }): {
390
+ pending: PlanSwitchTarget | null;
391
+ switching: boolean;
392
+ switchError: unknown;
393
+ checkoutPriceId: string | null;
394
+ checkoutError: unknown;
395
+ selectPlan: (plan: PublicPlan, price: PublicPlanPrice) => Promise<void>;
396
+ confirmSwitch: () => Promise<void>;
397
+ dismissSwitch: () => void;
398
+ };
347
399
  /**
348
400
  * Whether the current scope has access to one feature - the single entry
349
401
  * point for a live, per-feature decision. Deliberately not named after what
@@ -450,6 +502,24 @@ declare function useUsage(featureKey?: string): {
450
502
  isLoading: boolean;
451
503
  error: Error | null;
452
504
  };
505
+ /**
506
+ * Usage write path for the signed-in user: `consume()` gates a QUOTA and commits
507
+ * in one step, `report()`/`reportBatch()` record usage without a check.
508
+ * `reportBatch()` sends many events in one request - the fix for hand-rolled
509
+ * request staggering in a component reporting several rows at once.
510
+ *
511
+ * @example
512
+ * ```tsx
513
+ * const { consume, reportBatch } = useReportUsage();
514
+ * await consume('exports', { delta: 1 });
515
+ * await reportBatch(machines.map((m) => ({ featureKey: 'machine_minutes', delta: m.minutes })));
516
+ * ```
517
+ */
518
+ declare function useReportUsage(): {
519
+ consume: (featureKey: string, params?: Omit<ConsumeParams, "subject">) => Promise<EntitlementCheck>;
520
+ report: (featureKey: string, params?: Omit<ReportUsageParams, "subject">) => Promise<UsageRecord>;
521
+ reportBatch: (events: Array<Omit<ReportUsageBatchEvent, "subject">>) => Promise<_kerne_types.BatchUsageResult[]>;
522
+ };
453
523
  /**
454
524
  * Waitlist signup form - a mutation, not a data fetch, same shape as
455
525
  * `useCheckout`/`usePortal`.
@@ -691,4 +761,4 @@ declare function useKerneError(): {
691
761
  clearError: () => void;
692
762
  };
693
763
 
694
- export { Access, AuthLoading, Authenticated, HasSubscription, KerneClient, KerneContext, type KerneError, KerneErrorBoundary, KerneLocalization, KerneProvider, type KerneProviderProps, type KerneReactConfig, Protected, Unauthenticated, useAccess, useAuth, useAuthConfig, useCancelSubscription, useChangePlan, useCheckout, useClient, useEntitlements, useInvitation, useKerneError, usePlans, usePortal, useSubscription, useUsage, useUser, useWaitlist };
764
+ export { Access, AuthLoading, Authenticated, HasSubscription, KerneClient, KerneContext, type KerneError, KerneErrorBoundary, KerneLocalization, KerneProvider, type KerneProviderProps, type KerneReactConfig, type PlanSwitchTarget, Protected, Unauthenticated, useAccess, useAuth, useAuthConfig, useCancelSubscription, useChangePlan, useCheckout, useClient, useEntitlements, useInvitation, useKerneError, usePlanSwitch, usePlans, usePortal, useReportUsage, useSubscription, useUsage, useUser, useWaitlist };
package/dist/index.js CHANGED
@@ -13,13 +13,15 @@ import {
13
13
  useClient,
14
14
  useEntitlements,
15
15
  useInvitation,
16
+ usePlanSwitch,
16
17
  usePlans,
17
18
  usePortal,
19
+ useReportUsage,
18
20
  useSubscription,
19
21
  useUsage,
20
22
  useUser,
21
23
  useWaitlist
22
- } from "./chunk-NFJ2S5VJ.js";
24
+ } from "./chunk-IHNWY4ML.js";
23
25
 
24
26
  // src/components.tsx
25
27
  import React from "react";
@@ -173,8 +175,10 @@ export {
173
175
  useEntitlements,
174
176
  useInvitation,
175
177
  useKerneError,
178
+ usePlanSwitch,
176
179
  usePlans,
177
180
  usePortal,
181
+ useReportUsage,
178
182
  useSubscription,
179
183
  useUsage,
180
184
  useUser,