@openrails/contentkit-ui 0.93.0 → 0.94.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 (56) hide show
  1. package/README.md +34 -4
  2. package/dist/client/browser-reader-preferences.d.ts +38 -0
  3. package/dist/client/browser-reader-preferences.js +172 -0
  4. package/dist/client/browser-reader-preferences.js.map +1 -0
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +27 -25
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/discovery.js +24 -23
  9. package/dist/client/discovery.js.map +1 -1
  10. package/dist/client/generated/routes.d.ts +15 -2
  11. package/dist/client/generated/routes.js +18 -2
  12. package/dist/client/generated/routes.js.map +1 -1
  13. package/dist/client/generated/wire.d.ts +5 -0
  14. package/dist/client/generated/wire.js.map +1 -1
  15. package/dist/client/http.d.ts +18 -1
  16. package/dist/client/http.js +67 -26
  17. package/dist/client/http.js.map +1 -1
  18. package/dist/client/index.d.ts +2 -0
  19. package/dist/client/reader-preferences.d.ts +46 -0
  20. package/dist/client/reader-preferences.js +147 -0
  21. package/dist/client/reader-preferences.js.map +1 -0
  22. package/dist/client.js +8 -6
  23. package/dist/components/content/filters.d.ts +1 -1
  24. package/dist/components/content/filters.js +1 -5
  25. package/dist/components/content/filters.js.map +1 -1
  26. package/dist/components/content/reader-settings.d.ts +1 -1
  27. package/dist/components/content/reader-settings.js +67 -44
  28. package/dist/components/content/reader-settings.js.map +1 -1
  29. package/dist/locales/discovery/de.js +2 -0
  30. package/dist/locales/discovery/de.js.map +1 -1
  31. package/dist/locales/discovery/en.d.ts +2 -0
  32. package/dist/locales/discovery/en.js +2 -0
  33. package/dist/locales/discovery/en.js.map +1 -1
  34. package/dist/locales/discovery/es.js +2 -0
  35. package/dist/locales/discovery/es.js.map +1 -1
  36. package/dist/locales/discovery/ja.js +2 -0
  37. package/dist/locales/discovery/ja.js.map +1 -1
  38. package/dist/locales/discovery/ko.js +2 -0
  39. package/dist/locales/discovery/ko.js.map +1 -1
  40. package/dist/locales/discovery/zh.js +2 -0
  41. package/dist/locales/discovery/zh.js.map +1 -1
  42. package/dist/locales/en.d.ts +2 -0
  43. package/dist/react/context.d.ts +1 -1
  44. package/dist/react/context.js.map +1 -1
  45. package/dist/react/discovery.d.ts +2 -2
  46. package/dist/react/discovery.js +187 -149
  47. package/dist/react/discovery.js.map +1 -1
  48. package/dist/react/index.d.ts +1 -0
  49. package/dist/react/provider.d.ts +4 -1
  50. package/dist/react/provider.js +38 -31
  51. package/dist/react/provider.js.map +1 -1
  52. package/dist/react/reader-preferences.d.ts +13 -0
  53. package/dist/react/reader-preferences.js +15 -0
  54. package/dist/react/reader-preferences.js.map +1 -0
  55. package/dist/react.js +3 -2
  56. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { ReadStore } from './store.js';
5
5
  /** What failed: a component's or hook's save, load or render step. */
6
6
  export type ContentKitOperation = "poster.load" | "poster.frame" | "poster.save" | "slot.load" | "slot.decode" | "slot.save" | "slot.remove" | "upload" | "folder.load" | "folder.commit" | "folder.update" | "folder.process" | "crop.load" | "crop.save" | "version.download" | SocialOperation;
7
7
  /** What failed in a content component: a load or a write. */
8
- export type SocialOperation = "comment.load" | "comment.post" | "comment.edit" | "comment.delete" | "comment.react" | "comment.restore" | "ban.save" | "ban.lift" | "reaction.save" | "favorite.save" | "poll.load" | "poll.vote" | "poll.answer" | "poll.save" | "post.load" | "content.save" | "moderation.load" | "moderation.resolve" | "rules.save" | "reader.save" | "media.save" | "notifications.load" | "notifications.read" | "notifications.dismiss" | "group.load" | "group.save" | "membership.save" | "history.forget" | "filters.save" | "offer.save" | "membership.join";
8
+ export type SocialOperation = "comment.load" | "comment.post" | "comment.edit" | "comment.delete" | "comment.react" | "comment.restore" | "ban.save" | "ban.lift" | "reaction.save" | "favorite.save" | "poll.load" | "poll.vote" | "poll.answer" | "poll.save" | "post.load" | "content.save" | "moderation.load" | "moderation.resolve" | "rules.save" | "reader.save" | "media.save" | "notifications.load" | "notifications.read" | "notifications.dismiss" | "group.load" | "group.save" | "membership.save" | "history.forget" | "filters.save" | "preferences.save" | "offer.save" | "membership.join";
9
9
  /** The failure's context: the operation and, for one file, its name. */
10
10
  export interface ContentKitErrorInfo {
11
11
  operation: ContentKitOperation;
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../src/react/context.ts"],"sourcesContent":["import { createContext, useCallback, useContext, useLayoutEffect, useRef } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { toContentKitError, type ContentKitError } from \"../client/errors.js\";\nimport type { ContentURLs } from \"../urls/index.js\";\nimport type { ReadStore } from \"./store.js\";\n\n/** What failed: a component's or hook's save, load or render step. */\nexport type ContentKitOperation =\n | \"poster.load\"\n | \"poster.frame\"\n | \"poster.save\"\n | \"slot.load\"\n | \"slot.decode\"\n | \"slot.save\"\n | \"slot.remove\"\n | \"upload\"\n | \"folder.load\"\n | \"folder.commit\"\n | \"folder.update\"\n | \"folder.process\"\n | \"crop.load\"\n | \"crop.save\"\n | \"version.download\"\n | SocialOperation;\n\n/** What failed in a content component: a load or a write. */\nexport type SocialOperation =\n | \"comment.load\"\n | \"comment.post\"\n | \"comment.edit\"\n | \"comment.delete\"\n | \"comment.react\"\n | \"comment.restore\"\n | \"ban.save\"\n | \"ban.lift\"\n | \"reaction.save\"\n | \"favorite.save\"\n | \"poll.load\"\n | \"poll.vote\"\n | \"poll.answer\"\n | \"poll.save\"\n | \"post.load\"\n | \"content.save\"\n | \"moderation.load\"\n | \"moderation.resolve\"\n | \"rules.save\"\n | \"reader.save\"\n | \"media.save\"\n | \"notifications.load\"\n | \"notifications.read\"\n | \"notifications.dismiss\"\n | \"group.load\"\n | \"group.save\"\n | \"membership.save\"\n | \"history.forget\"\n | \"filters.save\"\n | \"offer.save\"\n | \"membership.join\";\n\n/** The failure's context: the operation and, for one file, its name. */\nexport interface ContentKitErrorInfo {\n operation: ContentKitOperation;\n file?: string;\n}\n\n/**\n * Every failure a component shows is also reported here (aborts excepted), so\n * the host can toast or log it. Components still show it in place.\n */\nexport type ContentKitErrorHandler = (error: ContentKitError, info: ContentKitErrorInfo) => void;\n\n/** The host router: in-app navigation, e.g. a canonical replace. */\nexport type Navigate = (to: string, options?: { replace?: boolean }) => void;\n\nexport interface ContentKitContextValue {\n client: ContentKitClient;\n /**\n * The signed-in user's id as ContentKit sees it, null when signed out,\n * undefined when the host does not say. Content reads are kept per viewer.\n */\n viewer?: string | null;\n /** Request language; keep it in sync with the client's language callback. */\n language?: string;\n /** Change when the current viewer's permissions or entitlements change. */\n accessRevision?: string | number;\n readScope: string;\n /** Asks the visitor to sign in; with it, signed-out visitors are prompted instead of acting anonymously. */\n onSignIn?: () => void;\n /** The host's content URL config (createContentURLs). */\n urls?: ContentURLs;\n navigate?: Navigate;\n onError?: ContentKitErrorHandler;\n /** The reads hooks share. */\n store: ReadStore;\n}\n\nexport const ContentKitContext = createContext<ContentKitContextValue | null>(null);\n\n/** Values that can change a read without changing its content reference. */\nexport function useReadScope(): string {\n return useContext(ContentKitContext)?.readScope ?? \"{}\";\n}\n\n/** The ContentKitProvider's value; throws outside one. */\nexport function useContentKit(): ContentKitContextValue {\n const ctx = useContext(ContentKitContext);\n if (!ctx) throw new Error(\"contentkit-ui: wrap the tree in <ContentKitProvider client>\");\n return ctx;\n}\n\n/** The client a hook or component uses: its own, else the provider's; throws without either. */\nexport function useContentKitClient(own?: ContentKitClient | null): ContentKitClient {\n const c = useOptionalContentKitClient(own);\n if (!c) throw new Error(\"contentkit-ui: pass `client` or render inside <ContentKitProvider client>\");\n return c;\n}\n\nexport function useOptionalContentKitClient(own?: ContentKitClient | null): ContentKitClient | null {\n const ctx = useContext(ContentKitContext);\n const client = own ?? ctx?.client ?? null;\n const scope = useReadScope();\n useLayoutEffect(() => { client?.setReadScope(scope); }, [client, scope]);\n return client;\n}\n\n/** The provider's content URL helpers; throws when none were given. */\nexport function useContentURLs(): ContentURLs {\n const urls = useContext(ContentKitContext)?.urls;\n if (!urls) throw new Error(\"contentkit-ui: pass `urls` to <ContentKitProvider>\");\n return urls;\n}\n\n/** A stable reporter: the component's own `onError`, else the provider's. */\nexport function useErrorReporter(own?: ContentKitErrorHandler): (e: unknown, operation: ContentKitOperation, file?: string) => void {\n const ctx = useContext(ContentKitContext)?.onError;\n const handler = useRef(own ?? ctx);\n handler.current = own ?? ctx;\n return useCallback((e: unknown, operation: ContentKitOperation, file?: string) => {\n const error = toContentKitError(e);\n if (error.code !== \"aborted\") handler.current?.(error, file === undefined ? { operation } : { operation, file });\n }, []);\n}\n\n/** Runs a write, e.g. auth-ui's useStepUpGuard(): re-authenticates when the write asks for a recent sign-in, then retries. */\nexport type ContentKitGuard = <T>(write: () => Promise<T>) => Promise<T>;\n\n/** The admin flow's guard; hooks run their writes through it. */\nexport const GuardContext = createContext<ContentKitGuard | undefined>(undefined);\n\n/** Runs fn through the flow's guard, when the host gave one. */\nexport function useGuarded(): <T>(fn: () => Promise<T>) => Promise<T> {\n const guard = useContext(GuardContext);\n return useCallback(<T,>(fn: () => Promise<T>) => (guard ? guard(fn) : fn()), [guard]);\n}\n"],"mappings":";;;AAgGA,IAAa,IAAoB,EAA6C,IAAI;AAGlF,SAAgB,IAAuB;CACrC,OAAO,EAAW,CAAiB,CAAC,EAAE,aAAa;AACrD;AAGA,SAAgB,IAAwC;CACtD,IAAM,IAAM,EAAW,CAAiB;CACxC,IAAI,CAAC,GAAK,MAAU,MAAM,6DAA6D;CACvF,OAAO;AACT;AAGA,SAAgB,EAAoB,GAAiD;CACnF,IAAM,IAAI,EAA4B,CAAG;CACzC,IAAI,CAAC,GAAG,MAAU,MAAM,2EAA2E;CACnG,OAAO;AACT;AAEA,SAAgB,EAA4B,GAAwD;CAClG,IAAM,IAAM,EAAW,CAAiB,GAClC,IAAS,KAAO,GAAK,UAAU,MAC/B,IAAQ,EAAa;CAE3B,OADA,QAAsB;EAAE,GAAQ,aAAa,CAAK;CAAG,GAAG,CAAC,GAAQ,CAAK,CAAC,GAChE;AACT;AAGA,SAAgB,IAA8B;CAC5C,IAAM,IAAO,EAAW,CAAiB,CAAC,EAAE;CAC5C,IAAI,CAAC,GAAM,MAAU,MAAM,oDAAoD;CAC/E,OAAO;AACT;AAGA,SAAgB,EAAiB,GAAmG;CAClI,IAAM,IAAM,EAAW,CAAiB,CAAC,EAAE,SACrC,IAAU,EAAO,KAAO,CAAG;CAEjC,OADA,EAAQ,UAAU,KAAO,GAClB,GAAa,GAAY,GAAgC,MAAkB;EAChF,IAAM,IAAQ,EAAkB,CAAC;EACjC,AAAI,EAAM,SAAS,aAAW,EAAQ,UAAU,GAAO,MAAS,KAAA,IAAY,EAAE,aAAU,IAAI;GAAE;GAAW;EAAK,CAAC;CACjH,GAAG,CAAC,CAAC;AACP;AAMA,IAAa,IAAe,EAA2C,KAAA,CAAS;AAGhF,SAAgB,IAAsD;CACpE,IAAM,IAAQ,EAAW,CAAY;CACrC,OAAO,GAAiB,MAA0B,IAAQ,EAAM,CAAE,IAAI,EAAG,GAAI,CAAC,CAAK,CAAC;AACtF"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../src/react/context.ts"],"sourcesContent":["import { createContext, useCallback, useContext, useLayoutEffect, useRef } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { toContentKitError, type ContentKitError } from \"../client/errors.js\";\nimport type { ContentURLs } from \"../urls/index.js\";\nimport type { ReadStore } from \"./store.js\";\n\n/** What failed: a component's or hook's save, load or render step. */\nexport type ContentKitOperation =\n | \"poster.load\"\n | \"poster.frame\"\n | \"poster.save\"\n | \"slot.load\"\n | \"slot.decode\"\n | \"slot.save\"\n | \"slot.remove\"\n | \"upload\"\n | \"folder.load\"\n | \"folder.commit\"\n | \"folder.update\"\n | \"folder.process\"\n | \"crop.load\"\n | \"crop.save\"\n | \"version.download\"\n | SocialOperation;\n\n/** What failed in a content component: a load or a write. */\nexport type SocialOperation =\n | \"comment.load\"\n | \"comment.post\"\n | \"comment.edit\"\n | \"comment.delete\"\n | \"comment.react\"\n | \"comment.restore\"\n | \"ban.save\"\n | \"ban.lift\"\n | \"reaction.save\"\n | \"favorite.save\"\n | \"poll.load\"\n | \"poll.vote\"\n | \"poll.answer\"\n | \"poll.save\"\n | \"post.load\"\n | \"content.save\"\n | \"moderation.load\"\n | \"moderation.resolve\"\n | \"rules.save\"\n | \"reader.save\"\n | \"media.save\"\n | \"notifications.load\"\n | \"notifications.read\"\n | \"notifications.dismiss\"\n | \"group.load\"\n | \"group.save\"\n | \"membership.save\"\n | \"history.forget\"\n | \"filters.save\"\n | \"preferences.save\"\n | \"offer.save\"\n | \"membership.join\";\n\n/** The failure's context: the operation and, for one file, its name. */\nexport interface ContentKitErrorInfo {\n operation: ContentKitOperation;\n file?: string;\n}\n\n/**\n * Every failure a component shows is also reported here (aborts excepted), so\n * the host can toast or log it. Components still show it in place.\n */\nexport type ContentKitErrorHandler = (error: ContentKitError, info: ContentKitErrorInfo) => void;\n\n/** The host router: in-app navigation, e.g. a canonical replace. */\nexport type Navigate = (to: string, options?: { replace?: boolean }) => void;\n\nexport interface ContentKitContextValue {\n client: ContentKitClient;\n /**\n * The signed-in user's id as ContentKit sees it, null when signed out,\n * undefined when the host does not say. Content reads are kept per viewer.\n */\n viewer?: string | null;\n /** Request language; keep it in sync with the client's language callback. */\n language?: string;\n /** Change when the current viewer's permissions or entitlements change. */\n accessRevision?: string | number;\n readScope: string;\n /** Asks the visitor to sign in; with it, signed-out visitors are prompted instead of acting anonymously. */\n onSignIn?: () => void;\n /** The host's content URL config (createContentURLs). */\n urls?: ContentURLs;\n navigate?: Navigate;\n onError?: ContentKitErrorHandler;\n /** The reads hooks share. */\n store: ReadStore;\n}\n\nexport const ContentKitContext = createContext<ContentKitContextValue | null>(null);\n\n/** Values that can change a read without changing its content reference. */\nexport function useReadScope(): string {\n return useContext(ContentKitContext)?.readScope ?? \"{}\";\n}\n\n/** The ContentKitProvider's value; throws outside one. */\nexport function useContentKit(): ContentKitContextValue {\n const ctx = useContext(ContentKitContext);\n if (!ctx) throw new Error(\"contentkit-ui: wrap the tree in <ContentKitProvider client>\");\n return ctx;\n}\n\n/** The client a hook or component uses: its own, else the provider's; throws without either. */\nexport function useContentKitClient(own?: ContentKitClient | null): ContentKitClient {\n const c = useOptionalContentKitClient(own);\n if (!c) throw new Error(\"contentkit-ui: pass `client` or render inside <ContentKitProvider client>\");\n return c;\n}\n\nexport function useOptionalContentKitClient(own?: ContentKitClient | null): ContentKitClient | null {\n const ctx = useContext(ContentKitContext);\n const client = own ?? ctx?.client ?? null;\n const scope = useReadScope();\n useLayoutEffect(() => { client?.setReadScope(scope); }, [client, scope]);\n return client;\n}\n\n/** The provider's content URL helpers; throws when none were given. */\nexport function useContentURLs(): ContentURLs {\n const urls = useContext(ContentKitContext)?.urls;\n if (!urls) throw new Error(\"contentkit-ui: pass `urls` to <ContentKitProvider>\");\n return urls;\n}\n\n/** A stable reporter: the component's own `onError`, else the provider's. */\nexport function useErrorReporter(own?: ContentKitErrorHandler): (e: unknown, operation: ContentKitOperation, file?: string) => void {\n const ctx = useContext(ContentKitContext)?.onError;\n const handler = useRef(own ?? ctx);\n handler.current = own ?? ctx;\n return useCallback((e: unknown, operation: ContentKitOperation, file?: string) => {\n const error = toContentKitError(e);\n if (error.code !== \"aborted\") handler.current?.(error, file === undefined ? { operation } : { operation, file });\n }, []);\n}\n\n/** Runs a write, e.g. auth-ui's useStepUpGuard(): re-authenticates when the write asks for a recent sign-in, then retries. */\nexport type ContentKitGuard = <T>(write: () => Promise<T>) => Promise<T>;\n\n/** The admin flow's guard; hooks run their writes through it. */\nexport const GuardContext = createContext<ContentKitGuard | undefined>(undefined);\n\n/** Runs fn through the flow's guard, when the host gave one. */\nexport function useGuarded(): <T>(fn: () => Promise<T>) => Promise<T> {\n const guard = useContext(GuardContext);\n return useCallback(<T,>(fn: () => Promise<T>) => (guard ? guard(fn) : fn()), [guard]);\n}\n"],"mappings":";;;AAiGA,IAAa,IAAoB,EAA6C,IAAI;AAGlF,SAAgB,IAAuB;CACrC,OAAO,EAAW,CAAiB,CAAC,EAAE,aAAa;AACrD;AAGA,SAAgB,IAAwC;CACtD,IAAM,IAAM,EAAW,CAAiB;CACxC,IAAI,CAAC,GAAK,MAAU,MAAM,6DAA6D;CACvF,OAAO;AACT;AAGA,SAAgB,EAAoB,GAAiD;CACnF,IAAM,IAAI,EAA4B,CAAG;CACzC,IAAI,CAAC,GAAG,MAAU,MAAM,2EAA2E;CACnG,OAAO;AACT;AAEA,SAAgB,EAA4B,GAAwD;CAClG,IAAM,IAAM,EAAW,CAAiB,GAClC,IAAS,KAAO,GAAK,UAAU,MAC/B,IAAQ,EAAa;CAE3B,OADA,QAAsB;EAAE,GAAQ,aAAa,CAAK;CAAG,GAAG,CAAC,GAAQ,CAAK,CAAC,GAChE;AACT;AAGA,SAAgB,IAA8B;CAC5C,IAAM,IAAO,EAAW,CAAiB,CAAC,EAAE;CAC5C,IAAI,CAAC,GAAM,MAAU,MAAM,oDAAoD;CAC/E,OAAO;AACT;AAGA,SAAgB,EAAiB,GAAmG;CAClI,IAAM,IAAM,EAAW,CAAiB,CAAC,EAAE,SACrC,IAAU,EAAO,KAAO,CAAG;CAEjC,OADA,EAAQ,UAAU,KAAO,GAClB,GAAa,GAAY,GAAgC,MAAkB;EAChF,IAAM,IAAQ,EAAkB,CAAC;EACjC,AAAI,EAAM,SAAS,aAAW,EAAQ,UAAU,GAAO,MAAS,KAAA,IAAY,EAAE,aAAU,IAAI;GAAE;GAAW;EAAK,CAAC;CACjH,GAAG,CAAC,CAAC;AACP;AAMA,IAAa,IAAe,EAA2C,KAAA,CAAS;AAGhF,SAAgB,IAAsD;CACpE,IAAM,IAAQ,EAAW,CAAY;CACrC,OAAO,GAAiB,MAA0B,IAAQ,EAAM,CAAE,IAAI,EAAG,GAAI,CAAC,CAAK,CAAC;AACtF"}
@@ -87,7 +87,7 @@ export declare function useMyReactions(q?: MineQuery & {
87
87
  client?: ContentKitClient;
88
88
  }): UseList<MyInteraction>;
89
89
  export interface UseContentFilters {
90
- /** null until read (and signed out). */
90
+ /** null until the configured filters have loaded. */
91
91
  filters: ContentFilters | null;
92
92
  loading: boolean;
93
93
  error?: ContentKitError;
@@ -98,7 +98,7 @@ export interface UseContentFilters {
98
98
  setVisible: (groupId: string, visible: boolean) => Promise<ContentFilters>;
99
99
  setIncludeDeleted: (include: boolean) => Promise<ContentFilters>;
100
100
  }
101
- /** The signed-in reader's content filters: each configured group, its default and their setting. */
101
+ /** Configured filters: browser choices for guests, server choices for accounts. */
102
102
  export declare function useContentFilters(o?: {
103
103
  language?: string;
104
104
  client?: ContentKitClient;
@@ -1,43 +1,43 @@
1
- import { toContentKitError as e } from "../client/errors.js";
2
- import { ContentKitContext as t, useGuarded as n } from "./context.js";
3
- import { keyOf as r, useContentScope as i, useList as a, useResource as o } from "./use-resource.js";
4
- import { recentSearchLimit as s } from "../client/browser-search-history.js";
5
- import { Beacons as c, eventId as l } from "../client/beacons.js";
6
- import { useCallback as u, useContext as d, useEffect as f, useLayoutEffect as p, useMemo as m, useRef as h, useState as g, useSyncExternalStore as _ } from "react";
1
+ import { ContentKitError as e, toContentKitError as t } from "../client/errors.js";
2
+ import { ContentKitContext as n, useGuarded as r } from "./context.js";
3
+ import { keyOf as i, useContentScope as a, useList as o, useResource as s } from "./use-resource.js";
4
+ import { recentSearchLimit as c } from "../client/browser-search-history.js";
5
+ import { Beacons as l, eventId as u } from "../client/beacons.js";
6
+ import { useCallback as d, useContext as f, useEffect as p, useLayoutEffect as m, useMemo as h, useRef as g, useState as _, useSyncExternalStore as v } from "react";
7
7
  //#region src/react/discovery.ts
8
- var v = (e) => ({
8
+ var y = (e) => ({
9
9
  items: e.contents,
10
10
  next: e.next_cursor ?? null
11
- }), y = [];
12
- function b(e, t) {
13
- let n = m(() => ({
11
+ }), b = [];
12
+ function x(e, t) {
13
+ let n = h(() => ({
14
14
  client: e,
15
15
  scope: t
16
- }), [e, t]), r = h(n);
17
- return p(() => (r.current = n, () => {
16
+ }), [e, t]), r = g(n);
17
+ return m(() => (r.current = n, () => {
18
18
  r.current = null;
19
- }), [n]), u(() => r.current === n, [n]);
19
+ }), [n]), d(() => r.current === n, [n]);
20
20
  }
21
- function x(e) {
22
- let n = d(t)?.language;
23
- return m(() => e && !e.display_language && n ? {
21
+ function S(e) {
22
+ let t = f(n)?.language;
23
+ return h(() => e && !e.display_language && t ? {
24
24
  ...e,
25
- display_language: n
26
- } : e, [e, n]);
25
+ display_language: t
26
+ } : e, [e, t]);
27
27
  }
28
- function S(e, t = {}) {
29
- let { client: n, store: o, scope: s } = i(t.client), c = x(e);
30
- return a(o, c ? r("cards", s, "list", c) : null, { type: "cards" }, async (e, t) => v(await n.discovery.list({
28
+ function C(e, t = {}) {
29
+ let { client: n, store: r, scope: s } = a(t.client), c = S(e);
30
+ return o(r, c ? i("cards", s, "list", c) : null, { type: "cards" }, async (e, t) => y(await n.discovery.list({
31
31
  ...c,
32
32
  cursor: e
33
33
  }, t)));
34
34
  }
35
- function C(e, t = {}) {
36
- let { client: n, store: a, scope: s } = i(t.client), c = x(m(() => {
35
+ function w(e, t = {}) {
36
+ let { client: n, store: r, scope: o } = a(t.client), c = S(h(() => {
37
37
  if (!e) return null;
38
38
  let { sort: t, cursor: n, limit: r, card_entities: i, mode: a, ...o } = e;
39
39
  return o;
40
- }, [e])), l = o(a, c ? r("release-dates", s, "locked", c) : null, { type: "release-dates" }, async (e) => {
40
+ }, [e])), l = s(r, c ? i("release-dates", o, "locked", c) : null, { type: "release-dates" }, async (e) => {
41
41
  let t = async (t) => (await n.discovery.releaseDates({
42
42
  ...c,
43
43
  mode: t,
@@ -51,37 +51,37 @@ function C(e, t = {}) {
51
51
  loading: l.loading
52
52
  };
53
53
  }
54
- function w(e, t = {}) {
55
- let { client: n, store: o, scope: s, viewer: c } = i(t.client), l = x(e?.q.trim() ? e : null), u = b(n, s);
56
- return a(o, l ? r("cards", s, "search", l) : null, { type: "cards" }, async (e, t) => {
54
+ function T(e, t = {}) {
55
+ let { client: n, store: r, scope: s, viewer: c } = a(t.client), l = S(e?.q.trim() ? e : null), u = x(n, s);
56
+ return o(r, l ? i("cards", s, "search", l) : null, { type: "cards" }, async (e, t) => {
57
57
  let r = await n.discovery.search({
58
58
  ...l,
59
59
  cursor: e
60
60
  }, t);
61
- return !e && c === null && !t.aborted && u() && n.discovery.browserSearches.record(l.q, r.contents.length), v(r);
61
+ return !e && c === null && !t.aborted && u() && n.discovery.browserSearches.record(l.q, r.contents.length), y(r);
62
62
  });
63
63
  }
64
- function T(e, t, n) {
65
- let { store: r } = i(n.client), a = o(r, e, { type: "cards" }, async (e) => (await t(e)).contents), s = a.error?.code === "not_configured";
64
+ function E(e, t, n) {
65
+ let { store: r } = a(n.client), i = s(r, e, { type: "cards" }, async (e) => (await t(e)).contents), o = i.error?.code === "not_configured";
66
66
  return {
67
- items: a.data ?? [],
68
- loading: !!e && (a.loading || !a.loaded),
69
- error: s ? void 0 : a.error,
70
- unavailable: s,
71
- reload: a.reload
67
+ items: i.data ?? [],
68
+ loading: !!e && (i.loading || !i.loaded),
69
+ error: o ? void 0 : i.error,
70
+ unavailable: o,
71
+ reload: i.reload
72
72
  };
73
73
  }
74
- function E(e, t = {}, n = {}) {
75
- let { client: a, scope: o } = i(n.client), s = x(t);
76
- return T(e ? r("cards", o, "similar", e, s) : null, (t) => a.discovery.similar(e, s, t), n);
77
- }
78
- function D(e = {}, t = {}) {
79
- let { client: n, scope: a, viewer: o } = i(t.client), s = x(e);
80
- return T(o === null || !s ? null : r("cards", a, "recommended", s), (e) => n.discovery.recommendations(s, e), t);
74
+ function D(e, t = {}, n = {}) {
75
+ let { client: r, scope: o } = a(n.client), s = S(t);
76
+ return E(e ? i("cards", o, "similar", e, s) : null, (t) => r.discovery.similar(e, s, t), n);
81
77
  }
82
78
  function O(e = {}, t = {}) {
83
- let { client: n, store: o, scope: s } = i(t.client), c = x(e);
84
- return a(o, r("release-dates", s, c), { type: "release-dates" }, async (e, t) => {
79
+ let { client: n, scope: r, viewer: o } = a(t.client), s = S(e);
80
+ return E(o === null || !s ? null : i("cards", r, "recommended", s), (e) => n.discovery.recommendations(s, e), t);
81
+ }
82
+ function k(e = {}, t = {}) {
83
+ let { client: n, store: r, scope: s } = a(t.client), c = S(e);
84
+ return o(r, i("release-dates", s, c), { type: "release-dates" }, async (e, t) => {
85
85
  let r = await n.discovery.releaseDates({
86
86
  ...c,
87
87
  cursor: e
@@ -95,173 +95,211 @@ function O(e = {}, t = {}) {
95
95
  };
96
96
  });
97
97
  }
98
- function k(e = {}, t = {}) {
99
- let { client: o, store: s, scope: c, viewer: l } = i(t.client), d = x(e), f = n(), p = a(s, l === null || !d ? null : r("history", c, d), { type: "history" }, async (e, t) => v(await o.discovery.history({
100
- ...d,
98
+ function A(e = {}, t = {}) {
99
+ let { client: n, store: s, scope: c, viewer: l } = a(t.client), u = S(e), f = r(), p = o(s, l === null || !u ? null : i("history", c, u), { type: "history" }, async (e, t) => y(await n.discovery.history({
100
+ ...u,
101
101
  cursor: e
102
- }, t))), m = u((e = {}) => f(() => o.discovery.forgetHistory(e)), [o, f]);
102
+ }, t))), m = d((e = {}) => f(() => n.discovery.forgetHistory(e)), [n, f]);
103
103
  return {
104
104
  ...p,
105
105
  forget: m
106
106
  };
107
107
  }
108
- function A(e = {}) {
109
- let { client: t, store: a, scope: c, viewer: l } = i(e.client), d = n(), p = b(t, c), h = l === null, g = e.enabled !== !1, v = t.discovery.browserSearches, x = u((e) => h && g ? v.subscribe(e) : () => {}, [
110
- v,
111
- h,
108
+ function j(e = {}) {
109
+ let { client: t, store: n, scope: o, viewer: l } = a(e.client), u = r(), f = x(t, o), m = l === null, g = e.enabled !== !1, _ = t.discovery.browserSearches, y = d((e) => m && g ? _.subscribe(e) : () => {}, [
110
+ _,
111
+ m,
112
112
  g
113
- ]), S = u(() => h && g ? v.snapshot() : y, [
114
- v,
115
- h,
113
+ ]), S = d(() => m && g ? _.snapshot() : b, [
114
+ _,
115
+ m,
116
116
  g
117
- ]), C = _(x, S, () => y), w = m(() => C.slice(0, s(e.limit)), [C, e.limit]), T = !g || h ? null : r("searches", c, e.limit ?? 10), E = o(a, T, { type: "searches" }, async (n) => (await t.discovery.recentSearches({ limit: e.limit }, n)).searches);
118
- f(() => {
117
+ ]), C = v(y, S, () => b), w = h(() => C.slice(0, c(e.limit)), [C, e.limit]), T = !g || m ? null : i("searches", o, e.limit ?? 10), E = s(n, T, { type: "searches" }, async (n) => (await t.discovery.recentSearches({ limit: e.limit }, n)).searches);
118
+ p(() => {
119
119
  if (!T) return;
120
120
  let e = () => {
121
- a.snapshot(T).loading || a.load(T, !0);
121
+ n.snapshot(T).loading || n.load(T, !0);
122
122
  };
123
- a.snapshot(T).loaded && e();
123
+ n.snapshot(T).loaded && e();
124
124
  let t = () => {
125
125
  document.visibilityState === "visible" && e();
126
126
  };
127
127
  return typeof window < "u" && window.addEventListener("focus", e), typeof document < "u" && document.addEventListener("visibilitychange", t), () => {
128
128
  typeof window < "u" && window.removeEventListener("focus", e), typeof document < "u" && document.removeEventListener("visibilitychange", t);
129
129
  };
130
- }, [T, a]);
131
- let D = u(async (e) => {
132
- if (p()) {
133
- if (h) {
134
- v.clear(e);
130
+ }, [T, n]);
131
+ let D = d(async (e) => {
132
+ if (f()) {
133
+ if (m) {
134
+ _.clear(e);
135
135
  return;
136
136
  }
137
- await d(() => p() ? t.discovery.clearSearches(e ? { query: e } : {}) : Promise.resolve());
137
+ await u(() => f() ? t.discovery.clearSearches(e ? { query: e } : {}) : Promise.resolve());
138
138
  }
139
139
  }, [
140
- v,
140
+ _,
141
141
  t,
142
- h,
143
- d,
144
- p
142
+ m,
143
+ u,
144
+ f
145
145
  ]);
146
- return h ? {
147
- searches: g ? w : y,
146
+ return m ? {
147
+ searches: g ? w : b,
148
148
  loading: !1,
149
149
  clear: D
150
150
  } : {
151
- searches: E.data ?? y,
151
+ searches: E.data ?? b,
152
152
  loading: !!T && (E.loading || !E.loaded),
153
153
  error: E.error,
154
154
  clear: D
155
155
  };
156
156
  }
157
- var j = (e) => ({
157
+ var M = (e) => ({
158
158
  items: e.items.map((e) => ({
159
159
  ...e,
160
160
  id: e.content?.id ?? e.entity?.id ?? ""
161
161
  })),
162
162
  next: e.next_cursor ?? null
163
163
  });
164
- function M(e = {}, t = {}) {
165
- let { client: n, store: o, scope: s, viewer: c } = i(t.client), l = x(e);
166
- return a(o, c === null ? null : r("favorites", s, l), { type: "favorites" }, async (e, t) => j(await n.favorites.mine({
164
+ function N(e = {}, t = {}) {
165
+ let { client: n, store: r, scope: s, viewer: c } = a(t.client), l = S(e);
166
+ return o(r, c === null ? null : i("favorites", s, l), { type: "favorites" }, async (e, t) => M(await n.favorites.mine({
167
167
  ...l,
168
168
  cursor: e
169
169
  }, t)));
170
170
  }
171
- function N(e = {}, t = {}) {
172
- let { client: n, store: o, scope: s, viewer: c } = i(t.client), l = x(e);
173
- return a(o, c === null ? null : r("reactions", s, l), { type: "reactions" }, async (e, t) => j(await n.reactions.mine({
171
+ function P(e = {}, t = {}) {
172
+ let { client: n, store: r, scope: s, viewer: c } = a(t.client), l = S(e);
173
+ return o(r, c === null ? null : i("reactions", s, l), { type: "reactions" }, async (e, t) => M(await n.reactions.mine({
174
174
  ...l,
175
175
  cursor: e
176
176
  }, t)));
177
177
  }
178
- function P(e = {}) {
179
- let { client: t, store: a, scope: s, viewer: c, language: l } = i(e.client), d = e.language ?? l, f = c === null ? null : r("content-filters", s, d), p = o(a, f, { type: "content-filters" }, (e) => t.discovery.contentFilters(d, e)), m = n(), [_, v] = g(0), y = h(p.data);
180
- y.current = p.data;
181
- let b = u(async (e) => {
182
- v((e) => e + 1);
178
+ function F(t = {}) {
179
+ let { client: n, store: o, scope: c, viewer: l, language: u } = a(t.client), f = t.language ?? u, m = l === null, y = n.preferences.browser, b = v(y.subscribe, y.snapshot, y.snapshot), S = i("content-filters", c, f), C = g(null), w = m && C.current?.guest && C.current.client === n && C.current.language === f ? C.current.data : void 0, T = s(o, S, { type: "content-filters" }, (e) => n.discovery.contentFilters(f, e), { initial: w });
180
+ C.current = {
181
+ client: n,
182
+ language: f,
183
+ guest: m,
184
+ data: T.data
185
+ };
186
+ let E = d((e, t = b.filters) => {
187
+ let n = new Map(t.map((e) => [e.group_id, e.visible]));
188
+ return {
189
+ include_deleted: !1,
190
+ filters: e.filters.map((e) => ({
191
+ ...e,
192
+ visible: n.get(e.entity.id) ?? e.default_visible,
193
+ overridden: n.has(e.entity.id)
194
+ }))
195
+ };
196
+ }, [b.filters]), D = h(() => T.data && m ? E(T.data) : T.data, [
197
+ T.data,
198
+ m,
199
+ E
200
+ ]), O = r(), k = x(n, c), [A, j] = _(0), M = g(D);
201
+ M.current = D, p(() => {
202
+ j(0);
203
+ }, [n, c]);
204
+ let N = d(async (t) => {
205
+ if (!k()) throw new e("aborted", "The account changed.");
206
+ if (m) {
207
+ let n = M.current;
208
+ if (!n) throw new e("invalid_request", "Content filters have not loaded.");
209
+ let r = new Set(n.filters.map((e) => e.entity.id));
210
+ if (t.filters.some((e) => !r.has(e.group_id))) throw new e("invalid_request", "This content filter is not configured.");
211
+ return y.setFilters(t.filters), E(n, t.filters);
212
+ }
213
+ j((e) => e + 1);
183
214
  try {
184
- let n = await m(() => t.discovery.setContentFilters(e, d));
185
- return f && a.set(f, n), n;
215
+ let r = await O(() => {
216
+ if (!k()) throw new e("aborted", "The account changed.");
217
+ return n.discovery.setContentFilters(t, f);
218
+ });
219
+ return k() && o.set(S, r), r;
186
220
  } finally {
187
- v((e) => e - 1);
221
+ j((e) => Math.max(0, e - 1));
188
222
  }
189
223
  }, [
190
- t,
191
- m,
192
- d,
224
+ n,
225
+ O,
193
226
  f,
194
- a
195
- ]), x = (e) => e.filters.filter((e) => e.overridden).map((e) => ({
227
+ S,
228
+ o,
229
+ k,
230
+ m,
231
+ y,
232
+ E
233
+ ]), P = (e) => e.filters.filter((e) => e.overridden).map((e) => ({
196
234
  group_id: e.entity.id,
197
235
  visible: e.visible
198
- })), S = u((e, t) => {
199
- let n = y.current;
200
- return n ? b({
201
- filters: [...x(n).filter((t) => t.group_id !== e), {
236
+ })), F = d((e, t) => {
237
+ let n = M.current;
238
+ return n ? N({
239
+ filters: [...P(n).filter((t) => t.group_id !== e), {
202
240
  group_id: e,
203
241
  visible: t
204
242
  }],
205
243
  include_deleted: n.include_deleted
206
244
  }) : Promise.reject(/* @__PURE__ */ Error("contentkit-ui: the content filters have not loaded"));
207
- }, [b]), C = u((e) => {
208
- let t = y.current;
209
- return t ? b({
210
- filters: x(t),
245
+ }, [N]), I = d((e) => {
246
+ let t = M.current;
247
+ return t ? N({
248
+ filters: P(t),
211
249
  include_deleted: e
212
250
  }) : Promise.reject(/* @__PURE__ */ Error("contentkit-ui: the content filters have not loaded"));
213
- }, [b]);
251
+ }, [N]);
214
252
  return {
215
- filters: p.data ?? null,
216
- loading: !!f && (p.loading || !p.loaded),
217
- error: p.error,
218
- saving: _ > 0,
219
- save: b,
220
- setVisible: S,
221
- setIncludeDeleted: C
253
+ filters: D ?? null,
254
+ loading: T.loading || !T.loaded,
255
+ error: T.error,
256
+ saving: A > 0,
257
+ save: N,
258
+ setVisible: F,
259
+ setIncludeDeleted: I
222
260
  };
223
261
  }
224
- var F = {
262
+ var I = {
225
263
  contents: [],
226
264
  entities: []
227
265
  };
228
- function I(t, n = {}) {
229
- let { client: r, language: a } = i(n.client), { debounce: o = 150, minLength: s = 1, client: c, ...l } = n, u = t.trim(), d = m(() => ({
230
- display_language: a,
266
+ function L(e, n = {}) {
267
+ let { client: r, language: i } = a(n.client), { debounce: o = 150, minLength: s = 1, client: c, ...l } = n, u = e.trim(), d = h(() => ({
268
+ display_language: i,
231
269
  ...l,
232
270
  q: u
233
271
  }), [
234
- a,
272
+ i,
235
273
  u,
236
274
  JSON.stringify(l)
237
- ]), [p, h] = g({
238
- ...F,
275
+ ]), [f, m] = _({
276
+ ...I,
239
277
  query: "",
240
278
  loading: !1
241
279
  });
242
- return f(() => {
280
+ return p(() => {
243
281
  if (u.length < s) {
244
- h({
245
- ...F,
282
+ m({
283
+ ...I,
246
284
  query: "",
247
285
  loading: !1
248
286
  });
249
287
  return;
250
288
  }
251
- h((e) => ({
289
+ m((e) => ({
252
290
  ...e,
253
291
  loading: !0
254
292
  }));
255
- let t = new AbortController(), n = setTimeout(() => {
256
- r.discovery.typeahead(d, t.signal).then((e) => h({
293
+ let e = new AbortController(), n = setTimeout(() => {
294
+ r.discovery.typeahead(d, e.signal).then((e) => m({
257
295
  contents: e.contents,
258
296
  entities: e.entities,
259
297
  query: u,
260
298
  loading: !1
261
- }), (t) => {
262
- let n = e(t);
263
- n.code !== "aborted" && h({
264
- ...F,
299
+ }), (e) => {
300
+ let n = t(e);
301
+ n.code !== "aborted" && m({
302
+ ...I,
265
303
  query: u,
266
304
  loading: !1,
267
305
  error: n
@@ -269,7 +307,7 @@ function I(t, n = {}) {
269
307
  });
270
308
  }, o);
271
309
  return () => {
272
- clearTimeout(n), t.abort();
310
+ clearTimeout(n), e.abort();
273
311
  };
274
312
  }, [
275
313
  r,
@@ -277,27 +315,27 @@ function I(t, n = {}) {
277
315
  u,
278
316
  o,
279
317
  s
280
- ]), p;
318
+ ]), f;
281
319
  }
282
- var L = /* @__PURE__ */ new WeakMap();
283
- function R(e, t) {
284
- let n = L.get(e);
285
- return n || L.set(e, n = new c(e, t)), n;
320
+ var R = /* @__PURE__ */ new WeakMap();
321
+ function z(e, t) {
322
+ let n = R.get(e);
323
+ return n || R.set(e, n = new l(e, t)), n;
286
324
  }
287
- function z(e = {}) {
288
- let { client: t } = i(e.client);
289
- return R(t);
325
+ function B(e = {}) {
326
+ let { client: t } = a(e.client);
327
+ return z(t);
290
328
  }
291
- function B(e, t, n = {}) {
292
- let r = z(n), { client: i, ...a } = n, o = m(() => e ? r.view(e, t, a) : null, [
329
+ function V(e, t, n = {}) {
330
+ let r = B(n), { client: i, ...a } = n, o = h(() => e ? r.view(e, t, a) : null, [
293
331
  r,
294
332
  e,
295
333
  t
296
334
  ]);
297
- return u((e) => o?.update(e), [o]);
335
+ return d((e) => o?.update(e), [o]);
298
336
  }
299
- function V(e, t) {
300
- let n = z(t), r = m(() => l(), [t.render]), i = m(() => ({
337
+ function H(e, t) {
338
+ let n = B(t), r = h(() => u(), [t.render]), i = h(() => ({
301
339
  render_id: r,
302
340
  surface: t.surface,
303
341
  ranker: t.ranker,
@@ -309,10 +347,10 @@ function V(e, t) {
309
347
  t.ranker,
310
348
  t.query_id,
311
349
  t.language
312
- ]), a = h(/* @__PURE__ */ new Set()), o = h(/* @__PURE__ */ new Set());
313
- f(() => {
350
+ ]), a = g(/* @__PURE__ */ new Set()), o = g(/* @__PURE__ */ new Set());
351
+ p(() => {
314
352
  a.current = /* @__PURE__ */ new Set(), o.current = /* @__PURE__ */ new Set();
315
- }, [r]), f(() => {
353
+ }, [r]), p(() => {
316
354
  let t = e.flatMap((e, t) => a.current.has(e.id) ? [] : [{
317
355
  content_id: e.id,
318
356
  position: t + 1
@@ -329,7 +367,7 @@ function V(e, t) {
329
367
  i,
330
368
  e
331
369
  ]);
332
- let s = h([]), c = h(void 0), d = m(() => typeof IntersectionObserver == "function" ? new IntersectionObserver((e) => {
370
+ let s = g([]), c = g(void 0), l = h(() => typeof IntersectionObserver == "function" ? new IntersectionObserver((e) => {
333
371
  for (let t of e) {
334
372
  if (!t.isIntersecting) continue;
335
373
  let e = t.target, n = e.dataset.exposureContent;
@@ -349,12 +387,12 @@ function V(e, t) {
349
387
  });
350
388
  }, 300);
351
389
  }, { threshold: .5 }) : null, [n, i]);
352
- return f(() => () => d?.disconnect(), [d]), {
390
+ return p(() => () => l?.disconnect(), [l]), {
353
391
  render_id: r,
354
- track: u((e, t) => (n) => {
355
- n && d && (n.dataset.exposureContent = e, n.dataset.exposurePosition = String(t), d.observe(n));
356
- }, [d]),
357
- click: u((e, i) => n.click(e, {
392
+ track: d((e, t) => (n) => {
393
+ n && l && (n.dataset.exposureContent = e, n.dataset.exposurePosition = String(t), l.observe(n));
394
+ }, [l]),
395
+ click: d((e, i) => n.click(e, {
358
396
  render_id: r,
359
397
  surface: t.surface,
360
398
  position: i
@@ -366,6 +404,6 @@ function V(e, t) {
366
404
  };
367
405
  }
368
406
  //#endregion
369
- export { R as beaconsFor, z as useBeacons, P as useContentFilters, S as useContents, V as useExposure, k as useHistory, C as useLockedCount, M as useMyFavorites, N as useMyReactions, A as useRecentSearches, D as useRecommendations, O as useReleaseDates, w as useSearch, E as useSimilar, I as useTypeahead, B as useViewSignal };
407
+ export { z as beaconsFor, B as useBeacons, F as useContentFilters, C as useContents, H as useExposure, A as useHistory, w as useLockedCount, N as useMyFavorites, P as useMyReactions, j as useRecentSearches, O as useRecommendations, k as useReleaseDates, T as useSearch, D as useSimilar, L as useTypeahead, V as useViewSignal };
370
408
 
371
409
  //# sourceMappingURL=discovery.js.map