@readyfor/api-client-base 1.56.0-pr1409.657b73e → 1.56.0-pr1409.ed0166a

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.
@@ -7,9 +7,27 @@ type Configuration = Config & {
7
7
  swr?: SWRConfiguration;
8
8
  };
9
9
  type Props = {
10
+ /**
11
+ * API クライアントの設定。
12
+ *
13
+ * **安定参照 / 値安定で渡すこと**(`useMemo` を使うか、モジュールスコープの定数にする)。
14
+ * インライン新オブジェクト(`config={{ ... }}`)を渡すと毎 render で浅い比較が走り、
15
+ * 値が変わらなくても参照が変わった場合は購読者全体が再 render される。
16
+ * 関数プロパティ(`onError` など)は参照比較のため、同様に安定参照を推奨する。
17
+ */
10
18
  config: Configuration;
11
19
  children: ReactNode;
12
20
  };
21
+ /**
22
+ * API クライアントの設定を子ツリーへ提供するプロバイダ。
23
+ *
24
+ * **注意事項**
25
+ * - `store` は `globalThis` 上の単一シングルトン。複数インスタンスを同時にマウントすると
26
+ * 後勝ちで上書きされ、意図しない挙動になる。アプリルートに 1 つだけ置くこと。
27
+ * - **CSR 専用**。SSR(Node / Edge での server render)環境では `store` がリクエスト間で
28
+ * 共有されるため、config が汚染される。SSR が必要な場合は別途対応を検討すること。
29
+ * - `config` は安定参照 / 値安定で渡すこと(`Props.config` の JSDoc を参照)。
30
+ */
13
31
  declare const ApiClientConfigProvider: FC<Props>;
14
32
  declare const useApiClientConfigContext: () => Store<Config>;
15
33
  //#endregion
@@ -6,13 +6,42 @@ let swr = require("swr");
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
7
  //#region src/react/ApiClientConfigProvider.tsx
8
8
  const ApiClientConfigContext = (0, react.createContext)(require_apiClientConfigStore.store);
9
+ /**
10
+ * `config` オブジェクトのキー集合と各値を浅く比較する。
11
+ * 関数プロパティは参照比較になる。
12
+ *
13
+ * キー集合の厳密一致を担保するため、長さチェックに加えて
14
+ * b 側に各キーが存在することも確認する。
15
+ */
16
+ const shallowEqual = (a, b) => {
17
+ const aKeys = Object.keys(a);
18
+ const bKeys = Object.keys(b);
19
+ if (aKeys.length !== bKeys.length) return false;
20
+ return aKeys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && a[k] === b[k]);
21
+ };
22
+ /**
23
+ * API クライアントの設定を子ツリーへ提供するプロバイダ。
24
+ *
25
+ * **注意事項**
26
+ * - `store` は `globalThis` 上の単一シングルトン。複数インスタンスを同時にマウントすると
27
+ * 後勝ちで上書きされ、意図しない挙動になる。アプリルートに 1 つだけ置くこと。
28
+ * - **CSR 専用**。SSR(Node / Edge での server render)環境では `store` がリクエスト間で
29
+ * 共有されるため、config が汚染される。SSR が必要な場合は別途対応を検討すること。
30
+ * - `config` は安定参照 / 値安定で渡すこと(`Props.config` の JSDoc を参照)。
31
+ */
9
32
  const ApiClientConfigProvider = (props) => {
10
33
  const { swr: swr$1, ...config } = props.config;
11
34
  const prevConfigRef = (0, react.useRef)(null);
12
- if (prevConfigRef.current !== config) {
35
+ if (prevConfigRef.current === null && typeof window !== "undefined") {
13
36
  require_apiClientConfigStore.store.setState(() => config);
14
37
  prevConfigRef.current = config;
15
38
  }
39
+ (0, react.useEffect)(() => {
40
+ if (prevConfigRef.current === null || !shallowEqual(prevConfigRef.current, config)) {
41
+ require_apiClientConfigStore.store.setState(() => config);
42
+ prevConfigRef.current = config;
43
+ }
44
+ });
16
45
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiClientConfigContext.Provider, {
17
46
  value: require_apiClientConfigStore.store,
18
47
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(swr.SWRConfig, {
@@ -1,5 +1,5 @@
1
1
  import { i as mergeRequestInit, r as store } from "../apiClientConfigStore-DDleIkQN.mjs";
2
- import { createContext, useContext, useMemo, useRef } from "react";
2
+ import { createContext, useContext, useEffect, useMemo, useRef } from "react";
3
3
  import { SWRConfig } from "swr";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
@@ -30,13 +30,42 @@ const createSwrConfig = (config) => ({
30
30
  //#endregion
31
31
  //#region src/react/ApiClientConfigProvider.tsx
32
32
  const ApiClientConfigContext = createContext(store);
33
+ /**
34
+ * `config` オブジェクトのキー集合と各値を浅く比較する。
35
+ * 関数プロパティは参照比較になる。
36
+ *
37
+ * キー集合の厳密一致を担保するため、長さチェックに加えて
38
+ * b 側に各キーが存在することも確認する。
39
+ */
40
+ const shallowEqual = (a, b) => {
41
+ const aKeys = Object.keys(a);
42
+ const bKeys = Object.keys(b);
43
+ if (aKeys.length !== bKeys.length) return false;
44
+ return aKeys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && a[k] === b[k]);
45
+ };
46
+ /**
47
+ * API クライアントの設定を子ツリーへ提供するプロバイダ。
48
+ *
49
+ * **注意事項**
50
+ * - `store` は `globalThis` 上の単一シングルトン。複数インスタンスを同時にマウントすると
51
+ * 後勝ちで上書きされ、意図しない挙動になる。アプリルートに 1 つだけ置くこと。
52
+ * - **CSR 専用**。SSR(Node / Edge での server render)環境では `store` がリクエスト間で
53
+ * 共有されるため、config が汚染される。SSR が必要な場合は別途対応を検討すること。
54
+ * - `config` は安定参照 / 値安定で渡すこと(`Props.config` の JSDoc を参照)。
55
+ */
33
56
  const ApiClientConfigProvider = (props) => {
34
57
  const { swr, ...config } = props.config;
35
58
  const prevConfigRef = useRef(null);
36
- if (prevConfigRef.current !== config) {
59
+ if (prevConfigRef.current === null && typeof window !== "undefined") {
37
60
  store.setState(() => config);
38
61
  prevConfigRef.current = config;
39
62
  }
63
+ useEffect(() => {
64
+ if (prevConfigRef.current === null || !shallowEqual(prevConfigRef.current, config)) {
65
+ store.setState(() => config);
66
+ prevConfigRef.current = config;
67
+ }
68
+ });
40
69
  return /* @__PURE__ */ jsx(ApiClientConfigContext.Provider, {
41
70
  value: store,
42
71
  children: /* @__PURE__ */ jsx(SWRConfig, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@readyfor/api-client-base",
3
- "version": "1.56.0-pr1409.657b73e",
3
+ "version": "1.56.0-pr1409.ed0166a",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",