@cross-deck/web 1.4.2 → 1.5.1

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 (45) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +94 -0
  3. package/dist/contracts 2.json +378 -0
  4. package/dist/contracts.json +378 -0
  5. package/dist/crossdeck.umd.min 2.js +3 -0
  6. package/dist/crossdeck.umd.min.js +2 -2
  7. package/dist/crossdeck.umd.min.js 2.map +1 -0
  8. package/dist/crossdeck.umd.min.js.map +1 -1
  9. package/dist/error-codes 2.json +196 -0
  10. package/dist/error-codes.json +1 -1
  11. package/dist/index 2.cjs +4778 -0
  12. package/dist/index 2.mjs +4742 -0
  13. package/dist/index.cjs +457 -0
  14. package/dist/index.cjs 2.map +1 -0
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d 2.mts +938 -0
  17. package/dist/index.d 2.ts +938 -0
  18. package/dist/index.d.mts +174 -1
  19. package/dist/index.d.ts +174 -1
  20. package/dist/index.mjs +456 -0
  21. package/dist/index.mjs 2.map +1 -0
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/react 2.cjs +4220 -0
  24. package/dist/react 2.mjs +4193 -0
  25. package/dist/react.cjs +31 -0
  26. package/dist/react.cjs 2.map +1 -0
  27. package/dist/react.cjs.map +1 -1
  28. package/dist/react.d 2.mts +91 -0
  29. package/dist/react.d 2.ts +91 -0
  30. package/dist/react.mjs +31 -0
  31. package/dist/react.mjs 2.map +1 -0
  32. package/dist/react.mjs.map +1 -1
  33. package/dist/types-Bu3jbmdq.d 2.mts +314 -0
  34. package/dist/types-Bu3jbmdq.d 2.ts +314 -0
  35. package/dist/vue 2.cjs +4185 -0
  36. package/dist/vue 2.mjs +4159 -0
  37. package/dist/vue.cjs +31 -0
  38. package/dist/vue.cjs 2.map +1 -0
  39. package/dist/vue.cjs.map +1 -1
  40. package/dist/vue.d 2.mts +37 -0
  41. package/dist/vue.d 2.ts +37 -0
  42. package/dist/vue.mjs +31 -0
  43. package/dist/vue.mjs 2.map +1 -0
  44. package/dist/vue.mjs.map +1 -1
  45. package/package.json +3 -2
