deepspace 0.4.2 → 0.4.3

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
@@ -4888,6 +4888,9 @@ async function request(method, endpoint, body, options) {
4888
4888
  } catch {
4889
4889
  }
4890
4890
  const controller = new AbortController();
4891
+ const abortFromCaller = () => controller.abort();
4892
+ if (options?.signal?.aborted) controller.abort();
4893
+ else options?.signal?.addEventListener("abort", abortFromCaller, { once: true });
4891
4894
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
4892
4895
  try {
4893
4896
  const res = await fetch(url, {
@@ -4924,6 +4927,7 @@ async function request(method, endpoint, body, options) {
4924
4927
  };
4925
4928
  } finally {
4926
4929
  clearTimeout(timeout);
4930
+ options?.signal?.removeEventListener("abort", abortFromCaller);
4927
4931
  }
4928
4932
  }
4929
4933
  var integration = {
@@ -5017,8 +5021,364 @@ function decodeAiStreamChunk(chunk) {
5017
5021
  }
5018
5022
  }
5019
5023
 
5024
+ // src/client/status.ts
5025
+ import { useCallback as useCallback26, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef17, useState as useState17 } from "react";
5026
+
5027
+ // src/client/status-core.ts
5028
+ var ASYNC_RESOURCE_DEFAULTS = {
5029
+ retry: 0,
5030
+ retryDelayMs: 2e3,
5031
+ slowAfterMs: 1e4
5032
+ };
5033
+ function isAsyncResourceSlow(input) {
5034
+ return input.slowAfterMs > 0 && input.now - input.startedAt >= input.slowAfterMs;
5035
+ }
5036
+ function getPagedResourceCooldownMs(input) {
5037
+ const failureCount = Math.max(1, input.failureCount);
5038
+ return Math.min(input.maxRetryDelayMs, input.retryDelayMs * 2 ** (failureCount - 1));
5039
+ }
5040
+ function canAutoLoadPagedResource(input) {
5041
+ return input.hasMore && !input.isLoading && input.cooldownUntil <= input.now;
5042
+ }
5043
+ function clampPagedResourceItems(input) {
5044
+ if (input.maxItemsPerPage <= 0 || input.items.length <= input.maxItemsPerPage) {
5045
+ return { items: input.items, droppedItemCount: 0 };
5046
+ }
5047
+ return {
5048
+ items: input.items.slice(0, input.maxItemsPerPage),
5049
+ droppedItemCount: input.items.length - input.maxItemsPerPage
5050
+ };
5051
+ }
5052
+ function deriveLoadState(input) {
5053
+ const auth = input.auth;
5054
+ if (auth) {
5055
+ if (!auth.isLoaded) return "loading";
5056
+ if (auth.requireSignedIn && !auth.isSignedIn) return "signedOut";
5057
+ if (auth.requireUser && auth.isSignedIn && auth.userLoading) return "loading";
5058
+ }
5059
+ const statuses = [...input.queries ?? [], ...input.resources ?? []];
5060
+ if (statuses.some((item) => item.status === "error" || item.error)) return "error";
5061
+ if (statuses.some((item) => item.status === "loading" || item.status === "idle")) return "loading";
5062
+ if (input.empty) return "empty";
5063
+ return "ready";
5064
+ }
5065
+
5066
+ // src/client/status.ts
5067
+ function useAuthStatus(options = {}) {
5068
+ const auth = useAuth();
5069
+ const status = deriveLoadState({
5070
+ auth: {
5071
+ isLoaded: auth.isLoaded,
5072
+ isSignedIn: auth.isSignedIn,
5073
+ requireSignedIn: options.requireSignedIn
5074
+ }
5075
+ });
5076
+ return {
5077
+ ...auth,
5078
+ status,
5079
+ isReady: status === "ready"
5080
+ };
5081
+ }
5082
+ function useAuthProfileReady(options = {}) {
5083
+ const auth = useAuth();
5084
+ const { user, isLoading: userLoading, refetch } = useUser();
5085
+ const status = deriveLoadState({
5086
+ auth: {
5087
+ isLoaded: auth.isLoaded,
5088
+ isSignedIn: auth.isSignedIn,
5089
+ requireSignedIn: options.requireSignedIn,
5090
+ requireUser: options.requireUser,
5091
+ userLoading
5092
+ }
5093
+ });
5094
+ return {
5095
+ ...auth,
5096
+ user,
5097
+ userLoading,
5098
+ refetchUser: refetch,
5099
+ status,
5100
+ isReady: status === "ready"
5101
+ };
5102
+ }
5103
+ var useAuthReady = useAuthProfileReady;
5104
+ function useAsyncResource(fetcher, deps, options = {}) {
5105
+ const enabled = options.enabled ?? true;
5106
+ const keepPreviousData = options.keepPreviousData ?? true;
5107
+ const retry = options.retry ?? ASYNC_RESOURCE_DEFAULTS.retry;
5108
+ const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
5109
+ const slowAfterMs = options.slowAfterMs ?? ASYNC_RESOURCE_DEFAULTS.slowAfterMs;
5110
+ const [state, setState] = useState17(() => ({
5111
+ status: enabled ? "loading" : "idle",
5112
+ data: options.initialData ?? null,
5113
+ error: null,
5114
+ isRefreshing: false,
5115
+ isSlow: false,
5116
+ retryCount: 0
5117
+ }));
5118
+ const requestIdRef = useRef17(0);
5119
+ const [reloadTick, setReloadTick] = useState17(0);
5120
+ const reload = useCallback26(() => {
5121
+ setReloadTick((tick) => tick + 1);
5122
+ }, []);
5123
+ useEffect20(() => {
5124
+ if (!enabled) {
5125
+ setState((prev) => ({ ...prev, status: "idle", isRefreshing: false, isSlow: false, retryCount: 0 }));
5126
+ return;
5127
+ }
5128
+ const requestId = ++requestIdRef.current;
5129
+ const controller = new AbortController();
5130
+ let retryTimer = null;
5131
+ let slowTimer = null;
5132
+ setState((prev) => {
5133
+ const hasData = keepPreviousData && prev.data != null;
5134
+ return {
5135
+ ...prev,
5136
+ status: hasData ? "ready" : "loading",
5137
+ error: null,
5138
+ isRefreshing: hasData,
5139
+ isSlow: false,
5140
+ data: hasData ? prev.data : options.initialData ?? null,
5141
+ retryCount: 0
5142
+ };
5143
+ });
5144
+ if (slowAfterMs > 0) {
5145
+ const startedAt = Date.now();
5146
+ slowTimer = setTimeout(() => {
5147
+ if (requestIdRef.current !== requestId || controller.signal.aborted) return;
5148
+ setState((prev) => ({
5149
+ ...prev,
5150
+ isSlow: isAsyncResourceSlow({ startedAt, now: Date.now(), slowAfterMs })
5151
+ }));
5152
+ }, slowAfterMs);
5153
+ }
5154
+ const wait = (ms) => new Promise((resolve) => {
5155
+ retryTimer = setTimeout(resolve, ms);
5156
+ });
5157
+ const load = async () => {
5158
+ let attempt = 0;
5159
+ while (!controller.signal.aborted) {
5160
+ try {
5161
+ const data = await fetcher(controller.signal);
5162
+ if (requestIdRef.current !== requestId || controller.signal.aborted) return;
5163
+ if (slowTimer) clearTimeout(slowTimer);
5164
+ setState({ status: "ready", data, error: null, isRefreshing: false, isSlow: false, retryCount: attempt });
5165
+ return;
5166
+ } catch (err) {
5167
+ if (requestIdRef.current !== requestId || controller.signal.aborted) return;
5168
+ const message = err instanceof Error ? err.message : "Request failed";
5169
+ if (attempt < retry) {
5170
+ attempt += 1;
5171
+ setState((prev) => ({
5172
+ ...prev,
5173
+ error: message,
5174
+ retryCount: attempt,
5175
+ isRefreshing: keepPreviousData && prev.data != null
5176
+ }));
5177
+ await wait(retryDelayMs);
5178
+ continue;
5179
+ }
5180
+ if (slowTimer) clearTimeout(slowTimer);
5181
+ setState((prev) => ({
5182
+ status: keepPreviousData && prev.data != null ? "ready" : "error",
5183
+ data: keepPreviousData ? prev.data : null,
5184
+ error: message,
5185
+ isRefreshing: false,
5186
+ isSlow: false,
5187
+ retryCount: attempt
5188
+ }));
5189
+ return;
5190
+ }
5191
+ }
5192
+ };
5193
+ load();
5194
+ return () => {
5195
+ if (retryTimer) clearTimeout(retryTimer);
5196
+ if (slowTimer) clearTimeout(slowTimer);
5197
+ controller.abort();
5198
+ };
5199
+ }, [enabled, keepPreviousData, retry, retryDelayMs, slowAfterMs, reloadTick, ...deps]);
5200
+ return useMemo15(() => ({ ...state, reload }), [state, reload]);
5201
+ }
5202
+ function usePagedResource(fetchPage, deps, options = {}) {
5203
+ const enabled = options.enabled ?? true;
5204
+ const initialItems = options.initialItems ?? [];
5205
+ const pageSize = options.pageSize ?? 20;
5206
+ const maxItemsPerPage = options.maxItemsPerPage ?? pageSize;
5207
+ const keepPreviousData = options.keepPreviousData ?? true;
5208
+ const autoRetryOnError = options.autoRetryOnError ?? false;
5209
+ const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
5210
+ const maxRetryDelayMs = options.maxRetryDelayMs ?? 3e4;
5211
+ const hasInitialItems = initialItems.length > 0;
5212
+ const [state, setState] = useState17(() => ({
5213
+ status: enabled ? hasInitialItems ? "ready" : "loading" : "idle",
5214
+ items: initialItems,
5215
+ error: null,
5216
+ warning: null,
5217
+ hasMore: true,
5218
+ isLoadingInitial: enabled && !hasInitialItems,
5219
+ isLoadingMore: false,
5220
+ isRefreshing: false
5221
+ }));
5222
+ const requestIdRef = useRef17(0);
5223
+ const controllerRef = useRef17(null);
5224
+ const loadingRef = useRef17(false);
5225
+ const nextPageRef = useRef17(hasInitialItems ? 2 : 1);
5226
+ const failedPageRef = useRef17(null);
5227
+ const failureCountRef = useRef17(0);
5228
+ const cooldownUntilRef = useRef17(0);
5229
+ const autoRetryTimerRef = useRef17(null);
5230
+ const clearAutoRetryTimer = useCallback26(() => {
5231
+ if (autoRetryTimerRef.current) {
5232
+ clearTimeout(autoRetryTimerRef.current);
5233
+ autoRetryTimerRef.current = null;
5234
+ }
5235
+ }, []);
5236
+ const resetCooldown = useCallback26(() => {
5237
+ failureCountRef.current = 0;
5238
+ cooldownUntilRef.current = 0;
5239
+ }, []);
5240
+ const setFailureCooldown = useCallback26(() => {
5241
+ failureCountRef.current += 1;
5242
+ const delay = getPagedResourceCooldownMs({
5243
+ failureCount: failureCountRef.current,
5244
+ retryDelayMs,
5245
+ maxRetryDelayMs
5246
+ });
5247
+ cooldownUntilRef.current = Date.now() + delay;
5248
+ return delay;
5249
+ }, [maxRetryDelayMs, retryDelayMs]);
5250
+ const startLoad = useCallback26(async (page, mode) => {
5251
+ if (!enabled || loadingRef.current) return;
5252
+ if (mode === "auto" && !canAutoLoadPagedResource({
5253
+ hasMore: true,
5254
+ isLoading: false,
5255
+ now: Date.now(),
5256
+ cooldownUntil: cooldownUntilRef.current
5257
+ })) {
5258
+ return;
5259
+ }
5260
+ clearAutoRetryTimer();
5261
+ loadingRef.current = true;
5262
+ const requestId = ++requestIdRef.current;
5263
+ controllerRef.current?.abort();
5264
+ const controller = new AbortController();
5265
+ controllerRef.current = controller;
5266
+ setState((prev) => {
5267
+ const hasItems = prev.items.length > 0;
5268
+ return {
5269
+ ...prev,
5270
+ status: hasItems && mode !== "refresh" ? "ready" : "loading",
5271
+ error: mode === "auto" && prev.error ? prev.error : null,
5272
+ warning: null,
5273
+ isLoadingInitial: !hasItems && mode !== "refresh",
5274
+ isLoadingMore: hasItems && mode !== "refresh",
5275
+ isRefreshing: mode === "refresh" && hasItems,
5276
+ items: mode === "refresh" && !keepPreviousData ? [] : prev.items
5277
+ };
5278
+ });
5279
+ try {
5280
+ const result = await fetchPage({ page, pageSize, signal: controller.signal });
5281
+ if (requestIdRef.current !== requestId || controller.signal.aborted) return;
5282
+ const { items: pageItems, droppedItemCount } = clampPagedResourceItems({
5283
+ items: result.items,
5284
+ maxItemsPerPage
5285
+ });
5286
+ resetCooldown();
5287
+ failedPageRef.current = null;
5288
+ nextPageRef.current = page + 1;
5289
+ setState((prev) => ({
5290
+ status: "ready",
5291
+ items: page === 1 || mode === "refresh" ? pageItems : [...prev.items, ...pageItems],
5292
+ error: null,
5293
+ warning: droppedItemCount > 0 ? `The last API page returned ${result.items.length} items; only ${pageItems.length} were kept. Request a smaller page from the API instead of fetching the whole feed.` : null,
5294
+ hasMore: droppedItemCount > 0 || (result.hasMore ?? result.items.length >= pageSize),
5295
+ isLoadingInitial: false,
5296
+ isLoadingMore: false,
5297
+ isRefreshing: false
5298
+ }));
5299
+ } catch (err) {
5300
+ if (requestIdRef.current !== requestId || controller.signal.aborted) return;
5301
+ const message = err instanceof Error ? err.message : "Request failed";
5302
+ failedPageRef.current = page;
5303
+ const cooldownMs = setFailureCooldown();
5304
+ setState((prev) => {
5305
+ const hasItems = prev.items.length > 0;
5306
+ return {
5307
+ ...prev,
5308
+ status: hasItems ? "ready" : "error",
5309
+ error: message,
5310
+ warning: prev.warning,
5311
+ hasMore: hasItems ? prev.hasMore : false,
5312
+ isLoadingInitial: false,
5313
+ isLoadingMore: false,
5314
+ isRefreshing: false
5315
+ };
5316
+ });
5317
+ if (autoRetryOnError) {
5318
+ autoRetryTimerRef.current = setTimeout(() => {
5319
+ autoRetryTimerRef.current = null;
5320
+ void startLoad(page, "auto");
5321
+ }, cooldownMs);
5322
+ }
5323
+ } finally {
5324
+ if (requestIdRef.current === requestId) {
5325
+ loadingRef.current = false;
5326
+ controllerRef.current = null;
5327
+ }
5328
+ }
5329
+ }, [autoRetryOnError, clearAutoRetryTimer, enabled, fetchPage, keepPreviousData, pageSize, resetCooldown, setFailureCooldown]);
5330
+ const loadMore = useCallback26(() => {
5331
+ if (!state.hasMore || state.isLoadingInitial || state.isLoadingMore || state.isRefreshing) return;
5332
+ void startLoad(nextPageRef.current, "auto");
5333
+ }, [startLoad, state.hasMore, state.isLoadingInitial, state.isLoadingMore, state.isRefreshing]);
5334
+ const retry = useCallback26(() => {
5335
+ const page = failedPageRef.current ?? nextPageRef.current;
5336
+ void startLoad(page, "manual");
5337
+ }, [startLoad]);
5338
+ const refresh = useCallback26(() => {
5339
+ failedPageRef.current = null;
5340
+ resetCooldown();
5341
+ nextPageRef.current = 1;
5342
+ void startLoad(1, "refresh");
5343
+ }, [resetCooldown, startLoad]);
5344
+ useEffect20(() => {
5345
+ requestIdRef.current += 1;
5346
+ controllerRef.current?.abort();
5347
+ clearAutoRetryTimer();
5348
+ loadingRef.current = false;
5349
+ failedPageRef.current = null;
5350
+ resetCooldown();
5351
+ nextPageRef.current = hasInitialItems ? 2 : 1;
5352
+ setState({
5353
+ status: enabled ? hasInitialItems ? "ready" : "loading" : "idle",
5354
+ items: initialItems,
5355
+ error: null,
5356
+ warning: null,
5357
+ hasMore: true,
5358
+ isLoadingInitial: enabled && !hasInitialItems,
5359
+ isLoadingMore: false,
5360
+ isRefreshing: false
5361
+ });
5362
+ if (enabled && !hasInitialItems) {
5363
+ void startLoad(1, "auto");
5364
+ }
5365
+ return () => {
5366
+ requestIdRef.current += 1;
5367
+ controllerRef.current?.abort();
5368
+ clearAutoRetryTimer();
5369
+ loadingRef.current = false;
5370
+ };
5371
+ }, [enabled, pageSize, maxItemsPerPage, keepPreviousData, autoRetryOnError, retryDelayMs, maxRetryDelayMs, ...deps]);
5372
+ return useMemo15(() => ({
5373
+ ...state,
5374
+ loadMore,
5375
+ retry,
5376
+ refresh
5377
+ }), [loadMore, refresh, retry, state]);
5378
+ }
5379
+
5020
5380
  // src/client/subscriptions/useSubscription.ts
5021
- import { useCallback as useCallback26, useEffect as useEffect20, useState as useState17 } from "react";
5381
+ import { useCallback as useCallback27, useEffect as useEffect21, useState as useState18 } from "react";
5022
5382
 
5023
5383
  // src/shared/subscription.ts
5024
5384
  var ENTITLED_STATUSES = /* @__PURE__ */ new Set([
@@ -5049,7 +5409,7 @@ async function authedJson(path, init) {
5049
5409
  return data;
5050
5410
  }
5051
5411
  function useSubscription() {
5052
- const [state, setState] = useState17({
5412
+ const [state, setState] = useState18({
5053
5413
  tier: "free",
5054
5414
  status: "none",
5055
5415
  interval: null,
@@ -5058,9 +5418,9 @@ function useSubscription() {
5058
5418
  trialEndsAt: null,
5059
5419
  plans: []
5060
5420
  });
5061
- const [isLoading, setLoading] = useState17(true);
5062
- const [error, setError] = useState17(null);
5063
- const refresh = useCallback26(async () => {
5421
+ const [isLoading, setLoading] = useState18(true);
5422
+ const [error, setError] = useState18(null);
5423
+ const refresh = useCallback27(async () => {
5064
5424
  setLoading(true);
5065
5425
  try {
5066
5426
  const r = await authedJson("/_deepspace/subscriptions/me");
@@ -5080,15 +5440,15 @@ function useSubscription() {
5080
5440
  setLoading(false);
5081
5441
  }
5082
5442
  }, []);
5083
- useEffect20(() => {
5443
+ useEffect21(() => {
5084
5444
  refresh();
5085
5445
  }, [refresh]);
5086
5446
  const entitled = isEntitled(state.tier, state.status);
5087
- const hasTier = useCallback26(
5447
+ const hasTier = useCallback27(
5088
5448
  (slug) => state.tier === slug && isEntitled(state.tier, state.status),
5089
5449
  [state.tier, state.status]
5090
5450
  );
5091
- const isAtLeast = useCallback26(
5451
+ const isAtLeast = useCallback27(
5092
5452
  (slug) => {
5093
5453
  if (!isEntitled(state.tier, state.status)) return false;
5094
5454
  const targetRank = state.plans.find((p) => p.slug === slug)?.rank;
@@ -5098,7 +5458,7 @@ function useSubscription() {
5098
5458
  },
5099
5459
  [state.plans, state.tier, state.status]
5100
5460
  );
5101
- const subscribe = useCallback26(
5461
+ const subscribe = useCallback27(
5102
5462
  async (planSlug, opts) => {
5103
5463
  const result = await authedJson("/_deepspace/subscriptions/checkout", {
5104
5464
  method: "POST",
@@ -5118,7 +5478,7 @@ function useSubscription() {
5118
5478
  },
5119
5479
  [refresh]
5120
5480
  );
5121
- const openPortal = useCallback26(
5481
+ const openPortal = useCallback27(
5122
5482
  async (returnUrl) => {
5123
5483
  return authedJson("/_deepspace/subscriptions/portal", {
5124
5484
  method: "POST",
@@ -5187,7 +5547,7 @@ function PricingTable(props) {
5187
5547
  }
5188
5548
 
5189
5549
  // src/client/charges/useCheckout.ts
5190
- import { useCallback as useCallback27, useEffect as useEffect21, useMemo as useMemo15, useState as useState18 } from "react";
5550
+ import { useCallback as useCallback28, useEffect as useEffect22, useMemo as useMemo16, useState as useState19 } from "react";
5191
5551
  async function authedJson2(path, init) {
5192
5552
  const token = await getAuthToken();
5193
5553
  const res = await fetch(path, {
@@ -5206,10 +5566,10 @@ async function authedJson2(path, init) {
5206
5566
  return data;
5207
5567
  }
5208
5568
  function useCheckout(opts) {
5209
- const [purchases, setPurchases] = useState18([]);
5210
- const [isLoading, setLoading] = useState18(true);
5211
- const [error, setError] = useState18(null);
5212
- const refresh = useCallback27(async () => {
5569
+ const [purchases, setPurchases] = useState19([]);
5570
+ const [isLoading, setLoading] = useState19(true);
5571
+ const [error, setError] = useState19(null);
5572
+ const refresh = useCallback28(async () => {
5213
5573
  setLoading(true);
5214
5574
  try {
5215
5575
  const r = await authedJson2(
@@ -5223,10 +5583,10 @@ function useCheckout(opts) {
5223
5583
  setLoading(false);
5224
5584
  }
5225
5585
  }, []);
5226
- useEffect21(() => {
5586
+ useEffect22(() => {
5227
5587
  refresh();
5228
5588
  }, [refresh]);
5229
- const chargeOnce = useCallback27(
5589
+ const chargeOnce = useCallback28(
5230
5590
  async (chargeOpts) => {
5231
5591
  setError(null);
5232
5592
  const common = {
@@ -5260,11 +5620,11 @@ function useCheckout(opts) {
5260
5620
  },
5261
5621
  []
5262
5622
  );
5263
- const ownsProduct = useCallback27(
5623
+ const ownsProduct = useCallback28(
5264
5624
  (productId) => purchases.some((p) => p.productId === productId),
5265
5625
  [purchases]
5266
5626
  );
5267
- const owned = useMemo15(
5627
+ const owned = useMemo16(
5268
5628
  () => !!opts?.productId && purchases.some((p) => p.productId === opts.productId),
5269
5629
  [opts?.productId, purchases]
5270
5630
  );
@@ -5516,13 +5876,14 @@ var buttonVariants = cva(
5516
5876
  }
5517
5877
  );
5518
5878
  var Button = React11.forwardRef(
5519
- ({ className, variant, size, asChild = false, loading = false, disabled, children, ...props }, ref) => {
5879
+ ({ className, variant, size, asChild = false, loading = false, disabled, children, type, ...props }, ref) => {
5520
5880
  const Comp = asChild ? Slot : "button";
5521
5881
  return /* @__PURE__ */ jsxs6(
5522
5882
  Comp,
5523
5883
  {
5524
5884
  className: cn(buttonVariants({ variant, size, className })),
5525
5885
  ref,
5886
+ type: asChild ? void 0 : type ?? "button",
5526
5887
  disabled: disabled || loading,
5527
5888
  ...props,
5528
5889
  children: [
@@ -6111,9 +6472,9 @@ AlertDescription.displayName = "AlertDescription";
6111
6472
  import {
6112
6473
  createContext as createContext4,
6113
6474
  useContext as useContext6,
6114
- useState as useState19,
6115
- useCallback as useCallback28,
6116
- useEffect as useEffect22
6475
+ useState as useState20,
6476
+ useCallback as useCallback29,
6477
+ useEffect as useEffect23
6117
6478
  } from "react";
6118
6479
  import { jsx as jsx28, jsxs as jsxs10 } from "react/jsx-runtime";
6119
6480
  function CheckCircleIcon({ className }) {
@@ -6160,14 +6521,14 @@ function ToastProvider({
6160
6521
  position = "bottom-right",
6161
6522
  maxToasts = 5
6162
6523
  }) {
6163
- const [toasts, setToasts] = useState19([]);
6164
- const dismiss = useCallback28((id) => {
6524
+ const [toasts, setToasts] = useState20([]);
6525
+ const dismiss = useCallback29((id) => {
6165
6526
  setToasts((prev) => prev.filter((t) => t.id !== id));
6166
6527
  }, []);
6167
- const dismissAll = useCallback28(() => {
6528
+ const dismissAll = useCallback29(() => {
6168
6529
  setToasts([]);
6169
6530
  }, []);
6170
- const addToast = useCallback28(
6531
+ const addToast = useCallback29(
6171
6532
  (options) => {
6172
6533
  const id = Math.random().toString(36).slice(2);
6173
6534
  const duration = options.duration ?? 5e3;
@@ -6181,23 +6542,23 @@ function ToastProvider({
6181
6542
  },
6182
6543
  [dismiss, maxToasts]
6183
6544
  );
6184
- const toast = useCallback28(
6545
+ const toast = useCallback29(
6185
6546
  (options) => addToast(options),
6186
6547
  [addToast]
6187
6548
  );
6188
- const success = useCallback28(
6549
+ const success = useCallback29(
6189
6550
  (title, description) => addToast({ type: "success", title, description }),
6190
6551
  [addToast]
6191
6552
  );
6192
- const error = useCallback28(
6553
+ const error = useCallback29(
6193
6554
  (title, description) => addToast({ type: "error", title, description }),
6194
6555
  [addToast]
6195
6556
  );
6196
- const warning = useCallback28(
6557
+ const warning = useCallback29(
6197
6558
  (title, description) => addToast({ type: "warning", title, description }),
6198
6559
  [addToast]
6199
6560
  );
6200
- const info = useCallback28(
6561
+ const info = useCallback29(
6201
6562
  (title, description) => addToast({ type: "info", title, description }),
6202
6563
  [addToast]
6203
6564
  );
@@ -6234,8 +6595,8 @@ var TOAST_CONFIG = {
6234
6595
  };
6235
6596
  function ToastItem({ toast, onDismiss }) {
6236
6597
  const { Icon: Icon2, accent, icon } = TOAST_CONFIG[toast.type];
6237
- const [exiting, setExiting] = useState19(false);
6238
- useEffect22(() => {
6598
+ const [exiting, setExiting] = useState20(false);
6599
+ useEffect23(() => {
6239
6600
  if (exiting) {
6240
6601
  const timer = setTimeout(onDismiss, 150);
6241
6602
  return () => clearTimeout(timer);
@@ -6828,6 +7189,7 @@ var SearchInput = React25.forwardRef(
6828
7189
  );
6829
7190
  SearchInput.displayName = "SearchInput";
6830
7191
  export {
7192
+ ASYNC_RESOURCE_DEFAULTS,
6831
7193
  Alert,
6832
7194
  AlertDescription,
6833
7195
  AlertTitle,
@@ -6955,6 +7317,8 @@ export {
6955
7317
  authClient,
6956
7318
  badgeVariants,
6957
7319
  buttonVariants,
7320
+ canAutoLoadPagedResource,
7321
+ clampPagedResourceItems,
6958
7322
  clearAuthToken,
6959
7323
  clearDeepSpaceTheme,
6960
7324
  clientBuild,
@@ -6963,6 +7327,7 @@ export {
6963
7327
  createEncoder,
6964
7328
  decodeAiStreamChunk,
6965
7329
  decodeReactError,
7330
+ deriveLoadState,
6966
7331
  detectEnvironment,
6967
7332
  dispatch,
6968
7333
  encode,
@@ -6980,6 +7345,7 @@ export {
6980
7345
  getConversationParticipantIds,
6981
7346
  getEnvironmentConfig,
6982
7347
  getMessageType,
7348
+ getPagedResourceCooldownMs,
6983
7349
  getPlatformWorkerUrl,
6984
7350
  getThreadCounts,
6985
7351
  getUserColor,
@@ -6988,6 +7354,7 @@ export {
6988
7354
  handleSyncMessage,
6989
7355
  hasContent,
6990
7356
  integration,
7357
+ isAsyncResourceSlow,
6991
7358
  isDMConversation,
6992
7359
  isDarkColor,
6993
7360
  isImageFile,
@@ -7005,7 +7372,11 @@ export {
7005
7372
  signOut,
7006
7373
  toConnectionStatus,
7007
7374
  toUint8Array,
7375
+ useAsyncResource,
7008
7376
  useAuth,
7377
+ useAuthProfileReady,
7378
+ useAuthReady,
7379
+ useAuthStatus,
7009
7380
  useAuthUser,
7010
7381
  useCanvas,
7011
7382
  useChannelMembers,
@@ -7022,6 +7393,7 @@ export {
7022
7393
  useJobs,
7023
7394
  useMessages,
7024
7395
  useMutations,
7396
+ usePagedResource,
7025
7397
  usePlatform,
7026
7398
  usePlatformWS,
7027
7399
  usePosts,