@scalemule/nextjs 0.1.4 → 0.1.6

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 CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
2
3
  import { ReactNode, ReactElement } from 'react';
3
4
  import { MoneyClient } from '@scalemule/money';
4
5
  export { MoneyClient, MoneyClientConfig, createMoneyClient } from '@scalemule/money';
@@ -184,12 +185,43 @@ interface MediaUploadResult {
184
185
  /** Whether the resulting storage object is public-readable. */
185
186
  is_public: boolean;
186
187
  }
188
+ /**
189
+ * Per-app media-pipeline policy. Drives release-gating + processing
190
+ * behavior. **Orthogonal to `is_public`.** See
191
+ * `docs/MEDIA-UPLOADS.md` and ADR-2026-04-26 for the full taxonomy.
192
+ *
193
+ * Today's behavior (Phase 4 v1):
194
+ * - `fast_trusted` / `safe_visible` (default): upload promise resolves
195
+ * as soon as the file is uploaded + registered. The post-processing
196
+ * (scan, optimize, transcode) runs async; callers can observe via
197
+ * `useFileStatus`.
198
+ * - `safe_public` / `moderated`: upload promise *waits* for the
199
+ * optimized image variant (image MIME) or HLS playlist (video MIME)
200
+ * to become ready before resolving. Acts as the release-gate for
201
+ * UGC-style apps that should not publish raw bytes.
202
+ * - `compliance`: today behaves as `safe_public`; Phase 4+ adds the
203
+ * audit-log + signed-with-purpose URL semantics.
204
+ */
205
+ type MediaPolicy = 'fast_trusted' | 'safe_visible' | 'safe_public' | 'moderated' | 'compliance';
187
206
  interface UseMediaUploadOptions {
188
207
  /** Whether the resulting storage object should be public-readable.
189
208
  * Default: `false` (private). Public is opt-in for surfaces that
190
209
  * genuinely need it (avatars, public listings). Chat / DM uploads
191
210
  * should always be private. */
192
211
  is_public?: boolean;
212
+ /**
213
+ * Per-call media-policy override. Defaults to `safe_visible` (visible
214
+ * immediately at original fidelity; optimized variants swap in async).
215
+ * Set to `safe_public` to make the upload promise *await* the optimized
216
+ * variant (image) or HLS playlist (video) before resolving — useful for
217
+ * broadcast / UGC apps that gate publication on processing complete.
218
+ *
219
+ * The per-app default lives in `application_storage_settings.media_policy`
220
+ * (Phase 4 / P3, live in prod 2026-04-26). Reading the per-app default
221
+ * into `useMedia` defaults lands in a follow-up; today the option is
222
+ * caller-provided per call.
223
+ */
224
+ policy?: MediaPolicy;
193
225
  /** Display filename (sanitized server-side). */
194
226
  filename?: string;
195
227
  /** Custom metadata attached to the file. */
@@ -332,6 +364,85 @@ interface UseFileStatusReturn {
332
364
  */
333
365
  declare function useFileStatus(options: UseFileStatusOptions): UseFileStatusReturn;
334
366
 
367
+ interface ScaleMuleMediaProps {
368
+ /** Storage `file_id` of the media to render. Required. */
369
+ fileId: string;
370
+ /** MIME type — drives which element to render. Required. */
371
+ mimeType: string;
372
+ /**
373
+ * Optional sender-side optimistic preview. While the upload is in
374
+ * progress (or the recipient hasn't yet observed the message), the
375
+ * component renders this Blob URL. Once `useFileStatus` resolves a
376
+ * scan-clean state and a server-side URL, the component swaps to it.
377
+ */
378
+ blobPreview?: string;
379
+ /** Display width hint (CSS pixels). Used for image breakpoint selection. */
380
+ width?: number;
381
+ /** Display height hint (CSS pixels). */
382
+ height?: number;
383
+ /** Pass-through className for the rendered element. */
384
+ className?: string;
385
+ /** Pass-through style. */
386
+ style?: React.CSSProperties;
387
+ /** Alt text for `<img>`; aria-label for `<audio>` / `<video>`. */
388
+ alt?: string;
389
+ /**
390
+ * Polling interval while waiting for the media pipeline to complete.
391
+ * Defaults to 2000ms; set to `null` to disable polling. Polling stops
392
+ * automatically once scan is clean.
393
+ */
394
+ pollIntervalMs?: number | null;
395
+ /**
396
+ * Render a custom placeholder while waiting for scan / upload. Defaults
397
+ * to a tiny "Loading…" div. Receives the current FileStatus (or null).
398
+ */
399
+ renderPlaceholder?: () => React.ReactNode;
400
+ /**
401
+ * Render the "blocked" UI when scan flips to `threat`. Defaults to a
402
+ * "This file was blocked" message. Customize for branding.
403
+ */
404
+ renderBlocked?: () => React.ReactNode;
405
+ /**
406
+ * Custom render override. If provided, the component still calls
407
+ * `useFileStatus` but yields rendering to this function. Useful for
408
+ * highly custom presentation (e.g. lightbox triggers, hover overlays).
409
+ */
410
+ renderOverride?: (args: {
411
+ src: string | null;
412
+ state: 'preview' | 'pending' | 'ready' | 'blocked' | 'error';
413
+ }) => React.ReactNode;
414
+ }
415
+ /**
416
+ * Progressive-enhancement media renderer.
417
+ *
418
+ * Renders the right element for the given MIME type and progressively
419
+ * upgrades the source URL as the media pipeline advances:
420
+ *
421
+ * blob preview (if set) → original view URL → optimized variant (image)
422
+ * → HLS playlist (video)
423
+ *
424
+ * Today this is pull-only — `useFileStatus` polls until scan is clean
425
+ * (and the caller can stop polling by passing `pollIntervalMs={null}`).
426
+ * The push variant rides on the chat translation bridge (Phase 3 / P5')
427
+ * and lights up automatically once that ships.
428
+ *
429
+ * For non-Safari browsers, HLS playback requires `hls.js` to be
430
+ * available. The component dynamic-imports it on first need; if the
431
+ * import fails (not installed), it falls back to the original-bytes URL.
432
+ *
433
+ * @example
434
+ * ```tsx
435
+ * <ScaleMuleMedia
436
+ * fileId={attachment.file_id}
437
+ * mimeType={attachment.mime_type}
438
+ * width={520}
439
+ * blobPreview={pendingPreviewUrl}
440
+ * alt={attachment.filename}
441
+ * />
442
+ * ```
443
+ */
444
+ declare function ScaleMuleMedia(props: ScaleMuleMediaProps): React.ReactElement | null;
445
+
335
446
  declare const useMoney: typeof useMoneyClient;
336
447
 
337
448
  /**
@@ -815,4 +926,4 @@ declare function createSafeLogger(prefix: string): {
815
926
  error: (message: string, data?: unknown) => void;
816
927
  };
817
928
 
818
- export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
929
+ export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaPolicy, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleMedia, type ScaleMuleMediaProps, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
2
3
  import { ReactNode, ReactElement } from 'react';
3
4
  import { MoneyClient } from '@scalemule/money';
4
5
  export { MoneyClient, MoneyClientConfig, createMoneyClient } from '@scalemule/money';
@@ -184,12 +185,43 @@ interface MediaUploadResult {
184
185
  /** Whether the resulting storage object is public-readable. */
185
186
  is_public: boolean;
186
187
  }
188
+ /**
189
+ * Per-app media-pipeline policy. Drives release-gating + processing
190
+ * behavior. **Orthogonal to `is_public`.** See
191
+ * `docs/MEDIA-UPLOADS.md` and ADR-2026-04-26 for the full taxonomy.
192
+ *
193
+ * Today's behavior (Phase 4 v1):
194
+ * - `fast_trusted` / `safe_visible` (default): upload promise resolves
195
+ * as soon as the file is uploaded + registered. The post-processing
196
+ * (scan, optimize, transcode) runs async; callers can observe via
197
+ * `useFileStatus`.
198
+ * - `safe_public` / `moderated`: upload promise *waits* for the
199
+ * optimized image variant (image MIME) or HLS playlist (video MIME)
200
+ * to become ready before resolving. Acts as the release-gate for
201
+ * UGC-style apps that should not publish raw bytes.
202
+ * - `compliance`: today behaves as `safe_public`; Phase 4+ adds the
203
+ * audit-log + signed-with-purpose URL semantics.
204
+ */
205
+ type MediaPolicy = 'fast_trusted' | 'safe_visible' | 'safe_public' | 'moderated' | 'compliance';
187
206
  interface UseMediaUploadOptions {
188
207
  /** Whether the resulting storage object should be public-readable.
189
208
  * Default: `false` (private). Public is opt-in for surfaces that
190
209
  * genuinely need it (avatars, public listings). Chat / DM uploads
191
210
  * should always be private. */
192
211
  is_public?: boolean;
212
+ /**
213
+ * Per-call media-policy override. Defaults to `safe_visible` (visible
214
+ * immediately at original fidelity; optimized variants swap in async).
215
+ * Set to `safe_public` to make the upload promise *await* the optimized
216
+ * variant (image) or HLS playlist (video) before resolving — useful for
217
+ * broadcast / UGC apps that gate publication on processing complete.
218
+ *
219
+ * The per-app default lives in `application_storage_settings.media_policy`
220
+ * (Phase 4 / P3, live in prod 2026-04-26). Reading the per-app default
221
+ * into `useMedia` defaults lands in a follow-up; today the option is
222
+ * caller-provided per call.
223
+ */
224
+ policy?: MediaPolicy;
193
225
  /** Display filename (sanitized server-side). */
194
226
  filename?: string;
195
227
  /** Custom metadata attached to the file. */
@@ -332,6 +364,85 @@ interface UseFileStatusReturn {
332
364
  */
333
365
  declare function useFileStatus(options: UseFileStatusOptions): UseFileStatusReturn;
334
366
 
367
+ interface ScaleMuleMediaProps {
368
+ /** Storage `file_id` of the media to render. Required. */
369
+ fileId: string;
370
+ /** MIME type — drives which element to render. Required. */
371
+ mimeType: string;
372
+ /**
373
+ * Optional sender-side optimistic preview. While the upload is in
374
+ * progress (or the recipient hasn't yet observed the message), the
375
+ * component renders this Blob URL. Once `useFileStatus` resolves a
376
+ * scan-clean state and a server-side URL, the component swaps to it.
377
+ */
378
+ blobPreview?: string;
379
+ /** Display width hint (CSS pixels). Used for image breakpoint selection. */
380
+ width?: number;
381
+ /** Display height hint (CSS pixels). */
382
+ height?: number;
383
+ /** Pass-through className for the rendered element. */
384
+ className?: string;
385
+ /** Pass-through style. */
386
+ style?: React.CSSProperties;
387
+ /** Alt text for `<img>`; aria-label for `<audio>` / `<video>`. */
388
+ alt?: string;
389
+ /**
390
+ * Polling interval while waiting for the media pipeline to complete.
391
+ * Defaults to 2000ms; set to `null` to disable polling. Polling stops
392
+ * automatically once scan is clean.
393
+ */
394
+ pollIntervalMs?: number | null;
395
+ /**
396
+ * Render a custom placeholder while waiting for scan / upload. Defaults
397
+ * to a tiny "Loading…" div. Receives the current FileStatus (or null).
398
+ */
399
+ renderPlaceholder?: () => React.ReactNode;
400
+ /**
401
+ * Render the "blocked" UI when scan flips to `threat`. Defaults to a
402
+ * "This file was blocked" message. Customize for branding.
403
+ */
404
+ renderBlocked?: () => React.ReactNode;
405
+ /**
406
+ * Custom render override. If provided, the component still calls
407
+ * `useFileStatus` but yields rendering to this function. Useful for
408
+ * highly custom presentation (e.g. lightbox triggers, hover overlays).
409
+ */
410
+ renderOverride?: (args: {
411
+ src: string | null;
412
+ state: 'preview' | 'pending' | 'ready' | 'blocked' | 'error';
413
+ }) => React.ReactNode;
414
+ }
415
+ /**
416
+ * Progressive-enhancement media renderer.
417
+ *
418
+ * Renders the right element for the given MIME type and progressively
419
+ * upgrades the source URL as the media pipeline advances:
420
+ *
421
+ * blob preview (if set) → original view URL → optimized variant (image)
422
+ * → HLS playlist (video)
423
+ *
424
+ * Today this is pull-only — `useFileStatus` polls until scan is clean
425
+ * (and the caller can stop polling by passing `pollIntervalMs={null}`).
426
+ * The push variant rides on the chat translation bridge (Phase 3 / P5')
427
+ * and lights up automatically once that ships.
428
+ *
429
+ * For non-Safari browsers, HLS playback requires `hls.js` to be
430
+ * available. The component dynamic-imports it on first need; if the
431
+ * import fails (not installed), it falls back to the original-bytes URL.
432
+ *
433
+ * @example
434
+ * ```tsx
435
+ * <ScaleMuleMedia
436
+ * fileId={attachment.file_id}
437
+ * mimeType={attachment.mime_type}
438
+ * width={520}
439
+ * blobPreview={pendingPreviewUrl}
440
+ * alt={attachment.filename}
441
+ * />
442
+ * ```
443
+ */
444
+ declare function ScaleMuleMedia(props: ScaleMuleMediaProps): React.ReactElement | null;
445
+
335
446
  declare const useMoney: typeof useMoneyClient;
336
447
 
337
448
  /**
@@ -815,4 +926,4 @@ declare function createSafeLogger(prefix: string): {
815
926
  error: (message: string, data?: unknown) => void;
816
927
  };
817
928
 
818
- export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
929
+ export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaPolicy, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleMedia, type ScaleMuleMediaProps, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };