@medialane/ui 0.331.0 → 0.333.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/components/account/input-otp.d.cts +2 -2
  2. package/dist/components/account/input-otp.d.ts +2 -2
  3. package/dist/components/asset-page.cjs +24 -33
  4. package/dist/components/asset-page.cjs.map +1 -1
  5. package/dist/components/asset-page.d.cts +4 -2
  6. package/dist/components/asset-page.d.ts +4 -2
  7. package/dist/components/asset-page.js +24 -33
  8. package/dist/components/asset-page.js.map +1 -1
  9. package/dist/components/asset-top-sections.cjs +24 -28
  10. package/dist/components/asset-top-sections.cjs.map +1 -1
  11. package/dist/components/asset-top-sections.d.cts +2 -2
  12. package/dist/components/asset-top-sections.d.ts +2 -2
  13. package/dist/components/asset-top-sections.js +24 -28
  14. package/dist/components/asset-top-sections.js.map +1 -1
  15. package/dist/components/button.d.cts +2 -2
  16. package/dist/components/button.d.ts +2 -2
  17. package/dist/components/discover-community-section.cjs +79 -67
  18. package/dist/components/discover-community-section.cjs.map +1 -1
  19. package/dist/components/discover-community-section.js +79 -67
  20. package/dist/components/discover-community-section.js.map +1 -1
  21. package/dist/components/discover-features.cjs +4 -3
  22. package/dist/components/discover-features.cjs.map +1 -1
  23. package/dist/components/discover-features.js +5 -3
  24. package/dist/components/discover-features.js.map +1 -1
  25. package/dist/components/discover-page.cjs +1 -1
  26. package/dist/components/discover-page.cjs.map +1 -1
  27. package/dist/components/discover-page.js +1 -1
  28. package/dist/components/discover-page.js.map +1 -1
  29. package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
  30. package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
  31. package/dist/components/media-header.cjs +2 -0
  32. package/dist/components/media-header.cjs.map +1 -1
  33. package/dist/components/media-header.js +2 -0
  34. package/dist/components/media-header.js.map +1 -1
  35. package/dist/components/rewards/leaderboard-panel.cjs +2 -2
  36. package/dist/components/rewards/leaderboard-panel.cjs.map +1 -1
  37. package/dist/components/rewards/leaderboard-panel.js +2 -2
  38. package/dist/components/rewards/leaderboard-panel.js.map +1 -1
  39. package/dist/components/rewards/leaderboard-table.cjs +1 -1
  40. package/dist/components/rewards/leaderboard-table.cjs.map +1 -1
  41. package/dist/components/rewards/leaderboard-table.js +1 -1
  42. package/dist/components/rewards/leaderboard-table.js.map +1 -1
  43. package/dist/components/scroll-section.cjs.map +1 -1
  44. package/dist/components/scroll-section.d.cts +1 -1
  45. package/dist/components/scroll-section.d.ts +1 -1
  46. package/dist/components/scroll-section.js.map +1 -1
  47. package/dist/components/section-heading.cjs +1 -1
  48. package/dist/components/section-heading.cjs.map +1 -1
  49. package/dist/components/section-heading.d.cts +1 -1
  50. package/dist/components/section-heading.d.ts +1 -1
  51. package/dist/components/section-heading.js +1 -1
  52. package/dist/components/section-heading.js.map +1 -1
  53. package/dist/components/sheet.d.cts +1 -1
  54. package/dist/components/sheet.d.ts +1 -1
  55. package/dist/utils/use-collections.cjs +3 -3
  56. package/dist/utils/use-collections.cjs.map +1 -1
  57. package/dist/utils/use-collections.d.cts +2 -2
  58. package/dist/utils/use-collections.d.ts +2 -2
  59. package/dist/utils/use-collections.js +3 -3
  60. package/dist/utils/use-collections.js.map +1 -1
  61. package/dist/utils/use-tokens.cjs +4 -3
  62. package/dist/utils/use-tokens.cjs.map +1 -1
  63. package/dist/utils/use-tokens.d.cts +2 -1
  64. package/dist/utils/use-tokens.d.ts +2 -1
  65. package/dist/utils/use-tokens.js +4 -3
  66. package/dist/utils/use-tokens.js.map +1 -1
  67. package/package.json +1 -1
@@ -23,14 +23,14 @@ function useCollections(page = 1, limit = 20, isFeatured, sort = "recent", hideE
23
23
  mutate
24
24
  };
