@proveanything/smartlinks 2.0.6 → 2.0.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.
Files changed (179) hide show
  1. package/dist/api/ai.d.ts +1 -1
  2. package/dist/api/ai.js +1 -1
  3. package/dist/api/analytics.d.ts +1 -1
  4. package/dist/api/analytics.js +1 -1
  5. package/dist/api/appConfiguration.d.ts +3 -3
  6. package/dist/api/appConfiguration.js +3 -3
  7. package/dist/api/appObjects.d.ts +1 -1
  8. package/dist/api/appObjects.js +1 -1
  9. package/dist/api/asset.d.ts +1 -1
  10. package/dist/api/asset.js +2 -2
  11. package/dist/api/async.d.ts +1 -1
  12. package/dist/api/async.js +1 -1
  13. package/dist/api/attestation.d.ts +1 -1
  14. package/dist/api/attestation.js +1 -1
  15. package/dist/api/attestations.d.ts +1 -1
  16. package/dist/api/attestations.js +1 -1
  17. package/dist/api/auth.d.ts +2 -2
  18. package/dist/api/auth.js +2 -2
  19. package/dist/api/authKit.d.ts +1 -1
  20. package/dist/api/authKit.js +1 -1
  21. package/dist/api/batch.d.ts +1 -1
  22. package/dist/api/batch.js +1 -1
  23. package/dist/api/broadcasts.d.ts +2 -2
  24. package/dist/api/broadcasts.js +1 -1
  25. package/dist/api/claimSet.d.ts +1 -1
  26. package/dist/api/claimSet.js +1 -1
  27. package/dist/api/collection.d.ts +1 -1
  28. package/dist/api/collection.js +1 -1
  29. package/dist/api/comms.d.ts +15 -15
  30. package/dist/api/comms.js +1 -1
  31. package/dist/api/config.d.ts +1 -1
  32. package/dist/api/config.js +1 -1
  33. package/dist/api/contact.d.ts +1 -1
  34. package/dist/api/contact.js +1 -1
  35. package/dist/api/containers.d.ts +1 -1
  36. package/dist/api/containers.js +1 -1
  37. package/dist/api/crate.d.ts +1 -1
  38. package/dist/api/crate.js +1 -1
  39. package/dist/api/facets.d.ts +1 -1
  40. package/dist/api/facets.js +1 -1
  41. package/dist/api/form.js +1 -1
  42. package/dist/api/http.js +1 -1
  43. package/dist/api/index.d.ts +46 -46
  44. package/dist/api/index.js +46 -46
  45. package/dist/api/integrations.d.ts +1 -1
  46. package/dist/api/integrations.js +1 -1
  47. package/dist/api/interactions.d.ts +1 -1
  48. package/dist/api/interactions.js +1 -1
  49. package/dist/api/jobs.d.ts +1 -1
  50. package/dist/api/jobs.js +1 -1
  51. package/dist/api/journeys.d.ts +1 -1
  52. package/dist/api/journeys.js +1 -1
  53. package/dist/api/journeysAnalytics.d.ts +1 -1
  54. package/dist/api/journeysAnalytics.js +1 -1
  55. package/dist/api/location.d.ts +1 -1
  56. package/dist/api/location.js +1 -1
  57. package/dist/api/lots.d.ts +1 -1
  58. package/dist/api/lots.js +1 -1
  59. package/dist/api/loyalty.d.ts +1 -1
  60. package/dist/api/loyalty.js +1 -1
  61. package/dist/api/navigation.d.ts +1 -1
  62. package/dist/api/navigation.js +1 -1
  63. package/dist/api/nfc.d.ts +1 -1
  64. package/dist/api/nfc.js +1 -1
  65. package/dist/api/order.d.ts +1 -1
  66. package/dist/api/order.js +1 -1
  67. package/dist/api/product.d.ts +1 -1
  68. package/dist/api/product.js +1 -1
  69. package/dist/api/products.d.ts +1 -1
  70. package/dist/api/products.js +1 -1
  71. package/dist/api/proof.d.ts +1 -1
  72. package/dist/api/proof.js +1 -1
  73. package/dist/api/qr.d.ts +1 -1
  74. package/dist/api/qr.js +1 -1
  75. package/dist/api/realtime.d.ts +1 -1
  76. package/dist/api/realtime.js +1 -1
  77. package/dist/api/research.d.ts +1 -1
  78. package/dist/api/research.js +1 -1
  79. package/dist/api/secrets.d.ts +1 -1
  80. package/dist/api/secrets.js +1 -1
  81. package/dist/api/segments.d.ts +1 -1
  82. package/dist/api/segments.js +1 -1
  83. package/dist/api/sequence.js +1 -1
  84. package/dist/api/tags.d.ts +1 -1
  85. package/dist/api/tags.js +1 -1
  86. package/dist/api/template.d.ts +1 -1
  87. package/dist/api/template.js +1 -1
  88. package/dist/api/translations.d.ts +1 -1
  89. package/dist/api/translations.js +2 -2
  90. package/dist/api/variant.d.ts +1 -1
  91. package/dist/api/variant.js +1 -1
  92. package/dist/containers/types.d.ts +1 -1
  93. package/dist/docs/API_SUMMARY.md +7 -7
  94. package/dist/docs/agent-tools.md +26 -14
  95. package/dist/docs/ai.md +14 -520
  96. package/dist/docs/analytics.md +41 -2
  97. package/dist/docs/app-data-storage.md +0 -38
  98. package/dist/docs/app-manifest.md +106 -7
  99. package/dist/docs/app-objects.md +0 -148
  100. package/dist/docs/app-records-pattern.md +2 -2
  101. package/dist/docs/building-react-components.md +6 -14
  102. package/dist/docs/caching.md +20 -21
  103. package/dist/docs/container-tracking.md +2 -0
  104. package/dist/docs/containers.md +14 -66
  105. package/dist/docs/executor.md +4 -4
  106. package/dist/docs/host-dependency-contract.md +27 -0
  107. package/dist/docs/iframe-responder.md +308 -0
  108. package/dist/docs/item-context.md +0 -2
  109. package/dist/docs/manifests.md +3 -3
  110. package/dist/docs/mobile-admin-container.md +4 -4
  111. package/dist/docs/mpa.md +5 -5
  112. package/dist/docs/native-facade.md +1 -1
  113. package/dist/docs/overview.md +35 -16
  114. package/dist/docs/portal-back-button.md +2 -3
  115. package/dist/docs/widgets.md +11 -69
  116. package/dist/http.d.ts +24 -8
  117. package/dist/http.js +32 -14
  118. package/dist/iframe.d.ts +2 -2
  119. package/dist/iframe.js +1 -1
  120. package/dist/iframeResponder.d.ts +7 -1
  121. package/dist/iframeResponder.js +45 -4
  122. package/dist/index.d.ts +30 -27
  123. package/dist/index.js +10 -8
  124. package/dist/mobile-admin/errors.d.ts +1 -1
  125. package/dist/mobile-admin/types.d.ts +2 -2
  126. package/dist/openapi.yaml +12 -0
  127. package/dist/shared-dependencies.d.ts +37 -0
  128. package/dist/shared-dependencies.js +79 -0
  129. package/dist/testing/index.d.ts +1 -1
  130. package/dist/translationCache.d.ts +1 -1
  131. package/dist/types/appManifest.d.ts +23 -0
  132. package/dist/types/broadcasts.d.ts +1 -1
  133. package/dist/types/collection.d.ts +2 -2
  134. package/dist/types/comms.d.ts +5 -5
  135. package/dist/types/contact.d.ts +1 -1
  136. package/dist/types/facets.d.ts +1 -1
  137. package/dist/types/iframeResponder.d.ts +3 -3
  138. package/dist/types/index.d.ts +44 -44
  139. package/dist/types/index.js +44 -44
  140. package/dist/types/interaction.d.ts +1 -1
  141. package/dist/types/itemContext.d.ts +1 -1
  142. package/dist/types/journeysAnalytics.d.ts +1 -1
  143. package/dist/types/navigation.d.ts +1 -1
  144. package/dist/types/product.d.ts +1 -1
  145. package/dist/types/proof.d.ts +1 -1
  146. package/dist/types/segments.d.ts +1 -1
  147. package/dist/types/widgets.d.ts +2 -2
  148. package/dist/utils/conditions.d.ts +1 -1
  149. package/dist/utils/index.d.ts +3 -3
  150. package/dist/utils/index.js +3 -3
  151. package/dist/utils/paths.d.ts +4 -4
  152. package/docs/API_SUMMARY.md +7 -7
  153. package/docs/agent-tools.md +26 -14
  154. package/docs/ai.md +14 -520
  155. package/docs/analytics.md +41 -2
  156. package/docs/app-data-storage.md +0 -38
  157. package/docs/app-manifest.md +106 -7
  158. package/docs/app-objects.md +0 -148
  159. package/docs/app-records-pattern.md +2 -2
  160. package/docs/building-react-components.md +6 -14
  161. package/docs/caching.md +20 -21
  162. package/docs/container-tracking.md +2 -0
  163. package/docs/containers.md +14 -66
  164. package/docs/executor.md +4 -4
  165. package/docs/host-dependency-contract.md +27 -0
  166. package/docs/iframe-responder.md +308 -0
  167. package/docs/item-context.md +0 -2
  168. package/docs/mobile-admin-container.md +4 -4
  169. package/docs/mpa.md +5 -5
  170. package/docs/native-facade.md +1 -1
  171. package/docs/overview.md +35 -16
  172. package/docs/portal-back-button.md +2 -3
  173. package/docs/widgets.md +11 -69
  174. package/openapi.yaml +12 -0
  175. package/package.json +17 -6
  176. package/scripts/doctor.mjs +171 -0
  177. package/docs/analytics-metadata-conventions.md +0 -88
  178. package/docs/iframe-streaming-parent-changes.md +0 -308
  179. package/docs/manifests.md +0 -204