@@ -0,0 +1,91 @@
1
+ import { ReactNode } from 'react';
2
+ import { C as CrossdeckOptions } from './types-Bu3jbmdq.mjs';
3
+
4
+ /**
5
+ * @cross-deck/web/react — React hooks for the Crossdeck SDK.
6
+ *
7
+ * Why this exists: `Crossdeck.isEntitled("pro")` is a synchronous cache
8
+ * read, but the cache populates asynchronously after `getEntitlements()`
9
+ * lands. React has no way to know the cache changed, so a component
10
+ * that calls `isEntitled` directly in a render path would show the
11
+ * empty-cache result forever (until something else triggered a re-render).
12
+ *
13
+ * The `useEntitlement` hook below ties cache state to React state via
14
+ * `onEntitlementsChange`, so the component re-renders the moment the
15
+ * answer changes. After the first render, every subsequent check is a
16
+ * sync cache hit — exactly the "microsecond entitlement check" the
17
+ * SDK promises.
18
+ *
19
+ * Side effect: importing this module pulls in `react` as a peer
20
+ * dependency. Consumers who don't use React shouldn't import it.
21
+ *
22
+ * SSR safety: `useEffect` is a no-op during server-side rendering, and
23
+ * the initial state is conservative (`false` until proven otherwise),
24
+ * so server output never claims a non-existent entitlement. The hook
25
+ * hydrates correctly on the client.
26
+ *
27
+ * NorthStar §11.4 (reactive bindings): every SDK ships first-class
28
+ * framework bindings so the canonical snippet stays one line. Web =>
29
+ * React hook here. iOS => `@Observable` SwiftUI wrapper (when iOS SDK
30
+ * ships). Android => Compose `State<Boolean>` wrapper (when Android
31
+ * SDK ships).
32
+ */
33
+
34
+ interface CrossdeckProviderProps extends Omit<CrossdeckOptions, "userId"> {
35
+ /**
36
+ * Optional. When defined, the provider calls Crossdeck.identify(userId)
37
+ * after init and on every change. When the prop flips back to undefined
38
+ * (logout), the provider calls Crossdeck.reset().
39
+ *
40
+ * Pass your auth library's stable user id directly:
41
+ * <CrossdeckProvider userId={session?.user?.id} … /> // NextAuth
42
+ * <CrossdeckProvider userId={user?.uid} … /> // Firebase
43
+ * <CrossdeckProvider userId={supabase.auth.user()?.id} … /> // Supabase
44
+ *
45
+ * Anonymous (pre-login) traffic stays anonymous until userId becomes
46
+ * defined — the SDK's anonymousId follows the same user record once
47
+ * identify lands, so attribution survives sign-up.
48
+ */
49
+ userId?: string | null | undefined;
50
+ children: ReactNode;
51
+ }
52
+ declare function CrossdeckProvider(props: CrossdeckProviderProps): ReactNode;
53
+ /**
54
+ * Subscribe a React component to a single entitlement key.
55
+ *
56
+ * The hook returns the current `isEntitled(key)` value AND keeps it in
57
+ * sync with the cache. When `getEntitlements()` lands, when a purchase
58
+ * adds an entitlement, or when `reset()` is called on logout, every
59
+ * component using this hook re-renders to reflect the change.
60
+ *
61
+ * Usage:
62
+ *
63
+ * import { useEntitlement } from "@cross-deck/web/react";
64
+ *
65
+ * function ProBadge() {
66
+ * const isPro = useEntitlement("pro");
67
+ * return isPro ? <span className="badge">Pro</span> : null;
68
+ * }
69
+ *
70
+ * Note that the hook does NOT call `getEntitlements()` itself — that's
71
+ * a one-time boot warm-up the consumer is expected to trigger after
72
+ * `Crossdeck.init()` (typically inside a top-level effect in their
73
+ * Providers wrapper). Once warmed, every component using this hook
74
+ * gets the answer for free.
75
+ *
76
+ * Pre-init: returns `false`. Calling Crossdeck.init() later doesn't
77
+ * automatically refresh existing hook instances — but as soon as
78
+ * something mutates the cache (i.e. after a successful
79
+ * getEntitlements() call on the new SDK instance), the hook fires.
80
+ */
81
+ declare function useEntitlement(key: string): boolean;
82
+ /**
83
+ * Subscribe to the full entitlement list. Returns an array of active
84
+ * entitlement keys, kept in sync with the cache. Useful for iterating
85
+ * (e.g. rendering a list of unlocked features in a settings page).
86
+ *
87
+ * Same pre-init / SSR semantics as `useEntitlement`.
88
+ */
89
+ declare function useEntitlements(): readonly string[];
90
+
91
+ export { CrossdeckProvider, useEntitlement, useEntitlements };
@@ -0,0 +1,91 @@
1
+ import { ReactNode } from 'react';
2
+ import { C as CrossdeckOptions } from './types-Bu3jbmdq.js';
3
+
4
+ /**
5
+ * @cross-deck/web/react — React hooks for the Crossdeck SDK.
6
+ *
7
+ * Why this exists: `Crossdeck.isEntitled("pro")` is a synchronous cache
8
+ * read, but the cache populates asynchronously after `getEntitlements()`
9
+ * lands. React has no way to know the cache changed, so a component
10
+ * that calls `isEntitled` directly in a render path would show the
11
+ * empty-cache result forever (until something else triggered a re-render).
12
+ *
13
+ * The `useEntitlement` hook below ties cache state to React state via
14
+ * `onEntitlementsChange`, so the component re-renders the moment the
15
+ * answer changes. After the first render, every subsequent check is a
16
+ * sync cache hit — exactly the "microsecond entitlement check" the
17
+ * SDK promises.
18
+ *
19
+ * Side effect: importing this module pulls in `react` as a peer
20
+ * dependency. Consumers who don't use React shouldn't import it.
21
+ *
22
+ * SSR safety: `useEffect` is a no-op during server-side rendering, and
23
+ * the initial state is conservative (`false` until proven otherwise),
24
+ * so server output never claims a non-existent entitlement. The hook
25
+ * hydrates correctly on the client.
26
+ *
27
+ * NorthStar §11.4 (reactive bindings): every SDK ships first-class
28
+ * framework bindings so the canonical snippet stays one line. Web =>
29
+ * React hook here. iOS => `@Observable` SwiftUI wrapper (when iOS SDK
30
+ * ships). Android => Compose `State<Boolean>` wrapper (when Android
31
+ * SDK ships).
32
+ */
33
+
34
+ interface CrossdeckProviderProps extends Omit<CrossdeckOptions, "userId"> {
35
+ /**
36
+ * Optional. When defined, the provider calls Crossdeck.identify(userId)
37
+ * after init and on every change. When the prop flips back to undefined
38
+ * (logout), the provider calls Crossdeck.reset().
39
+ *
40
+ * Pass your auth library's stable user id directly:
41
+ * <CrossdeckProvider userId={session?.user?.id} … /> // NextAuth
42
+ * <CrossdeckProvider userId={user?.uid} … /> // Firebase
43
+ * <CrossdeckProvider userId={supabase.auth.user()?.id} … /> // Supabase
44
+ *
45
+ * Anonymous (pre-login) traffic stays anonymous until userId becomes
46
+ * defined — the SDK's anonymousId follows the same user record once
47
+ * identify lands, so attribution survives sign-up.
48
+ */
49
+ userId?: string | null | undefined;
50
+ children: ReactNode;
51
+ }
52
+ declare function CrossdeckProvider(props: CrossdeckProviderProps): ReactNode;
53
+ /**
54
+ * Subscribe a React component to a single entitlement key.
55
+ *
56
+ * The hook returns the current `isEntitled(key)` value AND keeps it in
57
+ * sync with the cache. When `getEntitlements()` lands, when a purchase
58
+ * adds an entitlement, or when `reset()` is called on logout, every
59
+ * component using this hook re-renders to reflect the change.
60
+ *
61
+ * Usage:
62
+ *
63
+ * import { useEntitlement } from "@cross-deck/web/react";
64
+ *
65
+ * function ProBadge() {
66
+ * const isPro = useEntitlement("pro");
67
+ * return isPro ? <span className="badge">Pro</span> : null;
68
+ * }
69
+ *
70
+ * Note that the hook does NOT call `getEntitlements()` itself — that's
71
+ * a one-time boot warm-up the consumer is expected to trigger after
72
+ * `Crossdeck.init()` (typically inside a top-level effect in their
73
+ * Providers wrapper). Once warmed, every component using this hook
74
+ * gets the answer for free.
75
+ *
76
+ * Pre-init: returns `false`. Calling Crossdeck.init() later doesn't
77
+ * automatically refresh existing hook instances — but as soon as
78
+ * something mutates the cache (i.e. after a successful
79
+ * getEntitlements() call on the new SDK instance), the hook fires.
80
+ */
81
+ declare function useEntitlement(key: string): boolean;
82
+ /**
83
+ * Subscribe to the full entitlement list. Returns an array of active
84
+ * entitlement keys, kept in sync with the cache. Useful for iterating
85
+ * (e.g. rendering a list of unlocked features in a settings page).
86
+ *
87
+ * Same pre-init / SSR semantics as `useEntitlement`.
88
+ */
89
+ declare function useEntitlements(): readonly string[];
90
+
91
+ export { CrossdeckProvider, useEntitlement, useEntitlements };
package/dist/react.mjs CHANGED
@@ -3676,6 +3676,37 @@ var CrossdeckClient = class {
3676
3676
  * trip happens in the background. To flush before the page unloads,
3677
3677
  * call flush().
3678
3678
  */
3679
+ /**
3680
+ * Emit `crossdeck.contract_failed` with the canonical property
3681
+ * shape (`contract_id`, `sdk_version`, `sdk_platform`,
3682
+ * `failure_reason`, `run_context`, `run_id`). Goes through the
3683
+ * standard track() pipeline — same consent gate, same queue,
3684
+ * same ingest, no new endpoint.
3685
+ *
3686
+ * Wire the call from a test hook, dogfood failure path, or
3687
+ * customer contract-verification harness; see
3688
+ * `contracts/README.md` for the per-test-framework hook recipes.
3689
+ */
3690
+ reportContractFailure(input) {
3691
+ const props = {
3692
+ contract_id: input.contractId,
3693
+ sdk_version: SDK_VERSION,
3694
+ sdk_platform: "web",
3695
+ failure_reason: input.failureReason,
3696
+ run_context: input.runContext,
3697
+ run_id: input.runId
3698
+ };
3699
+ if (input.testRef) {
3700
+ props.test_file = input.testRef.file;
3701
+ props.test_name = input.testRef.name;
3702
+ }
3703
+ if (input.extra) {
3704
+ for (const [k, v] of Object.entries(input.extra)) {
3705
+ if (props[k] === void 0) props[k] = v;
3706
+ }
3707
+ }
3708
+ this.track("crossdeck.contract_failed", props);
3709
+ }
3679
3710
  track(name, properties) {
3680
3711
  const s = this.requireStarted();
3681
3712
  if (!name) {