25
25
  }
26
- function useCollection(contract) {
26
+ function useCollection(contract, initial) {
27
27
  const client = useMedialaneClient();
28
28
  const { data, error, isLoading } = useSWR(
29
29
  contract ? queryKeys.collection(contract) : null,
30
30
  () => client.api.collections.get(contract),
31
- { revalidateOnFocus: false }
31
+ { revalidateOnFocus: false, fallbackData: initial ?? void 0 }
32
32
  );
33
- return { collection: data ?? null, isLoading, error };
33
+ return { collection: data ?? null, isLoading: isLoading && !data, error };
34
34
  }
35
35
  function useCollectionsByOwner(owner) {
36
36
  const client = useMedialaneClient();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/use-collections.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport type { ApiCollection, ApiResponse, CollectionTokensSort } from \"@medialane/sdk\";\nimport { queryKeys } from \"./query-keys.js\";\n\nexport type CollectionSort = \"recent\" | \"supply\" | \"floor\" | \"volume\" | \"name\";\n\nexport function useCollections(\n page = 1,\n limit = 20,\n isFeatured?: boolean,\n sort: CollectionSort = \"recent\",\n hideEmpty = true,\n service?: string,\n\n standard?: string,\n\n fallback?: ApiCollection[]\n) {\n const client = useMedialaneClient();\n const key = `${queryKeys.collections(page, limit, isFeatured, sort, hideEmpty, service)}-${standard ?? \"\"}`;\n\n const { data, error, isLoading, mutate } = useSWR<ApiResponse<ApiCollection[]>>(\n key,\n async () => {\n return client.api.collections.list({ page, limit, isFeatured, sort, service, standard, hideEmpty });\n },\n {\n revalidateOnFocus: false,\n ...(fallback ? { fallbackData: { data: fallback } as ApiResponse<ApiCollection[]> } : {}),\n }\n );\n\n return {\n collections: data?.data ?? [],\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useCollection( contract: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract ? queryKeys.collection(contract) : null,\n () => client.api.collections.get(contract!),\n { revalidateOnFocus: false }\n );\n\n return { collection: data ?? null, isLoading, error };\n}\n\nexport function useCollectionsByOwner( owner: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n owner ? queryKeys.collectionsOwner(owner) : null,\n () => client.api.collections.list({ owner: owner!, limit: 50 }),\n { revalidateOnFocus: false, refreshInterval: 60_000 }\n );\n\n return { collections: data?.data ?? [], isLoading, error, mutate };\n}\n\nexport function useCollectionTokens(\n contract: string | null,\n page = 1,\n limit = 24,\n sort: CollectionTokensSort = \"recent\"\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n contract ? queryKeys.collectionTokens(contract, page, limit, sort) : null,\n () => client.api.collections.tokens(contract!, { page: page, limit: limit, sort: sort }),\n { revalidateOnFocus: false }\n );\n\n return { tokens: data?.data ?? [], meta: data?.meta, isLoading, error, mutate };\n}\n\nfunction pickNearbyTokens<T extends { tokenId: string }>(\n tokens: T[],\n currentTokenId: string | null,\n count: number\n): T[] {\n if (!currentTokenId) return tokens.slice(0, count);\n const idx = tokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));\n if (idx === -1) return tokens.slice(0, count);\n\n const picked: T[] = [];\n let after = idx + 1;\n let before = idx - 1;\n while (picked.length < count && (after < tokens.length || before >= 0)) {\n if (after < tokens.length) picked.push(tokens[after++]);\n if (picked.length < count && before >= 0) picked.push(tokens[before--]);\n }\n return picked.sort((a, b) => Number(a.tokenId) - Number(b.tokenId));\n}\n\nexport function useNearbyCollectionTokens(\n contract: string | null,\n currentTokenId: string | null,\n count = 4,\n poolSize = 60\n) {\n const { tokens, isLoading, error } = useCollectionTokens(contract, 1, poolSize, \"oldest\");\n return { tokens: pickNearbyTokens(tokens, currentTokenId, count), isLoading, error };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/use-collections.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport type { ApiCollection, ApiResponse, CollectionTokensSort } from \"@medialane/sdk\";\nimport { queryKeys } from \"./query-keys.js\";\n\nexport type CollectionSort = \"recent\" | \"supply\" | \"floor\" | \"volume\" | \"name\";\n\nexport function useCollections(\n page = 1,\n limit = 20,\n isFeatured?: boolean,\n sort: CollectionSort = \"recent\",\n hideEmpty = true,\n service?: string,\n\n standard?: string,\n\n fallback?: ApiCollection[]\n) {\n const client = useMedialaneClient();\n const key = `${queryKeys.collections(page, limit, isFeatured, sort, hideEmpty, service)}-${standard ?? \"\"}`;\n\n const { data, error, isLoading, mutate } = useSWR<ApiResponse<ApiCollection[]>>(\n key,\n async () => {\n return client.api.collections.list({ page, limit, isFeatured, sort, service, standard, hideEmpty });\n },\n {\n revalidateOnFocus: false,\n ...(fallback ? { fallbackData: { data: fallback } as ApiResponse<ApiCollection[]> } : {}),\n }\n );\n\n return {\n collections: data?.data ?? [],\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useCollection( contract: string | null, initial?: ApiCollection | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract ? queryKeys.collection(contract) : null,\n () => client.api.collections.get(contract!),\n { revalidateOnFocus: false, fallbackData: initial ?? undefined }\n );\n\n return { collection: data ?? null, isLoading: isLoading && !data, error };\n}\n\nexport function useCollectionsByOwner( owner: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n owner ? queryKeys.collectionsOwner(owner) : null,\n () => client.api.collections.list({ owner: owner!, limit: 50 }),\n { revalidateOnFocus: false, refreshInterval: 60_000 }\n );\n\n return { collections: data?.data ?? [], isLoading, error, mutate };\n}\n\nexport function useCollectionTokens(\n contract: string | null,\n page = 1,\n limit = 24,\n sort: CollectionTokensSort = \"recent\"\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n contract ? queryKeys.collectionTokens(contract, page, limit, sort) : null,\n () => client.api.collections.tokens(contract!, { page: page, limit: limit, sort: sort }),\n { revalidateOnFocus: false }\n );\n\n return { tokens: data?.data ?? [], meta: data?.meta, isLoading, error, mutate };\n}\n\nfunction pickNearbyTokens<T extends { tokenId: string }>(\n tokens: T[],\n currentTokenId: string | null,\n count: number\n): T[] {\n if (!currentTokenId) return tokens.slice(0, count);\n const idx = tokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));\n if (idx === -1) return tokens.slice(0, count);\n\n const picked: T[] = [];\n let after = idx + 1;\n let before = idx - 1;\n while (picked.length < count && (after < tokens.length || before >= 0)) {\n if (after < tokens.length) picked.push(tokens[after++]);\n if (picked.length < count && before >= 0) picked.push(tokens[before--]);\n }\n return picked.sort((a, b) => Number(a.tokenId) - Number(b.tokenId));\n}\n\nexport function useNearbyCollectionTokens(\n contract: string | null,\n currentTokenId: string | null,\n count = 4,\n poolSize = 60\n) {\n const { tokens, isLoading, error } = useCollectionTokens(contract, 1, poolSize, \"oldest\");\n return { tokens: pickNearbyTokens(tokens, currentTokenId, count), isLoading, error };\n}\n"],"mappings":"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","names":[]}
@@ -49,7 +49,7 @@ function isNotIndexedYet(error) {
49
49
  error && typeof error === "object" && error.status === 404
50
50
  );
51
51
  }
52
- function useToken(contract, tokenId) {
52
+ function useToken(contract, tokenId, initial) {
53
53
  const client = (0, import_use_medialane_client.useMedialaneClient)();
54
54
  const [startedAt] = (0, import_react.useState)(() => Date.now());
55
55
  const { data, error, isLoading, mutate } = (0, import_swr.default)(
@@ -58,14 +58,15 @@ function useToken(contract, tokenId) {
58
58
  {
59
59
  revalidateOnFocus: false,
60
60
  shouldRetryOnError: false,
61
- refreshInterval: (latest) => latest || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS
61
+ fallbackData: initial ?? void 0,
62
+ refreshInterval: (latest) => latest || initial || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS
62
63
  }
63
64
  );
64
65
  const token = data ?? null;
65
66
  const withinWindow = Date.now() - startedAt <= INDEXING_WINDOW_MS;
66
67
  return {
67
68
  token,
68
- isLoading,
69
+ isLoading: isLoading && !token,
69
70
  isIndexing: !token && isNotIndexedYet(error) && withinWindow,
70
71
  error: isNotIndexedYet(error) ? void 0 : error,
71
72
  mutate
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/use-tokens.ts"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport useSWRInfinite from \"swr/infinite\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport { QUERY_PREFIX, queryKeys } from \"./query-keys.js\";\n\nconst EMPTY_TOKENS: ApiToken[] = [];\n\nconst INDEXING_POLL_MS = 10_000;\nconst INDEXING_WINDOW_MS = 60_000;\n\nfunction isNotIndexedYet(error: unknown): boolean {\n return Boolean(\n error && typeof error === \"object\" && (error as { status?: unknown }).status === 404,\n );\n}\n\nexport function useToken( contract: string | null, tokenId: string | null) {\n const client = useMedialaneClient();\n const [startedAt] = useState(() => Date.now());\n\n const { data, error, isLoading, mutate } = useSWR(\n contract && tokenId ? queryKeys.token(contract, tokenId) : null,\n () => client.api.tokens.get(contract!, tokenId!),\n {\n revalidateOnFocus: false,\n shouldRetryOnError: false,\n refreshInterval: (latest) =>\n latest || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS,\n }\n );\n\n const token = data ?? null;\n const withinWindow = Date.now() - startedAt <= INDEXING_WINDOW_MS;\n\n return {\n token,\n isLoading,\n isIndexing: !token && isNotIndexedYet(error) && withinWindow,\n error: isNotIndexedYet(error) ? undefined : error,\n mutate,\n };\n}\n\nexport function useTokenBalance(\n contract: string | null,\n tokenId: string | null,\n owner: string | null | undefined,\n) {\n const client = useMedialaneClient();\n\n const { data, mutate } = useSWR(\n contract && tokenId && owner ? queryKeys.tokenBalance(contract, tokenId, owner) : null,\n () => client.api.tokens.balance(contract!, tokenId!, owner!),\n { revalidateOnFocus: false }\n );\n\n return { amount: data?.amount ?? null, mutate };\n}\n\nexport function useTokensByOwner(\n address: string | null,\n page = 1,\n limit = 20,\n refreshMs = 60_000,\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n address ? queryKeys.tokensOwned(address, page, limit) : null,\n () => client.api.tokens.ownedBy(address!, { page: page, limit: limit }),\n { revalidateOnFocus: false, refreshInterval: refreshMs, revalidateOnMount: true }\n );\n\n return {\n tokens: data?.data ?? EMPTY_TOKENS,\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useOwnedTokens(address: string | null, limit = 20) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, isValidating, setSize, mutate } = useSWRInfinite(\n (index) => (address ? ([QUERY_PREFIX.tokensOwnedPages, address, limit, index + 1] as const) : null),\n ([, owner, pageSize, page]) => client.api.tokens.ownedBy(owner, { page, limit: pageSize }),\n { revalidateOnFocus: false, revalidateFirstPage: false },\n );\n\n const tokens = data ? data.flatMap((page) => page.data) : EMPTY_TOKENS;\n const total = data?.[0]?.meta?.total ?? null;\n\n return {\n tokens,\n total,\n isLoading,\n isLoadingMore: isValidating,\n hasMore: total !== null && tokens.length < total,\n loadMore: () => void setSize((size) => size + 1),\n error,\n mutate,\n };\n}\n\nexport function useTokenHistory( contract: string | null, tokenId: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract && tokenId ? queryKeys.tokenHistory(contract, tokenId) : null,\n () => client.api.tokens.history(contract!, tokenId!),\n { revalidateOnFocus: false }\n );\n\n return { history: data?.data ?? [], isLoading, error };\n}\n\n"],"mappings":"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","names":["useSWR","useSWRInfinite"]}
1
+ {"version":3,"sources":["../../src/utils/use-tokens.ts"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport useSWRInfinite from \"swr/infinite\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport { QUERY_PREFIX, queryKeys } from \"./query-keys.js\";\n\nconst EMPTY_TOKENS: ApiToken[] = [];\n\nconst INDEXING_POLL_MS = 10_000;\nconst INDEXING_WINDOW_MS = 60_000;\n\nfunction isNotIndexedYet(error: unknown): boolean {\n return Boolean(\n error && typeof error === \"object\" && (error as { status?: unknown }).status === 404,\n );\n}\n\nexport function useToken( contract: string | null, tokenId: string | null, initial?: ApiToken | null) {\n const client = useMedialaneClient();\n const [startedAt] = useState(() => Date.now());\n\n const { data, error, isLoading, mutate } = useSWR(\n contract && tokenId ? queryKeys.token(contract, tokenId) : null,\n () => client.api.tokens.get(contract!, tokenId!),\n {\n revalidateOnFocus: false,\n shouldRetryOnError: false,\n fallbackData: initial ?? undefined,\n refreshInterval: (latest) =>\n latest || initial || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS,\n }\n );\n\n const token = data ?? null;\n const withinWindow = Date.now() - startedAt <= INDEXING_WINDOW_MS;\n\n return {\n token,\n isLoading: isLoading && !token,\n isIndexing: !token && isNotIndexedYet(error) && withinWindow,\n error: isNotIndexedYet(error) ? undefined : error,\n mutate,\n };\n}\n\nexport function useTokenBalance(\n contract: string | null,\n tokenId: string | null,\n owner: string | null | undefined,\n) {\n const client = useMedialaneClient();\n\n const { data, mutate } = useSWR(\n contract && tokenId && owner ? queryKeys.tokenBalance(contract, tokenId, owner) : null,\n () => client.api.tokens.balance(contract!, tokenId!, owner!),\n { revalidateOnFocus: false }\n );\n\n return { amount: data?.amount ?? null, mutate };\n}\n\nexport function useTokensByOwner(\n address: string | null,\n page = 1,\n limit = 20,\n refreshMs = 60_000,\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n address ? queryKeys.tokensOwned(address, page, limit) : null,\n () => client.api.tokens.ownedBy(address!, { page: page, limit: limit }),\n { revalidateOnFocus: false, refreshInterval: refreshMs, revalidateOnMount: true }\n );\n\n return {\n tokens: data?.data ?? EMPTY_TOKENS,\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useOwnedTokens(address: string | null, limit = 20) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, isValidating, setSize, mutate } = useSWRInfinite(\n (index) => (address ? ([QUERY_PREFIX.tokensOwnedPages, address, limit, index + 1] as const) : null),\n ([, owner, pageSize, page]) => client.api.tokens.ownedBy(owner, { page, limit: pageSize }),\n { revalidateOnFocus: false, revalidateFirstPage: false },\n );\n\n const tokens = data ? data.flatMap((page) => page.data) : EMPTY_TOKENS;\n const total = data?.[0]?.meta?.total ?? null;\n\n return {\n tokens,\n total,\n isLoading,\n isLoadingMore: isValidating,\n hasMore: total !== null && tokens.length < total,\n loadMore: () => void setSize((size) => size + 1),\n error,\n mutate,\n };\n}\n\nexport function useTokenHistory( contract: string | null, tokenId: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract && tokenId ? queryKeys.tokenHistory(contract, tokenId) : null,\n () => client.api.tokens.history(contract!, tokenId!),\n { revalidateOnFocus: false }\n );\n\n return { history: data?.data ?? [], isLoading, error };\n}\n\n"],"mappings":"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","names":["useSWR","useSWRInfinite"]}
@@ -1,8 +1,9 @@
1
1
  import * as swr_infinite from 'swr/infinite';
2
2
  import * as _medialane_sdk from '@medialane/sdk';
3
+ import { ApiToken } from '@medialane/sdk';
3
4
  import * as swr from 'swr';
4
5
 
5
- declare function useToken(contract: string | null, tokenId: string | null): {
6
+ declare function useToken(contract: string | null, tokenId: string | null, initial?: ApiToken | null): {
6
7
  token: {
7
8
  id: string;
8
9
  chain: string;
@@ -1,8 +1,9 @@
1
1
  import * as swr_infinite from 'swr/infinite';
2
2
  import * as _medialane_sdk from '@medialane/sdk';
3
+ import { ApiToken } from '@medialane/sdk';
3
4
  import * as swr from 'swr';
4
5
 
5
- declare function useToken(contract: string | null, tokenId: string | null): {
6
+ declare function useToken(contract: string | null, tokenId: string | null, initial?: ApiToken | null): {
6
7
  token: {
7
8
  id: string;
8
9
  chain: string;
@@ -12,7 +12,7 @@ function isNotIndexedYet(error) {
12
12
  error && typeof error === "object" && error.status === 404
13
13
  );
14
14
  }
15
- function useToken(contract, tokenId) {
15
+ function useToken(contract, tokenId, initial) {
16
16
  const client = useMedialaneClient();
17
17
  const [startedAt] = useState(() => Date.now());
18
18
  const { data, error, isLoading, mutate } = useSWR(
@@ -21,14 +21,15 @@ function useToken(contract, tokenId) {
21
21
  {
22
22
  revalidateOnFocus: false,
23
23
  shouldRetryOnError: false,
24
- refreshInterval: (latest) => latest || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS
24
+ fallbackData: initial ?? void 0,
25
+ refreshInterval: (latest) => latest || initial || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS
25
26
  }
26
27
  );
27
28
  const token = data ?? null;
28
29
  const withinWindow = Date.now() - startedAt <= INDEXING_WINDOW_MS;
29
30
  return {
30
31
  token,
31
- isLoading,
32
+ isLoading: isLoading && !token,
32
33
  isIndexing: !token && isNotIndexedYet(error) && withinWindow,
33
34
  error: isNotIndexedYet(error) ? void 0 : error,
34
35
  mutate
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/use-tokens.ts"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport useSWRInfinite from \"swr/infinite\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport { QUERY_PREFIX, queryKeys } from \"./query-keys.js\";\n\nconst EMPTY_TOKENS: ApiToken[] = [];\n\nconst INDEXING_POLL_MS = 10_000;\nconst INDEXING_WINDOW_MS = 60_000;\n\nfunction isNotIndexedYet(error: unknown): boolean {\n return Boolean(\n error && typeof error === \"object\" && (error as { status?: unknown }).status === 404,\n );\n}\n\nexport function useToken( contract: string | null, tokenId: string | null) {\n const client = useMedialaneClient();\n const [startedAt] = useState(() => Date.now());\n\n const { data, error, isLoading, mutate } = useSWR(\n contract && tokenId ? queryKeys.token(contract, tokenId) : null,\n () => client.api.tokens.get(contract!, tokenId!),\n {\n revalidateOnFocus: false,\n shouldRetryOnError: false,\n refreshInterval: (latest) =>\n latest || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS,\n }\n );\n\n const token = data ?? null;\n const withinWindow = Date.now() - startedAt <= INDEXING_WINDOW_MS;\n\n return {\n token,\n isLoading,\n isIndexing: !token && isNotIndexedYet(error) && withinWindow,\n error: isNotIndexedYet(error) ? undefined : error,\n mutate,\n };\n}\n\nexport function useTokenBalance(\n contract: string | null,\n tokenId: string | null,\n owner: string | null | undefined,\n) {\n const client = useMedialaneClient();\n\n const { data, mutate } = useSWR(\n contract && tokenId && owner ? queryKeys.tokenBalance(contract, tokenId, owner) : null,\n () => client.api.tokens.balance(contract!, tokenId!, owner!),\n { revalidateOnFocus: false }\n );\n\n return { amount: data?.amount ?? null, mutate };\n}\n\nexport function useTokensByOwner(\n address: string | null,\n page = 1,\n limit = 20,\n refreshMs = 60_000,\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n address ? queryKeys.tokensOwned(address, page, limit) : null,\n () => client.api.tokens.ownedBy(address!, { page: page, limit: limit }),\n { revalidateOnFocus: false, refreshInterval: refreshMs, revalidateOnMount: true }\n );\n\n return {\n tokens: data?.data ?? EMPTY_TOKENS,\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useOwnedTokens(address: string | null, limit = 20) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, isValidating, setSize, mutate } = useSWRInfinite(\n (index) => (address ? ([QUERY_PREFIX.tokensOwnedPages, address, limit, index + 1] as const) : null),\n ([, owner, pageSize, page]) => client.api.tokens.ownedBy(owner, { page, limit: pageSize }),\n { revalidateOnFocus: false, revalidateFirstPage: false },\n );\n\n const tokens = data ? data.flatMap((page) => page.data) : EMPTY_TOKENS;\n const total = data?.[0]?.meta?.total ?? null;\n\n return {\n tokens,\n total,\n isLoading,\n isLoadingMore: isValidating,\n hasMore: total !== null && tokens.length < total,\n loadMore: () => void setSize((size) => size + 1),\n error,\n mutate,\n };\n}\n\nexport function useTokenHistory( contract: string | null, tokenId: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract && tokenId ? queryKeys.tokenHistory(contract, tokenId) : null,\n () => client.api.tokens.history(contract!, tokenId!),\n { revalidateOnFocus: false }\n );\n\n return { history: data?.data ?? [], isLoading, error };\n}\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/use-tokens.ts"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport useSWRInfinite from \"swr/infinite\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport { QUERY_PREFIX, queryKeys } from \"./query-keys.js\";\n\nconst EMPTY_TOKENS: ApiToken[] = [];\n\nconst INDEXING_POLL_MS = 10_000;\nconst INDEXING_WINDOW_MS = 60_000;\n\nfunction isNotIndexedYet(error: unknown): boolean {\n return Boolean(\n error && typeof error === \"object\" && (error as { status?: unknown }).status === 404,\n );\n}\n\nexport function useToken( contract: string | null, tokenId: string | null, initial?: ApiToken | null) {\n const client = useMedialaneClient();\n const [startedAt] = useState(() => Date.now());\n\n const { data, error, isLoading, mutate } = useSWR(\n contract && tokenId ? queryKeys.token(contract, tokenId) : null,\n () => client.api.tokens.get(contract!, tokenId!),\n {\n revalidateOnFocus: false,\n shouldRetryOnError: false,\n fallbackData: initial ?? undefined,\n refreshInterval: (latest) =>\n latest || initial || Date.now() - startedAt > INDEXING_WINDOW_MS ? 0 : INDEXING_POLL_MS,\n }\n );\n\n const token = data ?? null;\n const withinWindow = Date.now() - startedAt <= INDEXING_WINDOW_MS;\n\n return {\n token,\n isLoading: isLoading && !token,\n isIndexing: !token && isNotIndexedYet(error) && withinWindow,\n error: isNotIndexedYet(error) ? undefined : error,\n mutate,\n };\n}\n\nexport function useTokenBalance(\n contract: string | null,\n tokenId: string | null,\n owner: string | null | undefined,\n) {\n const client = useMedialaneClient();\n\n const { data, mutate } = useSWR(\n contract && tokenId && owner ? queryKeys.tokenBalance(contract, tokenId, owner) : null,\n () => client.api.tokens.balance(contract!, tokenId!, owner!),\n { revalidateOnFocus: false }\n );\n\n return { amount: data?.amount ?? null, mutate };\n}\n\nexport function useTokensByOwner(\n address: string | null,\n page = 1,\n limit = 20,\n refreshMs = 60_000,\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n address ? queryKeys.tokensOwned(address, page, limit) : null,\n () => client.api.tokens.ownedBy(address!, { page: page, limit: limit }),\n { revalidateOnFocus: false, refreshInterval: refreshMs, revalidateOnMount: true }\n );\n\n return {\n tokens: data?.data ?? EMPTY_TOKENS,\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useOwnedTokens(address: string | null, limit = 20) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, isValidating, setSize, mutate } = useSWRInfinite(\n (index) => (address ? ([QUERY_PREFIX.tokensOwnedPages, address, limit, index + 1] as const) : null),\n ([, owner, pageSize, page]) => client.api.tokens.ownedBy(owner, { page, limit: pageSize }),\n { revalidateOnFocus: false, revalidateFirstPage: false },\n );\n\n const tokens = data ? data.flatMap((page) => page.data) : EMPTY_TOKENS;\n const total = data?.[0]?.meta?.total ?? null;\n\n return {\n tokens,\n total,\n isLoading,\n isLoadingMore: isValidating,\n hasMore: total !== null && tokens.length < total,\n loadMore: () => void setSize((size) => size + 1),\n error,\n mutate,\n };\n}\n\nexport function useTokenHistory( contract: string | null, tokenId: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract && tokenId ? queryKeys.tokenHistory(contract, tokenId) : null,\n () => client.api.tokens.history(contract!, tokenId!),\n { revalidateOnFocus: false }\n );\n\n return { history: data?.data ?? [], isLoading, error };\n}\n\n"],"mappings":";AAEA,SAAS,gBAAgB;AACzB,OAAO,YAAY;AACnB,OAAO,oBAAoB;AAE3B,SAAS,0BAA0B;AACnC,SAAS,cAAc,iBAAiB;AAExC,MAAM,eAA2B,CAAC;AAElC,MAAM,mBAAmB;AACzB,MAAM,qBAAqB;AAE3B,SAAS,gBAAgB,OAAyB;AAChD,SAAO;AAAA,IACL,SAAS,OAAO,UAAU,YAAa,MAA+B,WAAW;AAAA,EACnF;AACF;AAEO,SAAS,SAAU,UAAyB,SAAwB,SAA2B;AACpG,QAAM,SAAS,mBAAmB;AAClC,QAAM,CAAC,SAAS,IAAI,SAAS,MAAM,KAAK,IAAI,CAAC;AAE7C,QAAM,EAAE,MAAM,OAAO,WAAW,OAAO,IAAI;AAAA,IACzC,YAAY,UAAU,UAAU,MAAM,UAAU,OAAO,IAAI;AAAA,IAC3D,MAAM,OAAO,IAAI,OAAO,IAAI,UAAW,OAAQ;AAAA,IAC/C;AAAA,MACE,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,cAAc,WAAW;AAAA,MACzB,iBAAiB,CAAC,WAChB,UAAU,WAAW,KAAK,IAAI,IAAI,YAAY,qBAAqB,IAAI;AAAA,IAC3E;AAAA,EACF;AAEA,QAAM,QAAQ,QAAQ;AACtB,QAAM,eAAe,KAAK,IAAI,IAAI,aAAa;AAE/C,SAAO;AAAA,IACL;AAAA,IACA,WAAW,aAAa,CAAC;AAAA,IACzB,YAAY,CAAC,SAAS,gBAAgB,KAAK,KAAK;AAAA,IAChD,OAAO,gBAAgB,KAAK,IAAI,SAAY;AAAA,IAC5C;AAAA,EACF;AACF;AAEO,SAAS,gBACd,UACA,SACA,OACA;AACA,QAAM,SAAS,mBAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,IAAI;AAAA,IACvB,YAAY,WAAW,QAAQ,UAAU,aAAa,UAAU,SAAS,KAAK,IAAI;AAAA,IAClF,MAAM,OAAO,IAAI,OAAO,QAAQ,UAAW,SAAU,KAAM;AAAA,IAC3D,EAAE,mBAAmB,MAAM;AAAA,EAC7B;AAEA,SAAO,EAAE,QAAQ,MAAM,UAAU,MAAM,OAAO;AAChD;AAEO,SAAS,iBACd,SACA,OAAO,GACP,QAAQ,IACR,YAAY,KACZ;AACA,QAAM,SAAS,mBAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,WAAW,OAAO,IAAI;AAAA,IACzC,UAAU,UAAU,YAAY,SAAS,MAAM,KAAK,IAAI;AAAA,IACxD,MAAM,OAAO,IAAI,OAAO,QAAQ,SAAU,EAAE,MAAY,MAAa,CAAC;AAAA,IACtE,EAAE,mBAAmB,OAAO,iBAAiB,WAAW,mBAAmB,KAAK;AAAA,EAClF;AAEA,SAAO;AAAA,IACL,QAAQ,MAAM,QAAQ;AAAA,IACtB,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,eAAe,SAAwB,QAAQ,IAAI;AACjE,QAAM,SAAS,mBAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,WAAW,cAAc,SAAS,OAAO,IAAI;AAAA,IAChE,CAAC,UAAW,UAAW,CAAC,aAAa,kBAAkB,SAAS,OAAO,QAAQ,CAAC,IAAc;AAAA,IAC9F,CAAC,CAAC,EAAE,OAAO,UAAU,IAAI,MAAM,OAAO,IAAI,OAAO,QAAQ,OAAO,EAAE,MAAM,OAAO,SAAS,CAAC;AAAA,IACzF,EAAE,mBAAmB,OAAO,qBAAqB,MAAM;AAAA,EACzD;AAEA,QAAM,SAAS,OAAO,KAAK,QAAQ,CAAC,SAAS,KAAK,IAAI,IAAI;AAC1D,QAAM,QAAQ,OAAO,CAAC,GAAG,MAAM,SAAS;AAExC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf,SAAS,UAAU,QAAQ,OAAO,SAAS;AAAA,IAC3C,UAAU,MAAM,KAAK,QAAQ,CAAC,SAAS,OAAO,CAAC;AAAA,IAC/C;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,gBAAiB,UAAyB,SAAwB;AAChF,QAAM,SAAS,mBAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,UAAU,IAAI;AAAA,IACjC,YAAY,UAAU,UAAU,aAAa,UAAU,OAAO,IAAI;AAAA,IAClE,MAAM,OAAO,IAAI,OAAO,QAAQ,UAAW,OAAQ;AAAA,IACnD,EAAE,mBAAmB,MAAM;AAAA,EAC7B;AAEA,SAAO,EAAE,SAAS,MAAM,QAAQ,CAAC,GAAG,WAAW,MAAM;AACvD;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.331.0",
3
+ "version": "0.333.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,