@@ -14,7 +14,7 @@ Widgets are self-contained React components that:
14
14
 
15
15
  ```text
16
16
  ┌─────────────────────────────────────────────────────────────────┐
17
- │ Parent SmartLinks Portal (React 18) │
17
+ │ Parent SmartLinks Portal (React 19) │
18
18
  │ │
19
19
  │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
20
20
  │ │ Competition │ │ Music App │ │ Warranty │ │
@@ -53,53 +53,7 @@ Widgets are typically single-view components and don't need internal routing. If
53
53
 
54
54
  ### The `useAppContext()` Pattern
55
55
 
56
- To write widgets that work identically in both modes, use this abstraction pattern:
57
-
58
- ```tsx
59
- // src/hooks/useAppContext.ts
60
- import { useContext, createContext, useMemo } from 'react';
61
- import { useSearchParams } from 'react-router-dom';
62
-
63
- export interface AppContextValue {
64
- collectionId: string;
65
- appId: string;
66
- productId?: string;
67
- proofId?: string;
68
- pageId?: string;
69
- lang?: string;
70
- user?: { id: string; email: string; name?: string };
71
- SL: typeof import('@proveanything/smartlinks');
72
- onNavigate?: (request: any) => void;
73
- }
74
-
75
- export const AppContext = createContext<AppContextValue | null>(null);
76
-
77
- /**
78
- * Returns app context regardless of rendering mode.
79
- * - Direct component mode: reads from AppContext (props)
80
- * - Iframe mode: reads from URL search params
81
- */
82
- export function useAppContext(): AppContextValue {
83
- const ctx = useContext(AppContext);
84
-
85
- // If context exists, we're in direct-component mode
86
- if (ctx) return ctx;
87
-
88
- // Otherwise, we're in iframe mode — read from URL params
89
- const [searchParams] = useSearchParams();
90
- const SL = (window as any).SL ?? require('@proveanything/smartlinks');
91
-
92
- return useMemo(() => ({
93
- collectionId: searchParams.get('collectionId') ?? '',
94
- appId: searchParams.get('appId') ?? '',
95
- productId: searchParams.get('productId') ?? undefined,
96
- proofId: searchParams.get('proofId') ?? undefined,
97
- pageId: searchParams.get('pageId') ?? undefined,
98
- lang: searchParams.get('lang') ?? undefined,
99
- SL,
100
- }), [searchParams, SL]);
101
- }
102
- ```
56
+ Widgets read their context through the shared **`useAppContext()`** hook so the same code works in both direct-component and iframe modes. The hook and `AppContext` provider are defined once — see **[building-react-components.md](building-react-components.md#the-useappcontext-pattern)** for the full implementation (don't re-define it per app).
103
57
 
104
58
  **Usage in your widget:**
105
59
 
@@ -344,7 +298,7 @@ Declare support in `app.manifest.json`:
344
298
  "files": {
345
299
  "js": {
346
300
  "umd": "dist/widgets.umd.js",
347
- "esm": "dist/widgets.es.js"
301
+ "esm": "dist/widgets.esm.js"
348
302
  },
349
303
  "css": null
350
304
  },
@@ -511,7 +465,7 @@ export { MyWidget } from './MyWidget';
511
465
  // Update the manifest
512
466
  export const WIDGET_MANIFEST = {
513
467
  version: '1.0.0',
514
- reactVersion: '18.x',
468
+ reactVersion: '19.x',
515
469
  widgets: [
516
470
  // ... existing widgets
517
471
  {
@@ -570,7 +524,7 @@ The project includes a separate Vite config for building widgets:
570
524
  # Build widgets only
571
525
  vite build --config vite.config.widget.ts
572
526
 
573
- # Output: dist/widgets.es.js
527
+ # Output: dist/widgets.esm.js
574
528
  ```
