@scalemule/nextjs 0.1.3 → 0.1.5

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.js CHANGED
@@ -1,9 +1,29 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
3
+ var React = require('react');
4
4
  var money = require('@scalemule/money');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
26
+
7
27
  var __defProp = Object.defineProperty;
8
28
  var __getOwnPropNames = Object.getOwnPropertyNames;
9
29
  var __esm = (fn, res) => function __init() {
@@ -2707,6 +2727,31 @@ var StorageService = class extends ServiceModule {
2707
2727
  async getInfo(fileId, options) {
2708
2728
  return this._get(`/files/${fileId}/info`, options);
2709
2729
  }
2730
+ /**
2731
+ * Aggregate status for a file — single call returns scan + reserved
2732
+ * optimize/transcode slots + the canonical view URL paths for image
2733
+ * (transform endpoint) and video (HLS playlist) MIME types.
2734
+ *
2735
+ * Foundational primitive for the chat / progressive media read side.
2736
+ * `useFileStatus()` (in `@scalemule/nextjs`) consumes this for both
2737
+ * first-paint and refresh-on-demand scenarios.
2738
+ *
2739
+ * `optimize` and `transcode` are reserved for Phase 3 enrichment. Until
2740
+ * the photo/video services expose internal status endpoints, callers
2741
+ * should attempt the constructed URLs directly to discover readiness
2742
+ * (404 means the pipeline is still running).
2743
+ *
2744
+ * @example
2745
+ * ```ts
2746
+ * const r = await client.storage.getFileStatus(fileId);
2747
+ * if (r.data?.scan.status === 'clean' && r.data.urls.optimized) {
2748
+ * // image: try transform URL for an optimized variant
2749
+ * }
2750
+ * ```
2751
+ */
2752
+ async getFileStatus(fileId, options) {
2753
+ return this._get(`/files/${fileId}/status`, options);
2754
+ }
2710
2755
  /**
2711
2756
  * Get a signed view URL for inline display (img src, thumbnails).
2712
2757
  * Returns CloudFront signed URL (fast, ~1us) or S3 presigned fallback.
@@ -7383,7 +7428,7 @@ function setCachedUser(user) {
7383
7428
  } catch {
7384
7429
  }
7385
7430
  }
7386
- var ScaleMuleContext = react.createContext(null);
7431
+ var ScaleMuleContext = React.createContext(null);
7387
7432
  function ScaleMuleProvider({
7388
7433
  apiKey,
7389
7434
  applicationId,
@@ -7402,11 +7447,11 @@ function ScaleMuleProvider({
7402
7447
  onAuthError,
7403
7448
  bootstrapFlags
7404
7449
  }) {
7405
- const [user, setUser] = react.useState(null);
7406
- const [initializing, setInitializing] = react.useState(true);
7407
- const [error, setError] = react.useState(null);
7450
+ const [user, setUser] = React.useState(null);
7451
+ const [initializing, setInitializing] = React.useState(true);
7452
+ const [error, setError] = React.useState(null);
7408
7453
  const resolvedGatewayUrl = gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com");
7409
- const client = react.useMemo(
7454
+ const client = React.useMemo(
7410
7455
  () => createClient({
7411
7456
  apiKey,
7412
7457
  applicationId,
@@ -7418,7 +7463,7 @@ function ScaleMuleProvider({
7418
7463
  }),
7419
7464
  [apiKey, applicationId, environment, resolvedGatewayUrl, debug, storage, authProxyUrl]
7420
7465
  );
7421
- const money$1 = react.useMemo(
7466
+ const money$1 = React.useMemo(
7422
7467
  () => money.createMoneyClient({
7423
7468
  apiKey,
7424
7469
  gatewayUrl: resolvedGatewayUrl,
@@ -7428,7 +7473,7 @@ function ScaleMuleProvider({
7428
7473
  }),
7429
7474
  [apiKey, resolvedGatewayUrl, environment, client]
7430
7475
  );
7431
- const baseClient = react.useMemo(() => {
7476
+ const baseClient = React.useMemo(() => {
7432
7477
  return new ScaleMule({
7433
7478
  apiKey,
7434
7479
  applicationId,
@@ -7437,7 +7482,7 @@ function ScaleMuleProvider({
7437
7482
  debug
7438
7483
  });
7439
7484
  }, [apiKey, applicationId, environment, resolvedGatewayUrl, debug]);
7440
- react.useEffect(() => {
7485
+ React.useEffect(() => {
7441
7486
  const token = client.getSessionToken();
7442
7487
  if (token) {
7443
7488
  baseClient.setAccessToken(token);
@@ -7447,7 +7492,7 @@ function ScaleMuleProvider({
7447
7492
  money$1.setAccessToken(void 0);
7448
7493
  }
7449
7494
  }, [client, baseClient, money$1, user]);
7450
- react.useEffect(() => {
7495
+ React.useEffect(() => {
7451
7496
  let mounted = true;
7452
7497
  async function initialize() {
7453
7498
  try {
@@ -7521,7 +7566,7 @@ function ScaleMuleProvider({
7521
7566
  mounted = false;
7522
7567
  };
7523
7568
  }, [client, debug, onAuthError, authProxyUrl]);
7524
- const handleSetUser = react.useCallback(
7569
+ const handleSetUser = React.useCallback(
7525
7570
  (newUser) => {
7526
7571
  setUser(newUser);
7527
7572
  setCachedUser(newUser);
@@ -7531,7 +7576,7 @@ function ScaleMuleProvider({
7531
7576
  },
7532
7577
  [onLogout]
7533
7578
  );
7534
- const value = react.useMemo(
7579
+ const value = React.useMemo(
7535
7580
  () => ({
7536
7581
  client,
7537
7582
  money: money$1,
@@ -7558,7 +7603,7 @@ function ScaleMuleProvider({
7558
7603
  return /* @__PURE__ */ jsxRuntime.jsx(ScaleMuleContext.Provider, { value, children });
7559
7604
  }
7560
7605
  function useScaleMule() {
7561
- const context = react.useContext(ScaleMuleContext);
7606
+ const context = React.useContext(ScaleMuleContext);
7562
7607
  if (!context) {
7563
7608
  throw new Error(
7564
7609
  "useScaleMule must be used within a ScaleMuleProvider. Make sure to wrap your app with <ScaleMuleProvider>."
@@ -7638,7 +7683,7 @@ async function proxyFetch(proxyUrl, path, options = {}) {
7638
7683
  }
7639
7684
  function useAuth() {
7640
7685
  const { client, user, setUser, initializing, error, setError, authProxyUrl, enableAccountSwitcher, accountSwitcherPrivacy } = useScaleMule();
7641
- const register = react.useCallback(
7686
+ const register = React.useCallback(
7642
7687
  async (data) => {
7643
7688
  setError(null);
7644
7689
  if (authProxyUrl) {
@@ -7674,7 +7719,7 @@ function useAuth() {
7674
7719
  },
7675
7720
  [client, setUser, setError, authProxyUrl]
7676
7721
  );
7677
- const login = react.useCallback(
7722
+ const login = React.useCallback(
7678
7723
  async (data) => {
7679
7724
  setError(null);
7680
7725
  if (authProxyUrl) {
@@ -7725,7 +7770,7 @@ function useAuth() {
7725
7770
  },
7726
7771
  [client, setUser, setError, authProxyUrl]
7727
7772
  );
7728
- const logout = react.useCallback(async () => {
7773
+ const logout = React.useCallback(async () => {
7729
7774
  setError(null);
7730
7775
  if (authProxyUrl) {
7731
7776
  try {
@@ -7745,7 +7790,7 @@ function useAuth() {
7745
7790
  await client.clearSession();
7746
7791
  setUser(null);
7747
7792
  }, [client, setUser, setError, authProxyUrl]);
7748
- const forgotPassword = react.useCallback(
7793
+ const forgotPassword = React.useCallback(
7749
7794
  async (email) => {
7750
7795
  setError(null);
7751
7796
  if (authProxyUrl) {
@@ -7771,7 +7816,7 @@ function useAuth() {
7771
7816
  },
7772
7817
  [client, setError, authProxyUrl]
7773
7818
  );
7774
- const resetPassword = react.useCallback(
7819
+ const resetPassword = React.useCallback(
7775
7820
  async (token, newPassword) => {
7776
7821
  setError(null);
7777
7822
  if (authProxyUrl) {
@@ -7797,7 +7842,7 @@ function useAuth() {
7797
7842
  },
7798
7843
  [client, setError, authProxyUrl]
7799
7844
  );
7800
- const verifyEmail = react.useCallback(
7845
+ const verifyEmail = React.useCallback(
7801
7846
  async (token) => {
7802
7847
  setError(null);
7803
7848
  if (authProxyUrl) {
@@ -7846,7 +7891,7 @@ function useAuth() {
7846
7891
  },
7847
7892
  [client, setUser, setError, authProxyUrl]
7848
7893
  );
7849
- const resendVerification = react.useCallback(async (email) => {
7894
+ const resendVerification = React.useCallback(async (email) => {
7850
7895
  setError(null);
7851
7896
  if (authProxyUrl) {
7852
7897
  const body = email ? { email } : user ? {} : void 0;
@@ -7881,7 +7926,7 @@ function useAuth() {
7881
7926
  }
7882
7927
  }
7883
7928
  }, [client, user, setError, authProxyUrl]);
7884
- const refreshSession = react.useCallback(async () => {
7929
+ const refreshSession = React.useCallback(async () => {
7885
7930
  setError(null);
7886
7931
  if (authProxyUrl) {
7887
7932
  const response = await proxyFetch(
@@ -7929,7 +7974,7 @@ function useAuth() {
7929
7974
  throw err;
7930
7975
  }
7931
7976
  }, [client, setUser, setError, authProxyUrl]);
7932
- const startOAuth = react.useCallback(
7977
+ const startOAuth = React.useCallback(
7933
7978
  async (config) => {
7934
7979
  setError(null);
7935
7980
  let oauthData;
@@ -7953,7 +7998,7 @@ function useAuth() {
7953
7998
  },
7954
7999
  [client, setError]
7955
8000
  );
7956
- const completeOAuth = react.useCallback(
8001
+ const completeOAuth = React.useCallback(
7957
8002
  async (request) => {
7958
8003
  setError(null);
7959
8004
  if (typeof sessionStorage !== "undefined") {
@@ -7983,7 +8028,7 @@ function useAuth() {
7983
8028
  },
7984
8029
  [client, setUser, setError]
7985
8030
  );
7986
- const getLinkedAccounts = react.useCallback(async () => {
8031
+ const getLinkedAccounts = React.useCallback(async () => {
7987
8032
  setError(null);
7988
8033
  try {
7989
8034
  const data = await client.get("/v1/auth/oauth/accounts");
@@ -7995,7 +8040,7 @@ function useAuth() {
7995
8040
  throw err;
7996
8041
  }
7997
8042
  }, [client, setError]);
7998
- const linkAccount = react.useCallback(
8043
+ const linkAccount = React.useCallback(
7999
8044
  async (config) => {
8000
8045
  setError(null);
8001
8046
  if (!user) {
@@ -8026,7 +8071,7 @@ function useAuth() {
8026
8071
  },
8027
8072
  [client, user, setError]
8028
8073
  );
8029
- const unlinkAccount = react.useCallback(
8074
+ const unlinkAccount = React.useCallback(
8030
8075
  async (provider) => {
8031
8076
  setError(null);
8032
8077
  try {
@@ -8040,7 +8085,7 @@ function useAuth() {
8040
8085
  },
8041
8086
  [client, setError]
8042
8087
  );
8043
- const getMFAStatus = react.useCallback(async () => {
8088
+ const getMFAStatus = React.useCallback(async () => {
8044
8089
  setError(null);
8045
8090
  try {
8046
8091
  return await client.get("/v1/auth/mfa/status");
@@ -8051,7 +8096,7 @@ function useAuth() {
8051
8096
  throw err;
8052
8097
  }
8053
8098
  }, [client, setError]);
8054
- const setupMFA = react.useCallback(
8099
+ const setupMFA = React.useCallback(
8055
8100
  async (request) => {
8056
8101
  setError(null);
8057
8102
  try {
@@ -8068,7 +8113,7 @@ function useAuth() {
8068
8113
  },
8069
8114
  [client, setError]
8070
8115
  );
8071
- const verifyMFA = react.useCallback(
8116
+ const verifyMFA = React.useCallback(
8072
8117
  async (request) => {
8073
8118
  setError(null);
8074
8119
  try {
@@ -8082,7 +8127,7 @@ function useAuth() {
8082
8127
  },
8083
8128
  [client, setError]
8084
8129
  );
8085
- const completeMFAChallenge = react.useCallback(
8130
+ const completeMFAChallenge = React.useCallback(
8086
8131
  async (challengeToken, code, method) => {
8087
8132
  setError(null);
8088
8133
  let mfaResult;
@@ -8104,7 +8149,7 @@ function useAuth() {
8104
8149
  },
8105
8150
  [client, setUser, setError]
8106
8151
  );
8107
- const disableMFA = react.useCallback(
8152
+ const disableMFA = React.useCallback(
8108
8153
  async (password) => {
8109
8154
  setError(null);
8110
8155
  try {
@@ -8118,7 +8163,7 @@ function useAuth() {
8118
8163
  },
8119
8164
  [client, setError]
8120
8165
  );
8121
- const regenerateBackupCodes = react.useCallback(
8166
+ const regenerateBackupCodes = React.useCallback(
8122
8167
  async (password) => {
8123
8168
  setError(null);
8124
8169
  try {
@@ -8135,7 +8180,7 @@ function useAuth() {
8135
8180
  },
8136
8181
  [client, setError]
8137
8182
  );
8138
- const sendPhoneCode = react.useCallback(
8183
+ const sendPhoneCode = React.useCallback(
8139
8184
  async (request) => {
8140
8185
  setError(null);
8141
8186
  if (authProxyUrl) {
@@ -8161,7 +8206,7 @@ function useAuth() {
8161
8206
  },
8162
8207
  [client, setError, authProxyUrl]
8163
8208
  );
8164
- const verifyPhone = react.useCallback(
8209
+ const verifyPhone = React.useCallback(
8165
8210
  async (request) => {
8166
8211
  setError(null);
8167
8212
  if (authProxyUrl) {
@@ -8201,7 +8246,7 @@ function useAuth() {
8201
8246
  },
8202
8247
  [client, user, setUser, setError, authProxyUrl]
8203
8248
  );
8204
- const loginWithPhone = react.useCallback(
8249
+ const loginWithPhone = React.useCallback(
8205
8250
  async (request) => {
8206
8251
  setError(null);
8207
8252
  if (authProxyUrl) {
@@ -8245,7 +8290,7 @@ function useAuth() {
8245
8290
  },
8246
8291
  [client, setUser, setError, authProxyUrl]
8247
8292
  );
8248
- const readKnownAccountsCookie = react.useCallback(() => {
8293
+ const readKnownAccountsCookie = React.useCallback(() => {
8249
8294
  if (!enableAccountSwitcher) return [];
8250
8295
  if (typeof document === "undefined") return [];
8251
8296
  const match = document.cookie.match(/(?:^|; )sm_known_accounts=([^;]*)/);
@@ -8262,11 +8307,11 @@ function useAuth() {
8262
8307
  return [];
8263
8308
  }
8264
8309
  }, [enableAccountSwitcher, accountSwitcherPrivacy]);
8265
- const [knownAccounts, setKnownAccounts] = react.useState([]);
8266
- react.useEffect(() => {
8310
+ const [knownAccounts, setKnownAccounts] = React.useState([]);
8311
+ React.useEffect(() => {
8267
8312
  setKnownAccounts(readKnownAccountsCookie());
8268
8313
  }, [readKnownAccountsCookie, user]);
8269
- const switchAccount = react.useCallback(
8314
+ const switchAccount = React.useCallback(
8270
8315
  async (userId) => {
8271
8316
  const target = knownAccounts.find((a) => a.userId === userId) || null;
8272
8317
  if (!target) return null;
@@ -8287,7 +8332,7 @@ function useAuth() {
8287
8332
  },
8288
8333
  [client, setUser, knownAccounts, authProxyUrl]
8289
8334
  );
8290
- const removeKnownAccount = react.useCallback(
8335
+ const removeKnownAccount = React.useCallback(
8291
8336
  async (userId) => {
8292
8337
  if (authProxyUrl) {
8293
8338
  await proxyFetch(authProxyUrl, "forget-account", { body: { user_id: userId } });
@@ -8296,13 +8341,13 @@ function useAuth() {
8296
8341
  },
8297
8342
  [authProxyUrl]
8298
8343
  );
8299
- const clearKnownAccounts = react.useCallback(async () => {
8344
+ const clearKnownAccounts = React.useCallback(async () => {
8300
8345
  if (authProxyUrl) {
8301
8346
  await proxyFetch(authProxyUrl, "forget-all-accounts");
8302
8347
  }
8303
8348
  setKnownAccounts([]);
8304
8349
  }, [authProxyUrl]);
8305
- return react.useMemo(
8350
+ return React.useMemo(
8306
8351
  () => ({
8307
8352
  user,
8308
8353
  loading: initializing,
@@ -8381,9 +8426,9 @@ function retiredBillingRouteError(route) {
8381
8426
  }
8382
8427
  function useBilling() {
8383
8428
  const { client } = useScaleMule();
8384
- const [loading, setLoading] = react.useState(false);
8385
- const [error, setError] = react.useState(null);
8386
- const createConnectedAccount = react.useCallback(
8429
+ const [loading, setLoading] = React.useState(false);
8430
+ const [error, setError] = React.useState(null);
8431
+ const createConnectedAccount = React.useCallback(
8387
8432
  async (data) => {
8388
8433
  setError(null);
8389
8434
  setLoading(true);
@@ -8399,7 +8444,7 @@ function useBilling() {
8399
8444
  },
8400
8445
  [client]
8401
8446
  );
8402
- const getMyConnectedAccount = react.useCallback(async () => {
8447
+ const getMyConnectedAccount = React.useCallback(async () => {
8403
8448
  setError(null);
8404
8449
  setLoading(true);
8405
8450
  try {
@@ -8412,7 +8457,7 @@ function useBilling() {
8412
8457
  setLoading(false);
8413
8458
  }
8414
8459
  }, [client]);
8415
- const getConnectedAccount = react.useCallback(
8460
+ const getConnectedAccount = React.useCallback(
8416
8461
  async (id) => {
8417
8462
  setError(null);
8418
8463
  setLoading(true);
@@ -8428,7 +8473,7 @@ function useBilling() {
8428
8473
  },
8429
8474
  [client]
8430
8475
  );
8431
- const createOnboardingLink = react.useCallback(
8476
+ const createOnboardingLink = React.useCallback(
8432
8477
  async (id, data) => {
8433
8478
  setError(null);
8434
8479
  setLoading(true);
@@ -8448,7 +8493,7 @@ function useBilling() {
8448
8493
  },
8449
8494
  [client]
8450
8495
  );
8451
- const getAccountBalance = react.useCallback(
8496
+ const getAccountBalance = React.useCallback(
8452
8497
  async (id) => {
8453
8498
  setError(null);
8454
8499
  setLoading(true);
@@ -8462,7 +8507,7 @@ function useBilling() {
8462
8507
  },
8463
8508
  [client]
8464
8509
  );
8465
- const createPayment = react.useCallback(
8510
+ const createPayment = React.useCallback(
8466
8511
  async (data) => {
8467
8512
  setError(null);
8468
8513
  setLoading(true);
@@ -8477,7 +8522,7 @@ function useBilling() {
8477
8522
  },
8478
8523
  [client]
8479
8524
  );
8480
- const getPayment = react.useCallback(
8525
+ const getPayment = React.useCallback(
8481
8526
  async (id) => {
8482
8527
  setError(null);
8483
8528
  setLoading(true);
@@ -8491,7 +8536,7 @@ function useBilling() {
8491
8536
  },
8492
8537
  [client]
8493
8538
  );
8494
- const listPayments = react.useCallback(
8539
+ const listPayments = React.useCallback(
8495
8540
  async (params) => {
8496
8541
  setError(null);
8497
8542
  setLoading(true);
@@ -8506,7 +8551,7 @@ function useBilling() {
8506
8551
  },
8507
8552
  [client]
8508
8553
  );
8509
- const refundPayment = react.useCallback(
8554
+ const refundPayment = React.useCallback(
8510
8555
  async (id, data) => {
8511
8556
  setError(null);
8512
8557
  setLoading(true);
@@ -8521,7 +8566,7 @@ function useBilling() {
8521
8566
  },
8522
8567
  [client]
8523
8568
  );
8524
- const getPayoutHistory = react.useCallback(
8569
+ const getPayoutHistory = React.useCallback(
8525
8570
  async (accountId, params) => {
8526
8571
  setError(null);
8527
8572
  setLoading(true);
@@ -8536,7 +8581,7 @@ function useBilling() {
8536
8581
  },
8537
8582
  [client]
8538
8583
  );
8539
- const getPayoutSchedule = react.useCallback(
8584
+ const getPayoutSchedule = React.useCallback(
8540
8585
  async (accountId) => {
8541
8586
  setError(null);
8542
8587
  setLoading(true);
@@ -8554,7 +8599,7 @@ function useBilling() {
8554
8599
  },
8555
8600
  [client]
8556
8601
  );
8557
- const setPayoutSchedule = react.useCallback(
8602
+ const setPayoutSchedule = React.useCallback(
8558
8603
  async (accountId, data) => {
8559
8604
  setError(null);
8560
8605
  setLoading(true);
@@ -8573,7 +8618,7 @@ function useBilling() {
8573
8618
  },
8574
8619
  [client]
8575
8620
  );
8576
- const getTransactions = react.useCallback(
8621
+ const getTransactions = React.useCallback(
8577
8622
  async (params) => {
8578
8623
  setError(null);
8579
8624
  setLoading(true);
@@ -8588,7 +8633,7 @@ function useBilling() {
8588
8633
  },
8589
8634
  [client]
8590
8635
  );
8591
- const getTransactionSummary = react.useCallback(
8636
+ const getTransactionSummary = React.useCallback(
8592
8637
  async (params) => {
8593
8638
  setError(null);
8594
8639
  setLoading(true);
@@ -8603,7 +8648,7 @@ function useBilling() {
8603
8648
  },
8604
8649
  [client]
8605
8650
  );
8606
- const createSetupSession = react.useCallback(
8651
+ const createSetupSession = React.useCallback(
8607
8652
  async (data) => {
8608
8653
  setError(null);
8609
8654
  setLoading(true);
@@ -8623,7 +8668,7 @@ function useBilling() {
8623
8668
  },
8624
8669
  [client]
8625
8670
  );
8626
- return react.useMemo(
8671
+ return React.useMemo(
8627
8672
  () => ({
8628
8673
  loading,
8629
8674
  error,
@@ -8667,11 +8712,11 @@ function useBilling() {
8667
8712
  function useContent(options = {}) {
8668
8713
  const { autoFetch = false, initialParams } = options;
8669
8714
  const { client, user, setError } = useScaleMule();
8670
- const [files, setFiles] = react.useState([]);
8671
- const [loading, setLoading] = react.useState(false);
8672
- const [uploadProgress, setUploadProgress] = react.useState(null);
8673
- const [error, setLocalError] = react.useState(null);
8674
- const list = react.useCallback(
8715
+ const [files, setFiles] = React.useState([]);
8716
+ const [loading, setLoading] = React.useState(false);
8717
+ const [uploadProgress, setUploadProgress] = React.useState(null);
8718
+ const [error, setLocalError] = React.useState(null);
8719
+ const list = React.useCallback(
8675
8720
  async (params) => {
8676
8721
  setLocalError(null);
8677
8722
  setLoading(true);
@@ -8693,7 +8738,7 @@ function useContent(options = {}) {
8693
8738
  },
8694
8739
  [client, initialParams]
8695
8740
  );
8696
- const upload = react.useCallback(
8741
+ const upload = React.useCallback(
8697
8742
  async (file, options2) => {
8698
8743
  setLocalError(null);
8699
8744
  setLoading(true);
@@ -8728,7 +8773,7 @@ function useContent(options = {}) {
8728
8773
  },
8729
8774
  [client, list]
8730
8775
  );
8731
- const remove = react.useCallback(
8776
+ const remove = React.useCallback(
8732
8777
  async (fileId) => {
8733
8778
  setLocalError(null);
8734
8779
  setLoading(true);
@@ -8741,24 +8786,24 @@ function useContent(options = {}) {
8741
8786
  },
8742
8787
  [client]
8743
8788
  );
8744
- const get = react.useCallback(
8789
+ const get = React.useCallback(
8745
8790
  async (fileId) => {
8746
8791
  setLocalError(null);
8747
8792
  return await client.get(`/v1/storage/files/${fileId}/info`);
8748
8793
  },
8749
8794
  [client]
8750
8795
  );
8751
- const refresh = react.useCallback(async () => {
8796
+ const refresh = React.useCallback(async () => {
8752
8797
  await list(initialParams);
8753
8798
  }, [list, initialParams]);
8754
- const getSignedUploadUrl = react.useCallback(
8799
+ const getSignedUploadUrl = React.useCallback(
8755
8800
  async (request) => {
8756
8801
  setLocalError(null);
8757
8802
  return await client.post("/v1/storage/signed-upload", request);
8758
8803
  },
8759
8804
  [client]
8760
8805
  );
8761
- const uploadToSignedUrl = react.useCallback(
8806
+ const uploadToSignedUrl = React.useCallback(
8762
8807
  async (signedUrl, file, headers, onProgress) => {
8763
8808
  setLocalError(null);
8764
8809
  setLoading(true);
@@ -8806,7 +8851,7 @@ function useContent(options = {}) {
8806
8851
  },
8807
8852
  []
8808
8853
  );
8809
- const completeSignedUpload = react.useCallback(
8854
+ const completeSignedUpload = React.useCallback(
8810
8855
  async (fileId) => {
8811
8856
  setLocalError(null);
8812
8857
  const data = await client.post(`/v1/storage/signed-upload/${fileId}/complete`);
@@ -8815,12 +8860,12 @@ function useContent(options = {}) {
8815
8860
  },
8816
8861
  [client, list]
8817
8862
  );
8818
- react.useEffect(() => {
8863
+ React.useEffect(() => {
8819
8864
  if (autoFetch && user) {
8820
8865
  list(initialParams);
8821
8866
  }
8822
8867
  }, [autoFetch, user, list, initialParams]);
8823
- return react.useMemo(
8868
+ return React.useMemo(
8824
8869
  () => ({
8825
8870
  files,
8826
8871
  loading,
@@ -8853,9 +8898,9 @@ function useContent(options = {}) {
8853
8898
  }
8854
8899
  function useMedia() {
8855
8900
  const { storage, photo, video } = useScaleMule();
8856
- const [uploading, setUploading] = react.useState(false);
8857
- const [error, setError] = react.useState(null);
8858
- const upload = react.useCallback(
8901
+ const [uploading, setUploading] = React.useState(false);
8902
+ const [error, setError] = React.useState(null);
8903
+ const upload = React.useCallback(
8859
8904
  async (file, options) => {
8860
8905
  setUploading(true);
8861
8906
  setError(null);
@@ -8942,7 +8987,7 @@ function useMedia() {
8942
8987
  },
8943
8988
  [storage, photo]
8944
8989
  );
8945
- const cancelUpload = react.useCallback(
8990
+ const cancelUpload = React.useCallback(
8946
8991
  async (fileId) => {
8947
8992
  setError(null);
8948
8993
  try {
@@ -8961,14 +9006,228 @@ function useMedia() {
8961
9006
  );
8962
9007
  return { upload, cancelUpload, error, uploading };
8963
9008
  }
9009
+ function useFileStatus(options) {
9010
+ const { storage } = useScaleMule();
9011
+ const { fileId, pollIntervalMs = null, disabled = false } = options;
9012
+ const [status, setStatus] = React.useState(null);
9013
+ const [loading, setLoading] = React.useState(false);
9014
+ const [error, setError] = React.useState(null);
9015
+ const requestSeqRef = React.useRef(0);
9016
+ const fetchStatus = React.useCallback(async () => {
9017
+ if (!fileId || disabled) return;
9018
+ const seq = ++requestSeqRef.current;
9019
+ setLoading(true);
9020
+ setError(null);
9021
+ try {
9022
+ const r = await storage.getFileStatus(fileId);
9023
+ if (seq !== requestSeqRef.current) return;
9024
+ if (r.error || !r.data) {
9025
+ setError(r.error);
9026
+ return;
9027
+ }
9028
+ setStatus(r.data);
9029
+ } catch (err) {
9030
+ if (seq !== requestSeqRef.current) return;
9031
+ setError(err);
9032
+ } finally {
9033
+ if (seq === requestSeqRef.current) {
9034
+ setLoading(false);
9035
+ }
9036
+ }
9037
+ }, [storage, fileId, disabled]);
9038
+ React.useEffect(() => {
9039
+ void fetchStatus();
9040
+ }, [fetchStatus]);
9041
+ React.useEffect(() => {
9042
+ if (!pollIntervalMs || disabled || !fileId) return;
9043
+ const isClean = status?.scan.status === "clean";
9044
+ if (isClean) return;
9045
+ const id = setInterval(() => {
9046
+ void fetchStatus();
9047
+ }, pollIntervalMs);
9048
+ return () => clearInterval(id);
9049
+ }, [pollIntervalMs, disabled, fileId, status?.scan.status, fetchStatus]);
9050
+ const isReady = status?.scan.status === "clean";
9051
+ return { status, loading, error, isReady, refresh: fetchStatus };
9052
+ }
9053
+ function ScaleMuleMedia(props) {
9054
+ const {
9055
+ fileId,
9056
+ mimeType,
9057
+ blobPreview,
9058
+ width,
9059
+ height,
9060
+ className,
9061
+ style,
9062
+ alt,
9063
+ pollIntervalMs = 2e3,
9064
+ renderPlaceholder,
9065
+ renderBlocked,
9066
+ renderOverride
9067
+ } = props;
9068
+ const { status, isReady } = useFileStatus({ fileId, pollIntervalMs });
9069
+ const isImage = mimeType.startsWith("image/");
9070
+ const isVideo = mimeType.startsWith("video/");
9071
+ const isAudio = mimeType.startsWith("audio/");
9072
+ const src = React.useMemo(() => {
9073
+ const scan = status?.scan.status;
9074
+ if (scan === "threat" || scan === "quarantined") return null;
9075
+ if (status && isReady) {
9076
+ if (isImage && status.urls.optimized) return status.urls.optimized;
9077
+ if (isVideo && status.urls.hls) return status.urls.hls;
9078
+ return status.urls.original ?? null;
9079
+ }
9080
+ if (blobPreview) return blobPreview;
9081
+ return null;
9082
+ }, [status, isReady, isImage, isVideo, blobPreview]);
9083
+ const renderState = React.useMemo(() => {
9084
+ const scan = status?.scan.status;
9085
+ if (scan === "threat" || scan === "quarantined") return "blocked";
9086
+ if (isReady) return "ready";
9087
+ if (blobPreview) return "preview";
9088
+ return "pending";
9089
+ }, [status?.scan.status, isReady, blobPreview]);
9090
+ const videoRef = React__namespace.useRef(null);
9091
+ React.useEffect(() => {
9092
+ if (!isVideo) return;
9093
+ if (!src) return;
9094
+ if (!src.endsWith(".m3u8")) return;
9095
+ const el = videoRef.current;
9096
+ if (!el) return;
9097
+ if (el.canPlayType("application/vnd.apple.mpegurl")) {
9098
+ el.src = src;
9099
+ return;
9100
+ }
9101
+ let cancelled = false;
9102
+ let hls = null;
9103
+ void (async () => {
9104
+ try {
9105
+ const moduleName = "hls.js";
9106
+ const mod = await import(
9107
+ /* @vite-ignore */
9108
+ /* webpackIgnore: true */
9109
+ moduleName
9110
+ ).catch(
9111
+ () => null
9112
+ );
9113
+ if (cancelled || !mod) return;
9114
+ const Hls = mod.default ?? mod;
9115
+ if (Hls.isSupported()) {
9116
+ hls = new Hls();
9117
+ hls.loadSource(src);
9118
+ hls.attachMedia(el);
9119
+ } else {
9120
+ el.src = src;
9121
+ }
9122
+ } catch {
9123
+ }
9124
+ })();
9125
+ return () => {
9126
+ cancelled = true;
9127
+ if (hls) hls.destroy();
9128
+ };
9129
+ }, [isVideo, src]);
9130
+ if (renderOverride) {
9131
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderOverride({ src, state: renderState }) });
9132
+ }
9133
+ if (renderState === "blocked") {
9134
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderBlocked ? renderBlocked() : /* @__PURE__ */ jsxRuntime.jsx(
9135
+ "div",
9136
+ {
9137
+ role: "alert",
9138
+ className,
9139
+ style: { padding: 12, color: "#a00", ...style },
9140
+ children: "This file was blocked."
9141
+ }
9142
+ ) });
9143
+ }
9144
+ if (renderState === "pending" && !src) {
9145
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderPlaceholder ? renderPlaceholder() : /* @__PURE__ */ jsxRuntime.jsx(
9146
+ "div",
9147
+ {
9148
+ role: "status",
9149
+ "aria-busy": true,
9150
+ className,
9151
+ style: { padding: 12, color: "#666", ...style },
9152
+ children: "Loading\u2026"
9153
+ }
9154
+ ) });
9155
+ }
9156
+ if (isImage) {
9157
+ const finalSrc = src && status?.urls.optimized && (width || height) ? appendQuery(src, {
9158
+ width: width ? String(width) : void 0,
9159
+ height: height ? String(height) : void 0,
9160
+ fit: "cover"
9161
+ }) : src;
9162
+ return /* @__PURE__ */ jsxRuntime.jsx(
9163
+ "img",
9164
+ {
9165
+ src: finalSrc ?? void 0,
9166
+ alt: alt ?? "",
9167
+ width,
9168
+ height,
9169
+ className,
9170
+ style
9171
+ }
9172
+ );
9173
+ }
9174
+ if (isVideo) {
9175
+ return /* @__PURE__ */ jsxRuntime.jsx(
9176
+ "video",
9177
+ {
9178
+ ref: videoRef,
9179
+ src: src && !src.endsWith(".m3u8") ? src : void 0,
9180
+ controls: true,
9181
+ playsInline: true,
9182
+ preload: "metadata",
9183
+ className,
9184
+ style,
9185
+ "aria-label": alt,
9186
+ width,
9187
+ height
9188
+ }
9189
+ );
9190
+ }
9191
+ if (isAudio) {
9192
+ return /* @__PURE__ */ jsxRuntime.jsx(
9193
+ "audio",
9194
+ {
9195
+ src: src ?? void 0,
9196
+ controls: true,
9197
+ preload: "metadata",
9198
+ className,
9199
+ style,
9200
+ "aria-label": alt
9201
+ }
9202
+ );
9203
+ }
9204
+ return /* @__PURE__ */ jsxRuntime.jsx(
9205
+ "a",
9206
+ {
9207
+ href: src ?? "#",
9208
+ target: "_blank",
9209
+ rel: "noopener noreferrer",
9210
+ className,
9211
+ style,
9212
+ children: alt ?? "Download file"
9213
+ }
9214
+ );
9215
+ }
9216
+ function appendQuery(url, params) {
9217
+ const filtered = Object.entries(params).filter(([, v]) => v != null && v !== "");
9218
+ if (filtered.length === 0) return url;
9219
+ const sep = url.includes("?") ? "&" : "?";
9220
+ const qs = new URLSearchParams(filtered).toString();
9221
+ return url + sep + qs;
9222
+ }
8964
9223
 
8965
9224
  // src/hooks/useMoney.ts
8966
9225
  var useMoney = useMoneyClient;
8967
9226
  function useUser() {
8968
9227
  const { client, user, setUser, setError } = useScaleMule();
8969
- const [loading, setLoading] = react.useState(false);
8970
- const [localError, setLocalError] = react.useState(null);
8971
- const update = react.useCallback(
9228
+ const [loading, setLoading] = React.useState(false);
9229
+ const [localError, setLocalError] = React.useState(null);
9230
+ const update = React.useCallback(
8972
9231
  async (data) => {
8973
9232
  setLocalError(null);
8974
9233
  setLoading(true);
@@ -8982,7 +9241,7 @@ function useUser() {
8982
9241
  },
8983
9242
  [client, setUser]
8984
9243
  );
8985
- const changePassword = react.useCallback(
9244
+ const changePassword = React.useCallback(
8986
9245
  async (currentPassword, newPassword) => {
8987
9246
  setLocalError(null);
8988
9247
  setLoading(true);
@@ -8997,7 +9256,7 @@ function useUser() {
8997
9256
  },
8998
9257
  [client]
8999
9258
  );
9000
- const changeEmail = react.useCallback(
9259
+ const changeEmail = React.useCallback(
9001
9260
  async (newEmail, password) => {
9002
9261
  setLocalError(null);
9003
9262
  setLoading(true);
@@ -9012,7 +9271,7 @@ function useUser() {
9012
9271
  },
9013
9272
  [client]
9014
9273
  );
9015
- const deleteAccount = react.useCallback(
9274
+ const deleteAccount = React.useCallback(
9016
9275
  async (password) => {
9017
9276
  setLocalError(null);
9018
9277
  setLoading(true);
@@ -9028,7 +9287,7 @@ function useUser() {
9028
9287
  },
9029
9288
  [client, setUser]
9030
9289
  );
9031
- const exportData = react.useCallback(async () => {
9290
+ const exportData = React.useCallback(async () => {
9032
9291
  setLocalError(null);
9033
9292
  setLoading(true);
9034
9293
  try {
@@ -9039,7 +9298,7 @@ function useUser() {
9039
9298
  setLoading(false);
9040
9299
  }
9041
9300
  }, [client]);
9042
- return react.useMemo(
9301
+ return React.useMemo(
9043
9302
  () => ({
9044
9303
  profile: user,
9045
9304
  loading,
@@ -9055,19 +9314,19 @@ function useUser() {
9055
9314
  }
9056
9315
  function useRealtime(options) {
9057
9316
  const { realtime } = useScaleMule();
9058
- const [status, setStatus] = react.useState("disconnected");
9059
- const [lastMessage, setLastMessage] = react.useState(null);
9060
- const manualUnsubscribesRef = react.useRef([]);
9061
- const autoUnsubscribesRef = react.useRef([]);
9062
- const onMessageRef = react.useRef(void 0);
9317
+ const [status, setStatus] = React.useState("disconnected");
9318
+ const [lastMessage, setLastMessage] = React.useState(null);
9319
+ const manualUnsubscribesRef = React.useRef([]);
9320
+ const autoUnsubscribesRef = React.useRef([]);
9321
+ const onMessageRef = React.useRef(void 0);
9063
9322
  const channelSignature = (options?.channels ?? []).join("");
9064
- react.useEffect(() => {
9323
+ React.useEffect(() => {
9065
9324
  onMessageRef.current = options?.onMessage;
9066
9325
  }, [options?.onMessage]);
9067
- const disconnect = react.useCallback(() => {
9326
+ const disconnect = React.useCallback(() => {
9068
9327
  realtime.disconnect();
9069
9328
  }, [realtime]);
9070
- const subscribe = react.useCallback(
9329
+ const subscribe = React.useCallback(
9071
9330
  (channel, callback) => {
9072
9331
  const unsub = realtime.subscribe(channel, (data) => {
9073
9332
  setLastMessage({ channel, data });
@@ -9082,19 +9341,19 @@ function useRealtime(options) {
9082
9341
  },
9083
9342
  [realtime]
9084
9343
  );
9085
- const publish = react.useCallback(
9344
+ const publish = React.useCallback(
9086
9345
  (channel, data) => {
9087
9346
  realtime.publish(channel, data);
9088
9347
  },
9089
9348
  [realtime]
9090
9349
  );
9091
- react.useEffect(() => {
9350
+ React.useEffect(() => {
9092
9351
  const unsub = realtime.onStatusChange((newStatus) => {
9093
9352
  setStatus(newStatus);
9094
9353
  });
9095
9354
  return unsub;
9096
9355
  }, [realtime]);
9097
- react.useEffect(() => {
9356
+ React.useEffect(() => {
9098
9357
  for (const unsub of autoUnsubscribesRef.current) {
9099
9358
  unsub();
9100
9359
  }
@@ -9113,7 +9372,7 @@ function useRealtime(options) {
9113
9372
  autoUnsubscribesRef.current = [];
9114
9373
  };
9115
9374
  }, [realtime, channelSignature]);
9116
- react.useEffect(() => {
9375
+ React.useEffect(() => {
9117
9376
  return () => {
9118
9377
  for (const unsub of manualUnsubscribesRef.current) {
9119
9378
  unsub();
@@ -9332,20 +9591,20 @@ function useAnalytics(options = {}) {
9332
9591
  } = options;
9333
9592
  const shouldAutoCaptureUtmParams = autoCaptureUtmParams ?? autoCapturUtmParams ?? true;
9334
9593
  const { client, user, analyticsProxyUrl, publishableKey, gatewayUrl } = useScaleMule();
9335
- const [loading, setLoading] = react.useState(false);
9336
- const [error, setError] = react.useState(null);
9337
- const [utmParams, setUtmParams] = react.useState(null);
9338
- const sessionIdRef = react.useRef(null);
9339
- const anonymousIdRef = react.useRef(null);
9340
- const sessionStartRef = react.useRef(Date.now());
9341
- const originalReferrerRef = react.useRef(null);
9342
- const idsReadyRef = react.useRef(false);
9343
- const [sessionId, setSessionId] = react.useState(null);
9344
- const [anonymousId, setAnonymousId] = react.useState(null);
9345
- const initialized = react.useRef(false);
9346
- const landingPage = react.useRef(null);
9347
- const eventQueue = react.useRef([]);
9348
- react.useEffect(() => {
9594
+ const [loading, setLoading] = React.useState(false);
9595
+ const [error, setError] = React.useState(null);
9596
+ const [utmParams, setUtmParams] = React.useState(null);
9597
+ const sessionIdRef = React.useRef(null);
9598
+ const anonymousIdRef = React.useRef(null);
9599
+ const sessionStartRef = React.useRef(Date.now());
9600
+ const originalReferrerRef = React.useRef(null);
9601
+ const idsReadyRef = React.useRef(false);
9602
+ const [sessionId, setSessionId] = React.useState(null);
9603
+ const [anonymousId, setAnonymousId] = React.useState(null);
9604
+ const initialized = React.useRef(false);
9605
+ const landingPage = React.useRef(null);
9606
+ const eventQueue = React.useRef([]);
9607
+ React.useEffect(() => {
9349
9608
  if (initialized.current) return;
9350
9609
  initialized.current = true;
9351
9610
  if (!autoGenerateSessionId) {
@@ -9369,7 +9628,7 @@ function useAnalytics(options = {}) {
9369
9628
  }, 0);
9370
9629
  }
9371
9630
  }, [autoGenerateSessionId, sessionStorageKey, anonymousStorageKey]);
9372
- react.useEffect(() => {
9631
+ React.useEffect(() => {
9373
9632
  if (typeof window === "undefined") return;
9374
9633
  if (shouldAutoCaptureUtmParams) {
9375
9634
  const utm = parseUtmParams();
@@ -9394,11 +9653,11 @@ function useAnalytics(options = {}) {
9394
9653
  }
9395
9654
  }
9396
9655
  }, [shouldAutoCaptureUtmParams]);
9397
- const sendEventRef = react.useRef(null);
9398
- const getDeviceInfo = react.useCallback(() => {
9656
+ const sendEventRef = React.useRef(null);
9657
+ const getDeviceInfo = React.useCallback(() => {
9399
9658
  return detectDeviceInfo();
9400
9659
  }, []);
9401
- const buildFullEvent = react.useCallback(
9660
+ const buildFullEvent = React.useCallback(
9402
9661
  (event) => {
9403
9662
  const device = getDeviceInfo();
9404
9663
  const fullEvent = {
@@ -9438,7 +9697,7 @@ function useAnalytics(options = {}) {
9438
9697
  // Note: sessionId/anonymousId removed - we use refs to keep this stable
9439
9698
  [user, utmParams, getDeviceInfo]
9440
9699
  );
9441
- const sendEvent = react.useCallback(
9700
+ const sendEvent = React.useCallback(
9442
9701
  async (event) => {
9443
9702
  const fullEvent = buildFullEvent(event);
9444
9703
  const payload = JSON.stringify(fullEvent);
@@ -9481,7 +9740,7 @@ function useAnalytics(options = {}) {
9481
9740
  [client, buildFullEvent, useV2, analyticsProxyUrl, publishableKey, gatewayUrl]
9482
9741
  );
9483
9742
  sendEventRef.current = sendEvent;
9484
- const trackEvent = react.useCallback(
9743
+ const trackEvent = React.useCallback(
9485
9744
  async (event) => {
9486
9745
  if (shouldDedup(event.event_name, eventDedupMs, event.properties)) {
9487
9746
  return { tracked: 0, session_id: sessionIdRef.current || void 0 };
@@ -9507,7 +9766,7 @@ function useAnalytics(options = {}) {
9507
9766
  // Note: idsReady removed - we use ref to keep callback stable
9508
9767
  [sendEvent, eventDedupMs]
9509
9768
  );
9510
- const trackPageView = react.useCallback(
9769
+ const trackPageView = React.useCallback(
9511
9770
  async (data) => {
9512
9771
  const pageEvent = {
9513
9772
  event_name: "page_viewed",
@@ -9523,7 +9782,7 @@ function useAnalytics(options = {}) {
9523
9782
  },
9524
9783
  [trackEvent]
9525
9784
  );
9526
- const trackBatch = react.useCallback(
9785
+ const trackBatch = React.useCallback(
9527
9786
  async (events) => {
9528
9787
  setError(null);
9529
9788
  setLoading(true);
@@ -9577,7 +9836,7 @@ function useAnalytics(options = {}) {
9577
9836
  // Note: sessionId removed - we use ref to keep callback stable
9578
9837
  [client, buildFullEvent, useV2, analyticsProxyUrl, publishableKey, gatewayUrl]
9579
9838
  );
9580
- const identify = react.useCallback(
9839
+ const identify = React.useCallback(
9581
9840
  async (userId, traits) => {
9582
9841
  await trackEvent({
9583
9842
  event_name: "user_identified",
@@ -9592,7 +9851,7 @@ function useAnalytics(options = {}) {
9592
9851
  // Note: anonymousId removed - we use ref
9593
9852
  [trackEvent]
9594
9853
  );
9595
- const reset = react.useCallback(() => {
9854
+ const reset = React.useCallback(() => {
9596
9855
  const newSessionId = generateUUID();
9597
9856
  const newSessionStart = Date.now();
9598
9857
  sessionIdRef.current = newSessionId;
@@ -9606,10 +9865,10 @@ function useAnalytics(options = {}) {
9606
9865
  originalReferrerRef.current = null;
9607
9866
  setUtmParams(null);
9608
9867
  }, [sessionStorageKey]);
9609
- const setUtmParamsManual = react.useCallback((params) => {
9868
+ const setUtmParamsManual = React.useCallback((params) => {
9610
9869
  setUtmParams(params);
9611
9870
  }, []);
9612
- return react.useMemo(
9871
+ return React.useMemo(
9613
9872
  () => ({
9614
9873
  loading,
9615
9874
  error,
@@ -9662,8 +9921,8 @@ function useFeatureFlags(options = {}) {
9662
9921
  enabled = true
9663
9922
  } = options;
9664
9923
  const { client, publishableKey, gatewayUrl, bootstrapFlags } = smContext;
9665
- const warnedRef = react.useRef(false);
9666
- react.useEffect(() => {
9924
+ const warnedRef = React.useRef(false);
9925
+ React.useEffect(() => {
9667
9926
  if (!warnedRef.current && (!keys || keys.length === 0)) {
9668
9927
  warnedRef.current = true;
9669
9928
  console.warn(
@@ -9671,7 +9930,7 @@ function useFeatureFlags(options = {}) {
9671
9930
  );
9672
9931
  }
9673
9932
  }, [keys]);
9674
- const initialFlags = react.useMemo(() => {
9933
+ const initialFlags = React.useMemo(() => {
9675
9934
  if (!bootstrapFlags) return {};
9676
9935
  const result = {};
9677
9936
  for (const [key, value] of Object.entries(bootstrapFlags)) {
@@ -9682,19 +9941,19 @@ function useFeatureFlags(options = {}) {
9682
9941
  return result;
9683
9942
  }, [bootstrapFlags]);
9684
9943
  const hasBootstrap = Object.keys(initialFlags).length > 0;
9685
- const [flags, setFlags] = react.useState(initialFlags);
9686
- const [loading, setLoading] = react.useState(enabled && !hasBootstrap);
9687
- const [error, setError] = react.useState(null);
9688
- const contextRef = react.useRef(context);
9689
- const keysRef = react.useRef(keys);
9690
- const keysKey = react.useMemo(() => keys && keys.length > 0 ? [...keys].sort().join("|") : "", [keys]);
9691
- react.useEffect(() => {
9944
+ const [flags, setFlags] = React.useState(initialFlags);
9945
+ const [loading, setLoading] = React.useState(enabled && !hasBootstrap);
9946
+ const [error, setError] = React.useState(null);
9947
+ const contextRef = React.useRef(context);
9948
+ const keysRef = React.useRef(keys);
9949
+ const keysKey = React.useMemo(() => keys && keys.length > 0 ? [...keys].sort().join("|") : "", [keys]);
9950
+ React.useEffect(() => {
9692
9951
  contextRef.current = context;
9693
9952
  }, [context]);
9694
- react.useEffect(() => {
9953
+ React.useEffect(() => {
9695
9954
  keysRef.current = keys;
9696
9955
  }, [keys]);
9697
- const refresh = react.useCallback(async () => {
9956
+ const refresh = React.useCallback(async () => {
9698
9957
  if (!enabled) {
9699
9958
  setLoading(false);
9700
9959
  return;
@@ -9730,7 +9989,7 @@ function useFeatureFlags(options = {}) {
9730
9989
  setLoading(false);
9731
9990
  }
9732
9991
  }, [client, enabled, environment, keysKey, publishableKey, gatewayUrl]);
9733
- const bootstrapCoversKeys = react.useMemo(() => {
9992
+ const bootstrapCoversKeys = React.useMemo(() => {
9734
9993
  if (!hasBootstrap || !keys || keys.length === 0) return false;
9735
9994
  if (!keys.every((k) => k in initialFlags)) return false;
9736
9995
  if (environment !== (smContext.environment ?? "prod")) return false;
@@ -9738,12 +9997,12 @@ function useFeatureFlags(options = {}) {
9738
9997
  if (contextKeys.length > 0) return false;
9739
9998
  return true;
9740
9999
  }, [hasBootstrap, keys, initialFlags, environment, smContext.environment, context]);
9741
- react.useEffect(() => {
10000
+ React.useEffect(() => {
9742
10001
  if (!bootstrapCoversKeys) {
9743
10002
  void refresh();
9744
10003
  }
9745
10004
  }, [refresh, bootstrapCoversKeys]);
9746
- const isEnabled = react.useCallback(
10005
+ const isEnabled = React.useCallback(
9747
10006
  (flagKey, fallback = false) => {
9748
10007
  const evaluation = flags[flagKey];
9749
10008
  if (!evaluation) return fallback;
@@ -9751,7 +10010,7 @@ function useFeatureFlags(options = {}) {
9751
10010
  },
9752
10011
  [flags]
9753
10012
  );
9754
- const getFlag = react.useCallback(
10013
+ const getFlag = React.useCallback(
9755
10014
  (flagKey, fallback) => {
9756
10015
  const evaluation = flags[flagKey];
9757
10016
  if (!evaluation) return fallback;
@@ -9776,18 +10035,18 @@ function getCsrfToken() {
9776
10035
  function usePushNotifications(options = {}) {
9777
10036
  const { serviceWorkerUrl = "/sw.js", pushProxyUrl = "/api/push", registrationSource, onNotification } = options;
9778
10037
  const { user } = useScaleMule();
9779
- const [isSupported, setIsSupported] = react.useState(false);
9780
- const [permission, setPermission] = react.useState("unsupported");
9781
- const [isSubscribed, setIsSubscribed] = react.useState(false);
9782
- const [isLoading, setIsLoading] = react.useState(false);
9783
- const [error, setError] = react.useState(null);
9784
- const [tokenId, setTokenId] = react.useState(null);
9785
- const onNotificationRef = react.useRef(onNotification);
9786
- react.useEffect(() => {
10038
+ const [isSupported, setIsSupported] = React.useState(false);
10039
+ const [permission, setPermission] = React.useState("unsupported");
10040
+ const [isSubscribed, setIsSubscribed] = React.useState(false);
10041
+ const [isLoading, setIsLoading] = React.useState(false);
10042
+ const [error, setError] = React.useState(null);
10043
+ const [tokenId, setTokenId] = React.useState(null);
10044
+ const onNotificationRef = React.useRef(onNotification);
10045
+ React.useEffect(() => {
9787
10046
  onNotificationRef.current = onNotification;
9788
10047
  }, [onNotification]);
9789
- const prevUserRef = react.useRef(null);
9790
- const fetcher = react.useMemo(() => {
10048
+ const prevUserRef = React.useRef(null);
10049
+ const fetcher = React.useMemo(() => {
9791
10050
  async function proxyGet(path) {
9792
10051
  const res = await fetch(`${pushProxyUrl}/${path}`);
9793
10052
  const json = await res.json();
@@ -9838,7 +10097,7 @@ function usePushNotifications(options = {}) {
9838
10097
  disassociateUser: (id) => proxyDelete(`tokens/by-id/${id}/user`)
9839
10098
  };
9840
10099
  }, [pushProxyUrl]);
9841
- const manager = react.useMemo(() => {
10100
+ const manager = React.useMemo(() => {
9842
10101
  if (typeof window === "undefined") return null;
9843
10102
  try {
9844
10103
  return new WebPushManager({ fetcher, serviceWorkerUrl, registrationSource });
@@ -9846,7 +10105,7 @@ function usePushNotifications(options = {}) {
9846
10105
  return null;
9847
10106
  }
9848
10107
  }, [fetcher, serviceWorkerUrl]);
9849
- react.useEffect(() => {
10108
+ React.useEffect(() => {
9850
10109
  if (!manager) return;
9851
10110
  const supported = manager.isSupported();
9852
10111
  setIsSupported(supported);
@@ -9867,7 +10126,7 @@ function usePushNotifications(options = {}) {
9867
10126
  });
9868
10127
  }
9869
10128
  }, [manager]);
9870
- react.useEffect(() => {
10129
+ React.useEffect(() => {
9871
10130
  if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) return;
9872
10131
  function handleMessage(event) {
9873
10132
  if (event.data?.type === "push-received") {
@@ -9886,7 +10145,7 @@ function usePushNotifications(options = {}) {
9886
10145
  navigator.serviceWorker.addEventListener("message", handleMessage);
9887
10146
  return () => navigator.serviceWorker.removeEventListener("message", handleMessage);
9888
10147
  }, [manager]);
9889
- react.useEffect(() => {
10148
+ React.useEffect(() => {
9890
10149
  if (!manager) return;
9891
10150
  const currentUserId = user?.id || null;
9892
10151
  const prevUserId = prevUserRef.current;
@@ -9896,7 +10155,7 @@ function usePushNotifications(options = {}) {
9896
10155
  }
9897
10156
  prevUserRef.current = currentUserId;
9898
10157
  }, [user?.id, manager, isSubscribed]);
9899
- const subscribe = react.useCallback(async () => {
10158
+ const subscribe = React.useCallback(async () => {
9900
10159
  if (!manager) return;
9901
10160
  setIsLoading(true);
9902
10161
  setError(null);
@@ -9918,7 +10177,7 @@ function usePushNotifications(options = {}) {
9918
10177
  setIsLoading(false);
9919
10178
  }
9920
10179
  }, [manager]);
9921
- const unsubscribe = react.useCallback(async () => {
10180
+ const unsubscribe = React.useCallback(async () => {
9922
10181
  if (!manager) return;
9923
10182
  setIsLoading(true);
9924
10183
  setError(null);
@@ -9935,7 +10194,7 @@ function usePushNotifications(options = {}) {
9935
10194
  setIsLoading(false);
9936
10195
  }
9937
10196
  }, [manager]);
9938
- const disassociateUser = react.useCallback(async () => {
10197
+ const disassociateUser = React.useCallback(async () => {
9939
10198
  if (!manager) return;
9940
10199
  try {
9941
10200
  await manager.disassociateUser();
@@ -9956,12 +10215,12 @@ function usePushNotifications(options = {}) {
9956
10215
  }
9957
10216
  function useShare(options) {
9958
10217
  const { client, user } = useScaleMule();
9959
- const [referralCode, setReferralCode] = react.useState(
10218
+ const [referralCode, setReferralCode] = React.useState(
9960
10219
  options?.referralCode ?? null
9961
10220
  );
9962
- const [loading, setLoading] = react.useState(false);
9963
- const [copied, setCopied] = react.useState(false);
9964
- react.useEffect(() => {
10221
+ const [loading, setLoading] = React.useState(false);
10222
+ const [copied, setCopied] = React.useState(false);
10223
+ React.useEffect(() => {
9965
10224
  if (!user) {
9966
10225
  setReferralCode(options?.referralCode ?? null);
9967
10226
  setLoading(false);
@@ -9990,7 +10249,7 @@ function useShare(options) {
9990
10249
  cancelled = true;
9991
10250
  };
9992
10251
  }, [user?.id, options?.url, options?.referralCode, options?.autoFetchReferral, client]);
9993
- const shareUrl = react.useMemo(() => {
10252
+ const shareUrl = React.useMemo(() => {
9994
10253
  const raw = options?.url || (typeof window !== "undefined" ? window.location.href : "");
9995
10254
  if (!raw) return raw;
9996
10255
  try {
@@ -10004,7 +10263,7 @@ function useShare(options) {
10004
10263
  return raw;
10005
10264
  }
10006
10265
  }, [options?.url, referralCode]);
10007
- const copyLink = react.useCallback(async () => {
10266
+ const copyLink = React.useCallback(async () => {
10008
10267
  try {
10009
10268
  await navigator.clipboard.writeText(shareUrl);
10010
10269
  } catch {
@@ -10043,10 +10302,10 @@ function toApiError2(error) {
10043
10302
  function useFeedback(options = {}) {
10044
10303
  const { client } = useScaleMule();
10045
10304
  const { status, type, enabled = true } = options;
10046
- const [items, setItems] = react.useState([]);
10047
- const [loading, setLoading] = react.useState(enabled);
10048
- const [error, setError] = react.useState(null);
10049
- const refresh = react.useCallback(async () => {
10305
+ const [items, setItems] = React.useState([]);
10306
+ const [loading, setLoading] = React.useState(enabled);
10307
+ const [error, setError] = React.useState(null);
10308
+ const refresh = React.useCallback(async () => {
10050
10309
  if (!enabled) {
10051
10310
  setLoading(false);
10052
10311
  return;
@@ -10067,10 +10326,10 @@ function useFeedback(options = {}) {
10067
10326
  setLoading(false);
10068
10327
  }
10069
10328
  }, [client, enabled, status, type]);
10070
- react.useEffect(() => {
10329
+ React.useEffect(() => {
10071
10330
  refresh();
10072
10331
  }, [refresh]);
10073
- const submit = react.useCallback(
10332
+ const submit = React.useCallback(
10074
10333
  async (input) => {
10075
10334
  try {
10076
10335
  const created = await client.post("/v1/feedback/submit", input);
@@ -10203,18 +10462,18 @@ function FeedbackWidget(props) {
10203
10462
  const sm = useScaleMule();
10204
10463
  const { client } = sm;
10205
10464
  const { submit } = useFeedback({ enabled: false });
10206
- const [serverConfig, setServerConfig] = react.useState(null);
10207
- const [configLoaded, setConfigLoaded] = react.useState(false);
10208
- const [open, setOpen] = react.useState(false);
10209
- const [type, setType] = react.useState("feature_request");
10210
- const [title, setTitle] = react.useState("");
10211
- const [description, setDescription] = react.useState("");
10212
- const [email, setEmail] = react.useState("");
10213
- const [rating, setRating] = react.useState(null);
10214
- const [hoverRating, setHoverRating] = react.useState(null);
10215
- const [submitting, setSubmitting] = react.useState(false);
10216
- const [errMsg, setErrMsg] = react.useState(null);
10217
- const [done, setDone] = react.useState(false);
10465
+ const [serverConfig, setServerConfig] = React.useState(null);
10466
+ const [configLoaded, setConfigLoaded] = React.useState(false);
10467
+ const [open, setOpen] = React.useState(false);
10468
+ const [type, setType] = React.useState("feature_request");
10469
+ const [title, setTitle] = React.useState("");
10470
+ const [description, setDescription] = React.useState("");
10471
+ const [email, setEmail] = React.useState("");
10472
+ const [rating, setRating] = React.useState(null);
10473
+ const [hoverRating, setHoverRating] = React.useState(null);
10474
+ const [submitting, setSubmitting] = React.useState(false);
10475
+ const [errMsg, setErrMsg] = React.useState(null);
10476
+ const [done, setDone] = React.useState(false);
10218
10477
  const signedIn = Boolean(sm.user);
10219
10478
  const resolvedAllowedTypes = props.allowedTypes ?? serverConfig?.allowed_types ?? ALL_TYPES;
10220
10479
  const resolvedDefaultType = (props.defaultType && resolvedAllowedTypes.includes(props.defaultType) ? props.defaultType : resolvedAllowedTypes[0]) ?? "feature_request";
@@ -10222,7 +10481,7 @@ function FeedbackWidget(props) {
10222
10481
  const resolvedTheme = props.theme ?? serverConfig?.widget_theme ?? "auto";
10223
10482
  const allowAnonymous = serverConfig?.allow_anonymous ?? true;
10224
10483
  const anonymousBlocked = !signedIn && !allowAnonymous;
10225
- react.useEffect(() => {
10484
+ React.useEffect(() => {
10226
10485
  let active = true;
10227
10486
  client.get("/v1/feedback/widget-config").then((config) => {
10228
10487
  if (active) setServerConfig(config);
@@ -10235,7 +10494,7 @@ function FeedbackWidget(props) {
10235
10494
  active = false;
10236
10495
  };
10237
10496
  }, [client]);
10238
- react.useEffect(() => {
10497
+ React.useEffect(() => {
10239
10498
  setType(
10240
10499
  (current) => resolvedAllowedTypes.includes(current) ? current : resolvedDefaultType
10241
10500
  );
@@ -10758,6 +11017,7 @@ Object.defineProperty(exports, "createMoneyClient", {
10758
11017
  exports.FeedbackWidget = FeedbackWidget;
10759
11018
  exports.ScaleMuleApiError = ScaleMuleApiError;
10760
11019
  exports.ScaleMuleClient = ScaleMuleClient2;
11020
+ exports.ScaleMuleMedia = ScaleMuleMedia;
10761
11021
  exports.ScaleMuleProvider = ScaleMuleProvider;
10762
11022
  exports.composePhone = composePhone;
10763
11023
  exports.createClient = createClient;
@@ -10771,6 +11031,7 @@ exports.useBilling = useBilling;
10771
11031
  exports.useContent = useContent;
10772
11032
  exports.useFeatureFlags = useFeatureFlags;
10773
11033
  exports.useFeedback = useFeedback;
11034
+ exports.useFileStatus = useFileStatus;
10774
11035
  exports.useMedia = useMedia;
10775
11036
  exports.useMoney = useMoney;
10776
11037
  exports.useMoneyClient = useMoneyClient;