575
529
 
576
530
  ### Build Configuration
@@ -582,23 +536,11 @@ The widget build:
582
536
  - Minifies with esbuild for production
583
537
  - Outputs to `/dist` alongside the main app (not a separate folder)
584
538
 
585
- ### Externalized Dependencies (Peer Dependencies)
586
-
587
- The widget bundle does **not** include these libraries—the parent app must provide them:
539
+ ### Externalized dependencies
588
540
 
589
- | Package | Why Externalized |
590
- |---------|------------------|
591
- | `react`, `react-dom` | Parent's React context |
592
- | `@proveanything/smartlinks` | Passed via props as `SL` |
593
- | `@proveanything/smartlinks-auth-ui` | Auth UI components (also available globally as `window.SmartlinksAuthUI`) |
594
- | `tailwind-merge` | Utility for merging Tailwind classes |
595
- | `clsx` | Utility for conditional class names |
596
- | `class-variance-authority` | Utility for component variants |
541
+ The widget bundle does **not** include the host's shared libraries (React, the SDK, Radix, LiquidJS, …) — it **externalizes** them and resolves them from the host at runtime, so the bundle stays tiny and there's exactly one shared instance.
597
542
 
598
- These are standard packages that any modern React + Tailwind app will have. Externalizing them:
599
- 1. Reduces bundle size significantly
600
- 2. Removes JSDoc comments that inflate the bundle
601
- 3. Ensures consistent behavior with parent's versions
543
+ **The canonical, versioned list is the shared-dependency contract — don't hand-maintain your own here.** Import it from the SDK (`SHARED_DEPENDENCY_SPECIFIERS`) for your build's `external` list, and see **[host-dependency-contract.md](host-dependency-contract.md)** for the full table, the Vite `external`/`globals` config, and the *never bundle your own React* rule. `@proveanything/smartlinks-auth-ui` is externalized too (host global `window.SmartlinksAuthUI`) — do not ship a second copy.
602
544
 
603
545
  ### Enabling Widget Builds
604
546
 
@@ -626,7 +568,7 @@ import * as SL from '@proveanything/smartlinks';
626
568
 
627
569
  // Dynamic import from app's CDN
628
570
  const CompetitionWidget = lazy(() =>
629
- import('https://competition-app.example.com/widgets.es.js')
571
+ import('https://competition-app.example.com/widgets.esm.js')
630
572
  .then(m => ({ default: m.CompetitionWidget }))
631
573
  );
632
574
 
@@ -670,7 +612,7 @@ import { WidgetWrapper, CompetitionWidget } from 'competition-app/widgets';
670
612
  import { WIDGET_MANIFEST } from 'competition-app/widgets';
671
613
 
672
614
  // Verify React version compatibility
673
- if (!WIDGET_MANIFEST.reactVersion.startsWith('18')) {
615
+ if (!WIDGET_MANIFEST.reactVersion.startsWith('19')) {
674
616
  console.warn('Widget React version mismatch');
675
617
  }
676
618
 
@@ -741,7 +683,7 @@ Each app exports a `WIDGET_MANIFEST` for discovery:
741
683
  ```typescript
742
684
  export const WIDGET_MANIFEST = {
743
685
  version: '1.0.0', // Widget bundle version
744
- reactVersion: '18.x', // Required React version
686
+ reactVersion: '19.x', // Required React version
745
687
  widgets: [
746
688
  {
747
689
  name: 'ExampleWidget',
package/dist/http.d.ts CHANGED
@@ -168,22 +168,38 @@ export declare function configureSdkCache(options: {
168
168
  serveStaleOnOffline?: boolean;
169
169
  clearOnPageLoad?: boolean;
170
170
  }): void;
171
+ /** Options for {@link invalidateCache}. */
172
+ export interface InvalidateCacheOptions {
173
+ /**
174
+ * Match the path **exactly** (ignoring any query string) instead of the default
175
+ * substring match. Use this to clear one resource without wiping everything
176
+ * nested under it — e.g. `invalidateCache('/collection/abc', { exact: true })`
177
+ * drops only that entry, not `/collection/abc/settings|widgets|products|proofs`.
178
+ */
179
+ exact?: boolean;
180
+ }
171
181
  /**
172
182
  * Manually invalidate entries in the SDK's GET cache.
173
183
  *
174
- * @param urlPattern - Optional substring match. Every cache entry whose key
175
- * *contains* this string is removed. Omit (or pass `undefined`) to wipe the
176
- * entire cache.
184
+ * Note: the GET cache is **in-memory, per page load** (with an optional L2
185
+ * IndexedDB layer when persistence is enabled) — it does not persist across
186
+ * reloads unless you opt into persistence, so it rarely needs disabling "for
187
+ * correctness".
188
+ *
189
+ * @param urlPattern - Substring match by default (every entry whose key
190
+ * *contains* this string is removed). With `{ exact: true }`, matches the path
191
+ * precisely. Omit to wipe the entire cache.
192
+ * @param options - See {@link InvalidateCacheOptions}.
177
193
  *
178
194
  * @example
179
195
  * ```ts
180
- * invalidateCache() // clear everything
181
- * invalidateCache('/collection/abc123') // one specific collection
182
- * invalidateCache('/product/') // all legacy singular product responses
183
- * invalidateCache('/products/') // all canonical plural product responses
196
+ * invalidateCache() // clear everything
197
+ * invalidateCache('/collection/abc123') // that collection AND everything under it
198
+ * invalidateCache('/collection/abc123', { exact: true }) // ONLY that collection entry
199
+ * invalidateCache('/products/') // all canonical plural product responses
184
200
  * ```
185
201
  */
186
- export declare function invalidateCache(urlPattern?: string): void;
202
+ export declare function invalidateCache(urlPattern?: string, options?: InvalidateCacheOptions): void;
187
203
  /**
188
204
  * Upload a FormData payload via proxy with progress events using chunked postMessage.
189
205
  * Parent is expected to implement the counterpart protocol.
package/dist/http.js CHANGED
@@ -25,8 +25,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
25
25
  function reject(value) { resume("throw", value); }
26
26
  function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
27
27
  };
28
- import { SmartlinksApiError, SmartlinksOfflineError } from "./types/error";
29
- import { idbGet, idbSet, idbClear } from './persistentCache';
28
+ import { SmartlinksApiError, SmartlinksOfflineError } from "./types/error.js";
29
+ import { idbGet, idbSet, idbClear } from './persistentCache.js';
30
30
  let baseURL = null;
31
31
  let apiKey = undefined;
32
32
  let bearerToken = undefined;
@@ -424,7 +424,7 @@ function normalizeErrorResponse(responseBody, statusCode) {
424
424
  * @property {string} [options.bearerToken] - (Optional) Bearer token for AUTHORIZATION header
425
425
  * @property {boolean} [options.proxyMode] - (Optional) Tells the API that it is running in an iframe via parent proxy
426
426
  */
427
- import { iframe } from './iframe';
427
+ import { iframe } from './iframe.js';
428
428
  export function initializeApi(options) {
429
429
  var _a;
430
430
  // Normalize baseURL by removing trailing slashes.
@@ -660,29 +660,47 @@ export function configureSdkCache(options) {
660
660
  /**
661
661
  * Manually invalidate entries in the SDK's GET cache.
662
662
  *
663
- * @param urlPattern - Optional substring match. Every cache entry whose key
664
- * *contains* this string is removed. Omit (or pass `undefined`) to wipe the
665
- * entire cache.
663
+ * Note: the GET cache is **in-memory, per page load** (with an optional L2
664
+ * IndexedDB layer when persistence is enabled) — it does not persist across
665
+ * reloads unless you opt into persistence, so it rarely needs disabling "for
666
+ * correctness".
667
+ *
668
+ * @param urlPattern - Substring match by default (every entry whose key
669
+ * *contains* this string is removed). With `{ exact: true }`, matches the path
670
+ * precisely. Omit to wipe the entire cache.
671
+ * @param options - See {@link InvalidateCacheOptions}.
666
672
  *
667
673
  * @example
668
674
  * ```ts
669
- * invalidateCache() // clear everything
670
- * invalidateCache('/collection/abc123') // one specific collection
671
- * invalidateCache('/product/') // all legacy singular product responses
672
- * invalidateCache('/products/') // all canonical plural product responses
675
+ * invalidateCache() // clear everything
676
+ * invalidateCache('/collection/abc123') // that collection AND everything under it
677
+ * invalidateCache('/collection/abc123', { exact: true }) // ONLY that collection entry
678
+ * invalidateCache('/products/') // all canonical plural product responses
673
679
  * ```
674
680
  */
675
- export function invalidateCache(urlPattern) {
681
+ export function invalidateCache(urlPattern, options) {
676
682
  if (!urlPattern) {
677
683
  clearHttpCache('invalidateCache(all)');
678
684
  if (cachePersistence !== 'none')
679
685
  idbClear().catch(() => { });
680
686
  return;
681
687
  }
682
- for (const key of httpCache.keys()) {
683
- if (key.includes(urlPattern))
684
- httpCache.delete(key);
688
+ if (options === null || options === void 0 ? void 0 : options.exact) {
689
+ const exactKey = buildCacheKey(urlPattern);
690
+ for (const key of httpCache.keys()) {
691
+ // Compare the path portion (drop query) so exact clears query variants of
692
+ // the same path but never sub-resources beneath it.
693
+ if (key.split('?')[0] === exactKey)
694
+ httpCache.delete(key);
695
+ }
696
+ }
697
+ else {
698
+ for (const key of httpCache.keys()) {
699
+ if (key.includes(urlPattern))
700
+ httpCache.delete(key);
701
+ }
685
702
  }
703
+ // L2 (IndexedDB) sweep remains substring-based; the exact win is the in-memory L1.
686
704
  if (cachePersistence !== 'none')
687
705
  idbClear(urlPattern).catch(() => { });
688
706
  }
package/dist/iframe.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder';
2
- export type { IframeResponderOptions, CachedData, CollectionApp, RouteChangeMessage, SmartlinksIframeMessage, ProxyRequest, CustomProxyRequest, UploadStartMessage, UploadChunkMessage, UploadEndMessage, } from './types/iframeResponder';
1
+ export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder.js';
2
+ export type { IframeResponderOptions, CachedData, CollectionApp, RouteChangeMessage, SmartlinksIframeMessage, ProxyRequest, CustomProxyRequest, UploadStartMessage, UploadChunkMessage, UploadEndMessage, } from './types/iframeResponder.js';
3
3
  export declare namespace iframe {
4
4
  interface IframeResizeOptions {
5
5
  /** Minimum ms between height postMessages (default 100). */
package/dist/iframe.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // These helpers are optional and safe in non-browser / Node environments.
4
4
  // They build on the existing proxyMode infrastructure but can also be used standalone.
5
5
  // Re-export IframeResponder for parent-side iframe communication
6
- export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder';
6
+ export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder.js';
7
7
  export var iframe;
8
8
  (function (iframe) {
9
9
  let autoResizeTimer;
@@ -1,4 +1,4 @@
1
- import type { IframeResponderOptions, CachedData } from './types/iframeResponder';
1
+ import type { IframeResponderOptions, CachedData } from './types/iframeResponder.js';
2
2
  /**
3
3
  * Parent-side iframe responder for SmartLinks microapp embedding.
4
4
  *
@@ -30,6 +30,12 @@ export declare class IframeResponder {
30
30
  private iframe;
31
31
  private options;
32
32
  private cache;
33
+ /**
34
+ * Timestamp of the last anonymous (`401`) `/account` result, so a burst of
35
+ * "am I logged in?" checks on one page load doesn't re-hit the API 3–4 times.
36
+ * Only used while `cache.user` is unset; cleared the moment a login lands.
37
+ */
38
+ private lastAnonAccountAt;
33
39
  private uploads;
34
40
  private activeStreams;
35
41
  private isInitialLoad;
@@ -1,9 +1,9 @@
1
1
  // =============================================================================
2
2
  // IframeResponder - Parent-side iframe communication handler
3
3
  // =============================================================================
4
- import * as cache from './cache';
5
- import { collection } from './api/collection';
6
- import { getBaseURL } from './http';
4
+ import * as cache from './cache.js';
5
+ import { collection } from './api/collection.js';
6
+ import { getBaseURL, hasAuthCredentials } from './http.js';
7
7
  /**
8
8
  * Parent-side iframe responder for SmartLinks microapp embedding.
9
9
  *
@@ -34,6 +34,12 @@ import { getBaseURL } from './http';
34
34
  export class IframeResponder {
35
35
  constructor(options) {
36
36
  this.iframe = null;
37
+ /**
38
+ * Timestamp of the last anonymous (`401`) `/account` result, so a burst of
39
+ * "am I logged in?" checks on one page load doesn't re-hit the API 3–4 times.
40
+ * Only used while `cache.user` is unset; cleared the moment a login lands.
41
+ */
42
+ this.lastAnonAccountAt = 0;
37
43
  this.uploads = new Map();
38
44
  this.activeStreams = new Map();
39
45
  this.isInitialLoad = true;
@@ -346,8 +352,10 @@ export class IframeResponder {
346
352
  // TODO: Validate token using SDK auth utilities when available
347
353
  // await auth.verifyToken(token);
348
354
  await this.options.onAuthLogin(token, user, accountData);
349
- // Update cache with new user
355
+ // Update cache with new user; drop any stale "anonymous" account marker
356
+ // so the next check reflects the fresh login immediately.
350
357
  this.cache.user = user;
358
+ this.lastAnonAccountAt = 0;
351
359
  this.sendResponse(event, {
352
360
  type: 'smartlinks:authkit:login-acknowledged',
353
361
  messageId,
@@ -414,6 +422,35 @@ export class IframeResponder {
414
422
  return;
415
423
  }
416
424
  }
425
+ // "Am I logged in?" (GET /account) with no logged-in user cached. The positive
426
+ // path above already served logged-in users (cache.user set).
427
+ if (proxyData.method === 'GET' && path.includes('/account') && !this.cache.user) {
428
+ const notAuthenticated = () => {
429
+ response.statusCode = 401;
430
+ response.error = 'Not authenticated';
431
+ response.errorBody = { account: null, errorCode: 'NOT_AUTHENTICATED' };
432
+ this.sendResponse(event, response);
433
+ };
434
+ // Pre-emptive gate: will this request carry ANY credential the server could
435
+ // validate? The portal authenticates by bearer token (not cookie), and the
436
+ // proxy fetch forwards no cookie, so if neither the parent SDK nor the
437
+ // forwarded headers carry a token, the call is provably pointless — answer
438
+ // "not authenticated" locally, zero network calls.
439
+ const headers = (proxyData.headers || {});
440
+ const hasHeaderAuth = Object.keys(headers).some((k) => k.toLowerCase() === 'authorization' && !!headers[k]);
441
+ if (!hasAuthCredentials() && !hasHeaderAuth) {
442
+ notAuthenticated();
443
+ return;
444
+ }
445
+ // A credential IS present but no user is cached (e.g. an expired token):
446
+ // the first check goes to the network, then its 401 is remembered briefly
447
+ // so repeat checks in the same page load don't re-hit the API.
448
+ const ANON_ACCOUNT_TTL_MS = 30000;
449
+ if (this.lastAnonAccountAt && Date.now() - this.lastAnonAccountAt < ANON_ACCOUNT_TTL_MS) {
450
+ notAuthenticated();
451
+ return;
452
+ }
453
+ }
417
454
  // Forward to actual API using SDK's configured baseURL
418
455
  const baseUrl = getBaseURL();
419
456
  if (!baseUrl) {
@@ -434,6 +471,10 @@ export class IframeResponder {
434
471
  response.error = (responseData === null || responseData === void 0 ? void 0 : responseData.message) || (responseData === null || responseData === void 0 ? void 0 : responseData.errorText) || `Request failed with status ${fetchResponse.status}`;
435
472
  response.statusCode = fetchResponse.status;
436
473
  response.errorBody = responseData;
474
+ // Remember an anonymous /account result so repeat checks skip the network.
475
+ if (fetchResponse.status === 401 && path.includes('/account') && !this.cache.user) {
476
+ this.lastAnonAccountAt = Date.now();
477
+ }
437
478
  }
438
479
  else {
439
480
  response.data = responseData;
package/dist/index.d.ts CHANGED
@@ -1,29 +1,32 @@
1
- export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, getHttpCacheDiagnostics, resetHttpCacheDiagnostics, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, getBaseURL, isProxyEnabled, setBearerToken, getBearerToken, setGrantToken, getGrantToken } from "./http";
2
- export * from "./api";
3
- export * from "./types";
4
- export { iframe } from "./iframe";
5
- export * as cache from './cache';
6
- export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder';
7
- export * as utils from './utils';
8
- export type { PortalPathParams, Gs1DigitalLinkParams, ConditionParams, ConditionDebugOptions, ConditionDebugLogger, ConditionSet, Condition, UserInfo, ProductInfo, ProofInfo, CollectionInfo, } from './utils';
9
- export type { LoginResponse, VerifyTokenResponse, AccountInfoResponse, AuthLocation, } from "./api/auth";
10
- export type { UserAccountRegistrationRequest, } from "./types/auth";
11
- export type { CommunicationEvent, CommsQueryByUser, CommsRecipientIdsQuery, CommsRecipientsWithoutActionQuery, CommsRecipientsWithActionQuery, RecipientId, RecipientWithOutcome, LogCommunicationEventBody, LogBulkCommunicationEventsBody, AppendResult, AppendBulkResult, CommsSettings, TopicConfig, CommsSettingsGetResponse, CommsSettingsPatchBody, CommsPublicTopicsResponse, UnsubscribeQuery, UnsubscribeResponse, CommsConsentUpsertRequest, CommsPreferencesUpsertRequest, CommsSubscribeRequest, CommsSubscribeResponse, CommsSubscriptionCheckQuery, CommsSubscriptionCheckResponse, CommsListMethodsQuery, CommsListMethodsResponse, RegisterEmailMethodRequest, RegisterSmsMethodRequest, RegisterMethodResponse, SubscriptionsResolveRequest, SubscriptionsResolveResponse, } from "./types/comms";
12
- export type { BatchResponse, BatchCreateRequest, BatchUpdateRequest, } from "./types/batch";
13
- export type { Lot, LotStatus, LotSelector, LotPayload, LotCreateInput, LotUpdateInput, ListLotsParams, ListLotsResponse, LotMemberDiff, ResolveLotResponse, LotProductSummary, ListLotProductsResponse, LotResolutionResult, } from "./types/lots";
14
- export type { VariantResponse, VariantCreateRequest, VariantUpdateRequest, } from "./types/variant";
15
- export type { BroadcastSendRequest } from "./types/broadcasts";
16
- export type { AppConfigOptions } from "./api/appConfiguration";
17
- export type { AdditionalGtin, ISODateString, JsonPrimitive, JsonValue, ProductCreateRequest, ProductClaimCreateInput, ProductClaimCreateRequestBody, ProductClaimLookupInput, ProductFacetMap, ProductFacetValue, ProductImageUrlInput, ProductKey, ProductQueryRequest, ProductQueryResponse, ProductUpdateRequest, Product, ProductWriteInput, PublicProduct, } from "./types/product";
18
- export type { TranslationLookupMode, TranslationContentType, TranslationQuality, TranslationItemStatus, TranslationContextValue, TranslationContext, TranslationLookupRequestBase, TranslationLookupSingleRequest, TranslationLookupBatchRequest, TranslationLookupRequest, TranslationLookupItem, TranslationLookupResponse, ResolvedTranslationItem, ResolvedTranslationResponse, TranslationHashOptions, TranslationResolveOptions, TranslationRecord, TranslationListParams, TranslationListResponse, TranslationUpdateRequest, } from "./types/translations";
19
- export type { FacetBucket, FacetDefinition, FacetDefinitionWriteInput, FacetGetParams, FacetListParams, FacetListResponse, FacetNamespaceListResponse, FacetQueryRequest, FacetQueryResponse, FacetValue, FacetValueDefinition, FacetValueGetParams, FacetValueListParams, FacetValueListResponse, FacetValueResponse, FacetValueWriteInput, PublicFacetListParams, } from "./types/facets";
20
- export type { Collection, CollectionResponse, CollectionCreateRequest, CollectionUpdateRequest, DomainTarget, HubAvailabilityResponse, } from "./types/collection";
21
- export type { Proof, ProofResponse, ProofWrite, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, ProofGrant, GrantScope, GrantAudience, CreateGrantOptions, RedeemGrantOptions, RedeemGrantResult, ProofTransfer, ProofTransferType, ProofTransferState, TransferProofOptions, TransferProofResult, } from "./types/proof";
22
- export type { QrShortCodeLookupResponse, } from "./types/qr";
23
- export type { ReverseTagLookupParams, ReverseTagLookupResponse, } from "./types/tags";
1
+ export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, getHttpCacheDiagnostics, resetHttpCacheDiagnostics, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, getBaseURL, isProxyEnabled, setBearerToken, getBearerToken, setGrantToken, getGrantToken } from "./http.js";
2
+ export * from "./api/index.js";
3
+ export * from "./types/index.js";
4
+ export { iframe } from "./iframe.js";
5
+ export type { InvalidateCacheOptions } from "./http.js";
6
+ export * as cache from './cache.js';
7
+ export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder.js';
8
+ export * as utils from './utils/index.js';
9
+ export { SHARED_DEPENDENCY_CONTRACT_VERSION, SHARED_DEPENDENCIES, SHARED_DEPENDENCY_SPECIFIERS, importMapPathFor, getHostSharedDependencies, } from './shared-dependencies.js';
10
+ export type { SharedDependency, HostSharedDependencies } from './shared-dependencies.js';
11
+ export type { PortalPathParams, Gs1DigitalLinkParams, ConditionParams, ConditionDebugOptions, ConditionDebugLogger, ConditionSet, Condition, UserInfo, ProductInfo, ProofInfo, CollectionInfo, } from './utils/index.js';
12
+ export type { LoginResponse, VerifyTokenResponse, AccountInfoResponse, AuthLocation, } from "./api/auth.js";
13
+ export type { UserAccountRegistrationRequest, } from "./types/auth.js";
14
+ export type { CommunicationEvent, CommsQueryByUser, CommsRecipientIdsQuery, CommsRecipientsWithoutActionQuery, CommsRecipientsWithActionQuery, RecipientId, RecipientWithOutcome, LogCommunicationEventBody, LogBulkCommunicationEventsBody, AppendResult, AppendBulkResult, CommsSettings, TopicConfig, CommsSettingsGetResponse, CommsSettingsPatchBody, CommsPublicTopicsResponse, UnsubscribeQuery, UnsubscribeResponse, CommsConsentUpsertRequest, CommsPreferencesUpsertRequest, CommsSubscribeRequest, CommsSubscribeResponse, CommsSubscriptionCheckQuery, CommsSubscriptionCheckResponse, CommsListMethodsQuery, CommsListMethodsResponse, RegisterEmailMethodRequest, RegisterSmsMethodRequest, RegisterMethodResponse, SubscriptionsResolveRequest, SubscriptionsResolveResponse, } from "./types/comms.js";
15
+ export type { BatchResponse, BatchCreateRequest, BatchUpdateRequest, } from "./types/batch.js";
16
+ export type { Lot, LotStatus, LotSelector, LotPayload, LotCreateInput, LotUpdateInput, ListLotsParams, ListLotsResponse, LotMemberDiff, ResolveLotResponse, LotProductSummary, ListLotProductsResponse, LotResolutionResult, } from "./types/lots.js";
17
+ export type { VariantResponse, VariantCreateRequest, VariantUpdateRequest, } from "./types/variant.js";
18
+ export type { BroadcastSendRequest } from "./types/broadcasts.js";
19
+ export type { AppConfigOptions } from "./api/appConfiguration.js";
20
+ export type { AdditionalGtin, ISODateString, JsonPrimitive, JsonValue, ProductCreateRequest, ProductClaimCreateInput, ProductClaimCreateRequestBody, ProductClaimLookupInput, ProductFacetMap, ProductFacetValue, ProductImageUrlInput, ProductKey, ProductQueryRequest, ProductQueryResponse, ProductUpdateRequest, Product, ProductWriteInput, PublicProduct, } from "./types/product.js";
21
+ export type { TranslationLookupMode, TranslationContentType, TranslationQuality, TranslationItemStatus, TranslationContextValue, TranslationContext, TranslationLookupRequestBase, TranslationLookupSingleRequest, TranslationLookupBatchRequest, TranslationLookupRequest, TranslationLookupItem, TranslationLookupResponse, ResolvedTranslationItem, ResolvedTranslationResponse, TranslationHashOptions, TranslationResolveOptions, TranslationRecord, TranslationListParams, TranslationListResponse, TranslationUpdateRequest, } from "./types/translations.js";
22
+ export type { FacetBucket, FacetDefinition, FacetDefinitionWriteInput, FacetGetParams, FacetListParams, FacetListResponse, FacetNamespaceListResponse, FacetQueryRequest, FacetQueryResponse, FacetValue, FacetValueDefinition, FacetValueGetParams, FacetValueListParams, FacetValueListResponse, FacetValueResponse, FacetValueWriteInput, PublicFacetListParams, } from "./types/facets.js";
23
+ export type { Collection, CollectionResponse, CollectionCreateRequest, CollectionUpdateRequest, DomainTarget, HubAvailabilityResponse, } from "./types/collection.js";
24
+ export type { Proof, ProofResponse, ProofWrite, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, ProofGrant, GrantScope, GrantAudience, CreateGrantOptions, RedeemGrantOptions, RedeemGrantResult, ProofTransfer, ProofTransferType, ProofTransferState, TransferProofOptions, TransferProofResult, } from "./types/proof.js";
25
+ export type { QrShortCodeLookupResponse, } from "./types/qr.js";
26
+ export type { ReverseTagLookupParams, ReverseTagLookupResponse, } from "./types/tags.js";
24
27
  export type { AdminMobileCapability, ActionableCapability, AdminMobileHostId, AdminMobileEvent, AdminMobileEventCallback, AdminMobileEventSubscriber, ScannerEventSubscriber, // @deprecated — use AdminMobileEventCallback
25
28
  AdminMobileHostContext, AdminMobileComponentManifest, AdminMobileBundleManifest, MobileAdminComponentManifest, // @deprecated — use AdminMobileComponentManifest
26
- MobileAdminBundleManifest, } from './mobile-admin/types';
27
- export { HostCapabilityUnavailableError, HostPermissionDeniedError, HostTimeoutError, } from './mobile-admin/errors';
28
- export type { NativeCapability, NativeFacade, ShareFacade, ClipboardFacade, HapticImpactStyle, HapticNotificationStyle, HapticsFacade, NetworkStatus, NetworkFacade, DeviceInfo, DeviceFacade, StorageFacade, QrScanOptions, QrFacade, AuthFacade, NfcReadResult, NfcFacade, RfidScanOptions, RfidFacade, EventsFacade, WebSourceMode, WebSourceConfig, WebSourceFacade, } from './native/types';
29
- export type { AuthKitUser, UserProfile, ProfileUpdateData, UpdateProfileResponse, SuccessResponse, AuthLoginResponse, AppleLoginOptions, AuthKitErrorCode, RefreshResponse, LogoutResponse, RefreshErrorCode, MagicLinkSendResponse, MagicLinkVerifyResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, VerifyStatus, WhatsAppReplyCta, WhatsAppReplyOptions, WhatsAppContactData, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, AuthKitBrandingConfig, AuthKitConfig, AuthKitConfigInput, AuthKitSecurityConfig, AuthKitPasswordPolicy, AuthKitSessionPolicy, AuthKitLockoutPolicy, PasswordPolicyErrorCode, LoginSecurityErrorCode, } from './types/authKit';
29
+ MobileAdminBundleManifest, } from './mobile-admin/types.js';
30
+ export { HostCapabilityUnavailableError, HostPermissionDeniedError, HostTimeoutError, } from './mobile-admin/errors.js';
31
+ export type { NativeCapability, NativeFacade, ShareFacade, ClipboardFacade, HapticImpactStyle, HapticNotificationStyle, HapticsFacade, NetworkStatus, NetworkFacade, DeviceInfo, DeviceFacade, StorageFacade, QrScanOptions, QrFacade, AuthFacade, NfcReadResult, NfcFacade, RfidScanOptions, RfidFacade, EventsFacade, WebSourceMode, WebSourceConfig, WebSourceFacade, } from './native/types.js';
32
+ export type { AuthKitUser, UserProfile, ProfileUpdateData, UpdateProfileResponse, SuccessResponse, AuthLoginResponse, AppleLoginOptions, AuthKitErrorCode, RefreshResponse, LogoutResponse, RefreshErrorCode, MagicLinkSendResponse, MagicLinkVerifyResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, VerifyStatus, WhatsAppReplyCta, WhatsAppReplyOptions, WhatsAppContactData, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, AuthKitBrandingConfig, AuthKitConfig, AuthKitConfigInput, AuthKitSecurityConfig, AuthKitPasswordPolicy, AuthKitSessionPolicy, AuthKitLockoutPolicy, PasswordPolicyErrorCode, LoginSecurityErrorCode, } from './types/authKit.js';
package/dist/index.js CHANGED
@@ -1,14 +1,16 @@
1
1
  // src/index.ts
2
2
  // Top-level entrypoint of the npm package. Re-export initializeApi + all namespaces.
3
- export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, getHttpCacheDiagnostics, resetHttpCacheDiagnostics, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, getBaseURL, isProxyEnabled, setBearerToken, getBearerToken, setGrantToken, getGrantToken } from "./http";
4
- export * from "./api";
5
- export * from "./types";
3
+ export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, getHttpCacheDiagnostics, resetHttpCacheDiagnostics, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, getBaseURL, isProxyEnabled, setBearerToken, getBearerToken, setGrantToken, getGrantToken } from "./http.js";
4
+ export * from "./api/index.js";
5
+ export * from "./types/index.js";
6
6
  // Iframe namespace
7
- export { iframe } from "./iframe";
8
- import * as cache_1 from './cache';
7
+ export { iframe } from "./iframe.js";
8
+ import * as cache_1 from './cache.js';
9
9
  export { cache_1 as cache };
10
10
  // IframeResponder (also exported via iframe namespace)
11
- export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder';
12
- import * as utils_1 from './utils';
11
+ export { IframeResponder, isAdminFromRoles, buildIframeSrc, } from './iframeResponder.js';
12
+ import * as utils_1 from './utils/index.js';
13
13
  export { utils_1 as utils };
14
- export { HostCapabilityUnavailableError, HostPermissionDeniedError, HostTimeoutError, } from './mobile-admin/errors';
14
+ // Shared dependency contract (host↔app) — one source of truth for externalized deps
15
+ export { SHARED_DEPENDENCY_CONTRACT_VERSION, SHARED_DEPENDENCIES, SHARED_DEPENDENCY_SPECIFIERS, importMapPathFor, getHostSharedDependencies, } from './shared-dependencies.js';
16
+ export { HostCapabilityUnavailableError, HostPermissionDeniedError, HostTimeoutError, } from './mobile-admin/errors.js';
@@ -5,7 +5,7 @@
5
5
  * All three classes call `Object.setPrototypeOf(this, new.target.prototype)` so
6
6
  * `instanceof` works correctly when transpiled to ES5.
7
7
  */
8
- import type { ActionableCapability, AdminMobileHostId } from './types';
8
+ import type { ActionableCapability, AdminMobileHostId } from './types.js';
9
9
  /**
10
10
  * Thrown when a container requests a hardware action that the current host
11
11
  * does not support (e.g. calling `requestNfcTap` on a `'pwa'` host).
@@ -1,4 +1,4 @@
1
- import type { NativeFacade } from '../native/types';
1
+ import type { NativeFacade } from '../native/types.js';
2
2
  /**
3
3
  * Hardware/software capability tokens a mobile admin host may advertise.
4
4
  * Passed to `AdminMobileHostContext.capabilities` and to
@@ -79,7 +79,7 @@ export interface AdminMobileHostContext {
79
79
  * calls — never `import * as SL from '@proveanything/smartlinks'` inside a
80
80
  * container, as that would create a second SDK instance.
81
81
  */
82
- SL: typeof import('../index');
82
+ SL: typeof import('../index.js');
83
83
  /** Capabilities advertised by this host instance. */
84
84
  capabilities: AdminMobileCapability[];
85
85
  /**
package/dist/openapi.yaml CHANGED
@@ -17471,6 +17471,18 @@ components:
17471
17471
  type: string
17472
17472
  appId:
17473
17473
  type: string
17474
+ moduleFormat:
17475
+ type: string
17476
+ enum:
17477
+ - umd
17478
+ - esm
17479
+ - dual
17480
+ sharedDependencies:
17481
+ type: string
17482
+ globals:
17483
+ type: object
17484
+ additionalProperties:
17485
+ type: string
17474
17486
  seo:
17475
17487
  type: object
17476
17488
  additionalProperties: true
@@ -0,0 +1,37 @@
1
+ /** Current contract revision. Bumped when the entry list or host versions change. */
2
+ export declare const SHARED_DEPENDENCY_CONTRACT_VERSION: "v5";
3
+ export interface SharedDependency {
4
+ /** Bare import specifier the app writes, e.g. `react-dom/client`. */
5
+ specifier: string;
6
+ /** Window global the host exposes for the UMD (legacy) resolution path. */
7
+ globalName: string;
8
+ /** Minimum version whose API the host guarantees — build against `>=` this, `<=` host. */
9
+ minVersion: string;
10
+ /** Portal-served ESM shim path this specifier maps to in the import map. */
11
+ importMapPath: string;
12
+ }
13
+ /**
14
+ * Canonical import-map path for a specifier: drop the leading `@` scope marker and
15
+ * turn every `/` into `-`.
16
+ * 'react-dom/client' -> '/sl-shared/v5/react-dom-client.js'
17
+ * '@radix-ui/react-slot' -> '/sl-shared/v5/radix-ui-react-slot.js'
18
+ * Hosts MUST serve shims at these paths so the map the SDK advertises resolves.
19
+ */
20
+ export declare function importMapPathFor(specifier: string, version?: string): string;
21
+ /** The full shared-dependency contract for {@link SHARED_DEPENDENCY_CONTRACT_VERSION}. */
22
+ export declare const SHARED_DEPENDENCIES: readonly SharedDependency[];
23
+ /** Just the bare specifiers — handy for a bundler `external` list. */
24
+ export declare const SHARED_DEPENDENCY_SPECIFIERS: readonly string[];
25
+ /** What a host advertises at runtime so apps can detect the live contract. */
26
+ export interface HostSharedDependencies {
27
+ version: string;
28
+ specifiers: string[];
29
+ }
30
+ /**
31
+ * Read the shared-dependency contract the current host advertises at runtime
32
+ * (via `window.__SMARTLINKS_SHARED__`). Returns `null` when there is no host
33
+ * marker — e.g. an older portal, or the bundle running outside a portal — so an
34
+ * app can degrade gracefully or fail with an actionable message instead of a
35
+ * bare-specifier resolution crash.
36
+ */
37
+ export declare function getHostSharedDependencies(): HostSharedDependencies | null;