@simplysm/solid 13.0.31 → 13.0.33

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 (72) hide show
  1. package/README.md +39 -14
  2. package/dist/hooks/useLogger.js +4 -4
  3. package/dist/hooks/useLogger.js.map +1 -1
  4. package/dist/hooks/useSyncConfig.d.ts +1 -1
  5. package/dist/hooks/useSyncConfig.d.ts.map +1 -1
  6. package/dist/hooks/useSyncConfig.js +6 -4
  7. package/dist/hooks/useSyncConfig.js.map +1 -1
  8. package/dist/index.d.ts +6 -3
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +7 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/{hooks/useClipboardValueCopy.d.ts → providers/ClipboardProvider.d.ts} +4 -3
  13. package/dist/providers/ClipboardProvider.d.ts.map +1 -0
  14. package/dist/{hooks/useClipboardValueCopy.js → providers/ClipboardProvider.js} +11 -8
  15. package/dist/providers/ClipboardProvider.js.map +6 -0
  16. package/dist/providers/ConfigContext.d.ts +15 -47
  17. package/dist/providers/ConfigContext.d.ts.map +1 -1
  18. package/dist/providers/ConfigContext.js +18 -1
  19. package/dist/providers/ConfigContext.js.map +3 -3
  20. package/dist/providers/ErrorLoggerProvider.d.ts +10 -0
  21. package/dist/providers/ErrorLoggerProvider.d.ts.map +1 -0
  22. package/dist/providers/ErrorLoggerProvider.js +23 -0
  23. package/dist/providers/ErrorLoggerProvider.js.map +6 -0
  24. package/dist/providers/LoggerContext.d.ts +38 -0
  25. package/dist/providers/LoggerContext.d.ts.map +1 -0
  26. package/dist/providers/LoggerContext.js +25 -0
  27. package/dist/providers/LoggerContext.js.map +6 -0
  28. package/dist/providers/PwaUpdateProvider.d.ts +12 -0
  29. package/dist/providers/PwaUpdateProvider.d.ts.map +1 -0
  30. package/dist/providers/PwaUpdateProvider.js +56 -0
  31. package/dist/providers/PwaUpdateProvider.js.map +6 -0
  32. package/dist/providers/ServiceClientContext.d.ts.map +1 -1
  33. package/dist/providers/ServiceClientContext.js +1 -3
  34. package/dist/providers/ServiceClientContext.js.map +1 -1
  35. package/dist/providers/SyncStorageContext.d.ts +42 -0
  36. package/dist/providers/SyncStorageContext.d.ts.map +1 -0
  37. package/dist/providers/SyncStorageContext.js +25 -0
  38. package/dist/providers/SyncStorageContext.js.map +6 -0
  39. package/dist/providers/ThemeContext.d.ts.map +1 -1
  40. package/dist/providers/ThemeContext.js +1 -1
  41. package/dist/providers/ThemeContext.js.map +1 -1
  42. package/docs/disclosure.md +1 -1
  43. package/docs/feedback.md +4 -4
  44. package/docs/form-controls.md +1 -1
  45. package/docs/hooks.md +8 -42
  46. package/docs/providers.md +116 -3
  47. package/docs/styling.md +1 -1
  48. package/package.json +16 -16
  49. package/src/hooks/useLogger.ts +4 -4
  50. package/src/hooks/useSyncConfig.ts +7 -5
  51. package/src/index.ts +6 -3
  52. package/src/{hooks/useClipboardValueCopy.ts → providers/ClipboardProvider.tsx} +6 -4
  53. package/src/providers/ConfigContext.tsx +48 -0
  54. package/src/providers/ErrorLoggerProvider.tsx +31 -0
  55. package/src/providers/LoggerContext.tsx +46 -0
  56. package/src/providers/PwaUpdateProvider.tsx +68 -0
  57. package/src/providers/ServiceClientContext.ts +1 -3
  58. package/src/providers/SyncStorageContext.tsx +52 -0
  59. package/src/providers/ThemeContext.tsx +1 -3
  60. package/dist/hooks/useClipboardValueCopy.d.ts.map +0 -1
  61. package/dist/hooks/useClipboardValueCopy.js.map +0 -6
  62. package/dist/hooks/usePwaUpdate.d.ts +0 -14
  63. package/dist/hooks/usePwaUpdate.d.ts.map +0 -1
  64. package/dist/hooks/usePwaUpdate.js +0 -50
  65. package/dist/hooks/usePwaUpdate.js.map +0 -6
  66. package/dist/providers/InitializeProvider.d.ts +0 -25
  67. package/dist/providers/InitializeProvider.d.ts.map +0 -1
  68. package/dist/providers/InitializeProvider.js +0 -60
  69. package/dist/providers/InitializeProvider.js.map +0 -6
  70. package/src/hooks/usePwaUpdate.ts +0 -73
  71. package/src/providers/ConfigContext.ts +0 -80
  72. package/src/providers/InitializeProvider.tsx +0 -79
@@ -0,0 +1,56 @@
1
+ import { memo as _$memo } from "solid-js/web";
2
+ import { onCleanup } from "solid-js";
3
+ import { useNotification } from "../components/feedback/notification/NotificationContext.js";
4
+ const UPDATE_INTERVAL = 5 * 60 * 1e3;
5
+ const PwaUpdateProvider = (props) => {
6
+ if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
7
+ let promptUpdate2 = function(waitingSW) {
8
+ notification.info("\uC571\uC774 \uC5C5\uB370\uC774\uD2B8\uB418\uC5C8\uC2B5\uB2C8\uB2E4", "\uC0C8\uB85C\uACE0\uCE68\uD558\uBA74 \uCD5C\uC2E0 \uBC84\uC804\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4", {
9
+ action: {
10
+ label: "\uC0C8\uB85C\uACE0\uCE68",
11
+ onClick: () => {
12
+ waitingSW.postMessage({
13
+ type: "SKIP_WAITING"
14
+ });
15
+ }
16
+ }
17
+ });
18
+ };
19
+ var promptUpdate = promptUpdate2;
20
+ const notification = useNotification();
21
+ let intervalId;
22
+ void navigator.serviceWorker.getRegistration().then((registration) => {
23
+ if (registration == null) return;
24
+ intervalId = setInterval(() => {
25
+ void registration.update();
26
+ }, UPDATE_INTERVAL);
27
+ if (registration.waiting != null) {
28
+ promptUpdate2(registration.waiting);
29
+ }
30
+ registration.addEventListener("updatefound", () => {
31
+ const newSW = registration.installing;
32
+ if (newSW == null) return;
33
+ newSW.addEventListener("statechange", () => {
34
+ if (newSW.state === "installed" && navigator.serviceWorker.controller != null) {
35
+ promptUpdate2(newSW);
36
+ }
37
+ });
38
+ });
39
+ });
40
+ const onControllerChange = () => {
41
+ window.location.reload();
42
+ };
43
+ navigator.serviceWorker.addEventListener("controllerchange", onControllerChange);
44
+ onCleanup(() => {
45
+ if (intervalId != null) {
46
+ clearInterval(intervalId);
47
+ }
48
+ navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
49
+ });
50
+ }
51
+ return _$memo(() => props.children);
52
+ };
53
+ export {
54
+ PwaUpdateProvider
55
+ };
56
+ //# sourceMappingURL=PwaUpdateProvider.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/providers/PwaUpdateProvider.tsx"],
4
+ "mappings": ";AAAA,SAASA,iBAAuC;AAChD,SAASC,uBAAuB;AAEhC,MAAMC,kBAAkB,IAAI,KAAK;AAW1B,MAAMC,oBAAsCC,WAAU;AAC3D,MAAI,OAAOC,cAAc,eAAe,mBAAmBA,WAAW;AAuCpE,QAASC,gBAAT,SAAsBC,WAAgC;AACpDC,mBAAaC,KAAK,uEAAgB,2HAA4B;QAC5DC,QAAQ;UACNC,OAAO;UACPC,SAASA,MAAM;AACbL,sBAAUM,YAAY;cAAEC,MAAM;YAAe,CAAC;UAChD;QACF;MACF,CAAC;IACH;AATSR,uBAAAA;AAtCT,UAAME,eAAeP,gBAAgB;AACrC,QAAIc;AAEJ,SAAKV,UAAUW,cAAcC,gBAAgB,EAAEC,KAAMC,kBAAiB;AACpE,UAAIA,gBAAgB,KAAM;AAE1BJ,mBAAaK,YAAY,MAAM;AAC7B,aAAKD,aAAaE,OAAO;MAC3B,GAAGnB,eAAe;AAElB,UAAIiB,aAAaG,WAAW,MAAM;AAChChB,QAAAA,cAAaa,aAAaG,OAAO;MACnC;AAEAH,mBAAaI,iBAAiB,eAAe,MAAM;AACjD,cAAMC,QAAQL,aAAaM;AAC3B,YAAID,SAAS,KAAM;AAEnBA,cAAMD,iBAAiB,eAAe,MAAM;AAC1C,cAAIC,MAAME,UAAU,eAAerB,UAAUW,cAAcW,cAAc,MAAM;AAC7ErB,YAAAA,cAAakB,KAAK;UACpB;QACF,CAAC;MACH,CAAC;IACH,CAAC;AAED,UAAMI,qBAAqBA,MAAM;AAC/BC,aAAOC,SAASC,OAAO;IACzB;AACA1B,cAAUW,cAAcO,iBAAiB,oBAAoBK,kBAAkB;AAE/E5B,cAAU,MAAM;AACd,UAAIe,cAAc,MAAM;AACtBiB,sBAAcjB,UAAU;MAC1B;AACAV,gBAAUW,cAAciB,oBAAoB,oBAAoBL,kBAAkB;IACpF,CAAC;EAYH;AAEA,SAAAM,OAAA,MAAU9B,MAAM+B,QAAQ;AAC1B;",
5
+ "names": ["onCleanup", "useNotification", "UPDATE_INTERVAL", "PwaUpdateProvider", "props", "navigator", "promptUpdate", "waitingSW", "notification", "info", "action", "label", "onClick", "postMessage", "type", "intervalId", "serviceWorker", "getRegistration", "then", "registration", "setInterval", "update", "waiting", "addEventListener", "newSW", "installing", "state", "controller", "onControllerChange", "window", "location", "reload", "clearInterval", "removeEventListener", "_$memo", "children"]
6
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceClientContext.d.ts","sourceRoot":"","sources":["../../src/providers/ServiceClientContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEvF,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpF,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;IACpC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,eAAO,MAAM,oBAAoB,mEAA6C,CAAC;AAE/E,wBAAgB,gBAAgB,IAAI,yBAAyB,CAQ5D"}
1
+ {"version":3,"file":"ServiceClientContext.d.ts","sourceRoot":"","sources":["../../src/providers/ServiceClientContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEvF,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpF,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;IACpC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,eAAO,MAAM,oBAAoB,mEAA6C,CAAC;AAE/E,wBAAgB,gBAAgB,IAAI,yBAAyB,CAM5D"}
@@ -3,9 +3,7 @@ const ServiceClientContext = createContext();
3
3
  function useServiceClient() {
4
4
  const context = useContext(ServiceClientContext);
5
5
  if (!context) {
6
- throw new Error(
7
- "useServiceClient\uB294 ServiceClientProvider \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. ServiceClientProvider\uB294 InitializeProvider\uC640 NotificationProvider \uC544\uB798\uC5D0 \uC704\uCE58\uD574\uC57C \uD569\uB2C8\uB2E4"
8
- );
6
+ throw new Error("useServiceClient\uB294 ServiceClientProvider \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
9
7
  }
10
8
  return context;
11
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/providers/ServiceClientContext.ts"],
4
- "mappings": "AAAA,SAAS,eAAe,kBAAkB;AAUnC,MAAM,uBAAuB,cAAyC;AAEtE,SAAS,mBAA8C;AAC5D,QAAM,UAAU,WAAW,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;",
4
+ "mappings": "AAAA,SAAS,eAAe,kBAAkB;AAUnC,MAAM,uBAAuB,cAAyC;AAEtE,SAAS,mBAA8C;AAC5D,QAAM,UAAU,WAAW,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gIAA0D;AAAA,EAC5E;AACA,SAAO;AACT;",
5
5
  "names": []
6
6
  }
@@ -0,0 +1,42 @@
1
+ import { type ParentComponent } from "solid-js";
2
+ /**
3
+ * 커스텀 동기화 저장소 어댑터 인터페이스
4
+ *
5
+ * @remarks
6
+ * - 동기 저장소: `localStorage`, `sessionStorage` 등 그대로 전달 가능
7
+ * - 비동기 저장소: `getItem`이 `Promise`를 반환하는 구현체 전달
8
+ */
9
+ export interface StorageAdapter {
10
+ getItem(key: string): string | null | Promise<string | null>;
11
+ setItem(key: string, value: string): void | Promise<unknown>;
12
+ removeItem(key: string): void | Promise<void>;
13
+ }
14
+ /**
15
+ * 동기화 저장소 Context
16
+ *
17
+ * @remarks
18
+ * Provider가 없으면 `undefined` (useSyncConfig에서 localStorage로 fallback)
19
+ */
20
+ export declare const SyncStorageContext: import("solid-js").Context<StorageAdapter | undefined>;
21
+ /**
22
+ * 동기화 저장소 Context에 접근하는 훅
23
+ *
24
+ * @returns StorageAdapter 또는 undefined (Provider가 없으면)
25
+ */
26
+ export declare function useSyncStorage(): StorageAdapter | undefined;
27
+ /**
28
+ * 동기화 저장소 Provider
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * <SyncStorageProvider storage={myStorageAdapter}>
33
+ * <ThemeProvider>
34
+ * <App />
35
+ * </ThemeProvider>
36
+ * </SyncStorageProvider>
37
+ * ```
38
+ */
39
+ export declare const SyncStorageProvider: ParentComponent<{
40
+ storage: StorageAdapter;
41
+ }>;
42
+ //# sourceMappingURL=SyncStorageContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncStorageContext.d.ts","sourceRoot":"","sources":["../../src/providers/SyncStorageContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,wDAAuD,CAAC;AAEvF;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,cAAc,GAAG,SAAS,CAE3D;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAAC;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,CAO5E,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { createComponent as _$createComponent } from "solid-js/web";
2
+ import { createContext, useContext } from "solid-js";
3
+ const SyncStorageContext = createContext(void 0);
4
+ function useSyncStorage() {
5
+ return useContext(SyncStorageContext);
6
+ }
7
+ const SyncStorageProvider = (props) => {
8
+ return (
9
+ // eslint-disable-next-line solid/reactivity -- storage는 초기 설정값으로 변경되지 않음
10
+ _$createComponent(SyncStorageContext.Provider, {
11
+ get value() {
12
+ return props.storage;
13
+ },
14
+ get children() {
15
+ return props.children;
16
+ }
17
+ })
18
+ );
19
+ };
20
+ export {
21
+ SyncStorageContext,
22
+ SyncStorageProvider,
23
+ useSyncStorage
24
+ };
25
+ //# sourceMappingURL=SyncStorageContext.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/providers/SyncStorageContext.tsx"],
4
+ "mappings": ";AAAA,SAASA,eAAeC,kBAAwC;AAqBzD,MAAMC,qBAAqBF,cAA0CG,MAAS;AAO9E,SAASC,iBAA6C;AAC3D,SAAOH,WAAWC,kBAAkB;AACtC;AAcO,MAAMG,sBAAqEC,WAAU;AAC1F;;IACEC,kBACCL,mBAAmBM,UAAQ;MAAA,IAACC,QAAK;AAAA,eAAEH,MAAMI;MAAO;MAAA,IAAAC,WAAA;AAAA,eAC9CL,MAAMK;MAAQ;IAAA,CAAA;;AAGrB;",
5
+ "names": ["createContext", "useContext", "SyncStorageContext", "undefined", "useSyncStorage", "SyncStorageProvider", "props", "_$createComponent", "Provider", "value", "storage", "children"]
6
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeContext.d.ts","sourceRoot":"","sources":["../../src/providers/ThemeContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAIrB,MAAM,UAAU,CAAC;AAIlB;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7C,UAAU,iBAAiB;IACzB,yBAAyB;IACzB,IAAI,EAAE,MAAM,SAAS,CAAC;IACtB,eAAe;IACf,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACnC,sCAAsC;IACtC,aAAa,EAAE,MAAM,aAAa,CAAC;IACnC,gDAAgD;IAChD,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAQ5C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,EAAE,eA2C3B,CAAC"}
1
+ {"version":3,"file":"ThemeContext.d.ts","sourceRoot":"","sources":["../../src/providers/ThemeContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAIrB,MAAM,UAAU,CAAC;AAIlB;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7C,UAAU,iBAAiB;IACzB,yBAAyB;IACzB,IAAI,EAAE,MAAM,SAAS,CAAC;IACtB,eAAe;IACf,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACnC,sCAAsC;IACtC,aAAa,EAAE,MAAM,aAAa,CAAC;IACnC,gDAAgD;IAChD,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,EAAE,eA2C3B,CAAC"}
@@ -6,7 +6,7 @@ const ThemeContext = createContext();
6
6
  function useTheme() {
7
7
  const context = useContext(ThemeContext);
8
8
  if (!context) {
9
- throw new Error("useTheme\uB294 ThemeProvider \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. ThemeProvider\uB294 InitializeProvider \uC544\uB798\uC5D0 \uC704\uCE58\uD574\uC57C \uD569\uB2C8\uB2E4");
9
+ throw new Error("useTheme\uB294 ThemeProvider \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
10
10
  }
11
11
  return context;
12
12
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/providers/ThemeContext.tsx"],
4
- "mappings": ";AAAA,SACEA,eACAC,YAEAC,YACAC,cACAC,iBACK;AACP,SAASC,wBAAwB;AACjC,SAASC,qBAAqB;AA0B9B,MAAMC,eAAeP,cAAiC;AAwB/C,SAASQ,WAA8B;AAC5C,QAAMC,UAAUR,WAAWM,YAAY;AACvC,MAAI,CAACE,SAAS;AACZ,UAAM,IAAIC,MACR,uNACF;EACF;AACA,SAAOD;AACT;AAmBO,MAAME,gBAAkCC,WAAU;AACvD,QAAM,CAACC,MAAMC,SAASC,KAAK,IAAIT,cAAyB,SAAS,QAAQ;AAGzE,QAAMU,cAAcX,iBAAiB,8BAA8B;AAGnE,QAAMY,gBAAgBf,WAA0B,MAAM;AACpD,UAAMgB,cAAcL,KAAK;AACzB,QAAIK,gBAAgB,UAAU;AAC5B,aAAOF,YAAY,IAAI,SAAS;IAClC;AACA,WAAOE;EACT,CAAC;AAGD,QAAMC,YAAYA,MAAM;AACtB,UAAMC,UAAUP,KAAK;AACrB,UAAMQ,OACJD,YAAY,UAAU,WAAWA,YAAY,WAAW,SAAS;AACnEN,YAAQO,IAAI;EACd;AAGAlB,eAAa,MAAM;AACjB,QAAI,CAACY,MAAM,EAAG;AACd,UAAMO,SAASL,cAAc,MAAM;AACnCM,aAASC,gBAAgBC,UAAUC,OAAO,QAAQJ,MAAM;EAC1D,CAAC;AAGDlB,YAAU,MAAM;AACdmB,aAASC,gBAAgBC,UAAUE,OAAO,MAAM;EAClD,CAAC;AAED,QAAMC,eAAkC;IACtCf;IACAC;IACAG;IACAE;EACF;AAEA,SAAAU,kBAAQtB,aAAauB,UAAQ;IAACC,OAAOH;IAAY,IAAAI,WAAA;AAAA,aAAGpB,MAAMoB;IAAQ;EAAA,CAAA;AACpE;",
4
+ "mappings": ";AAAA,SACEA,eACAC,YAEAC,YACAC,cACAC,iBACK;AACP,SAASC,wBAAwB;AACjC,SAASC,qBAAqB;AA0B9B,MAAMC,eAAeP,cAAiC;AAwB/C,SAASQ,WAA8B;AAC5C,QAAMC,UAAUR,WAAWM,YAAY;AACvC,MAAI,CAACE,SAAS;AACZ,UAAM,IAAIC,MAAM,gHAA0C;EAC5D;AACA,SAAOD;AACT;AAmBO,MAAME,gBAAkCC,WAAU;AACvD,QAAM,CAACC,MAAMC,SAASC,KAAK,IAAIT,cAAyB,SAAS,QAAQ;AAGzE,QAAMU,cAAcX,iBAAiB,8BAA8B;AAGnE,QAAMY,gBAAgBf,WAA0B,MAAM;AACpD,UAAMgB,cAAcL,KAAK;AACzB,QAAIK,gBAAgB,UAAU;AAC5B,aAAOF,YAAY,IAAI,SAAS;IAClC;AACA,WAAOE;EACT,CAAC;AAGD,QAAMC,YAAYA,MAAM;AACtB,UAAMC,UAAUP,KAAK;AACrB,UAAMQ,OACJD,YAAY,UAAU,WAAWA,YAAY,WAAW,SAAS;AACnEN,YAAQO,IAAI;EACd;AAGAlB,eAAa,MAAM;AACjB,QAAI,CAACY,MAAM,EAAG;AACd,UAAMO,SAASL,cAAc,MAAM;AACnCM,aAASC,gBAAgBC,UAAUC,OAAO,QAAQJ,MAAM;EAC1D,CAAC;AAGDlB,YAAU,MAAM;AACdmB,aAASC,gBAAgBC,UAAUE,OAAO,MAAM;EAClD,CAAC;AAED,QAAMC,eAAkC;IACtCf;IACAC;IACAG;IACAE;EACF;AAEA,SAAAU,kBAAQtB,aAAauB,UAAQ;IAACC,OAAOH;IAAY,IAAAI,WAAA;AAAA,aAAGpB,MAAMoB;IAAQ;EAAA,CAAA;AACpE;",
5
5
  "names": ["createContext", "useContext", "createMemo", "createEffect", "onCleanup", "createMediaQuery", "useSyncConfig", "ThemeContext", "useTheme", "context", "Error", "ThemeProvider", "props", "mode", "setMode", "ready", "prefersDark", "resolvedTheme", "currentMode", "cycleMode", "current", "next", "isDark", "document", "documentElement", "classList", "toggle", "remove", "contextValue", "_$createComponent", "Provider", "value", "children"]
6
6
  }
@@ -212,7 +212,7 @@ function MyPage() {
212
212
 
213
213
  **DialogProvider:**
214
214
 
215
- `DialogProvider` is the provider component that enables `useDialog`. It is automatically included by `InitializeProvider`. Use `DialogProvider` directly only when building a custom provider tree.
215
+ `DialogProvider` is the provider component that enables `useDialog`. Use it in your provider tree to enable programmatic dialogs.
216
216
 
217
217
  ```tsx
218
218
  import { DialogProvider } from "@simplysm/solid";
package/docs/feedback.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Notification
4
4
 
5
- Notification system. `InitializeProvider` automatically sets up `NotificationProvider` and `NotificationBanner`, so you only need to use the `useNotification` hook and optionally add `NotificationBell` in your layout.
5
+ Notification system. Set up `NotificationProvider` and `NotificationBanner` in your provider tree. Use the `useNotification` hook to show notifications and optionally add `NotificationBell` in your layout.
6
6
 
7
7
  ```tsx
8
8
  import {
@@ -58,14 +58,14 @@ function MyComponent() {
58
58
  | `clear` | `() => void` | Clear all |
59
59
 
60
60
  **Components:**
61
- - `NotificationBanner` -- Top-of-screen notification banner (automatically included by `InitializeProvider`)
61
+ - `NotificationBanner` -- Top-of-screen notification banner (add inside `NotificationProvider`)
62
62
  - `NotificationBell` -- Notification bell icon (shows unread count, add to your layout as needed)
63
63
 
64
64
  ---
65
65
 
66
66
  ## Busy
67
67
 
68
- Busy overlay system. `InitializeProvider` automatically sets up `BusyProvider` and `BusyContainer`. Use the `busyVariant` option in `AppConfig` to choose between `"spinner"` (default) and `"bar"` variants. Control the busy state using the `useBusy` hook.
68
+ Busy overlay system. Set up `BusyProvider` in your provider tree. Pass `variant` prop to choose between `"spinner"` (default) and `"bar"` variants. Control the busy state using the `useBusy` hook.
69
69
 
70
70
  ```tsx
71
71
  import { useBusy } from "@simplysm/solid";
@@ -119,7 +119,7 @@ import { BusyContainer } from "@simplysm/solid";
119
119
 
120
120
  ## Print / usePrint
121
121
 
122
- Browser printing and PDF generation. Must be used inside `InitializeProvider`.
122
+ Browser printing and PDF generation.
123
123
 
124
124
  ```tsx
125
125
  import { Print, usePrint } from "@simplysm/solid";
@@ -589,7 +589,7 @@ import { ColorPicker } from "@simplysm/solid";
589
589
 
590
590
  ## ThemeToggle
591
591
 
592
- Dark/light/system theme cycle toggle button. Must be used inside `InitializeProvider`.
592
+ Dark/light/system theme cycle toggle button. Must be used inside `ThemeProvider`.
593
593
 
594
594
  ```tsx
595
595
  import { ThemeToggle } from "@simplysm/solid";
package/docs/hooks.md CHANGED
@@ -1,42 +1,8 @@
1
1
  # Hooks
2
2
 
3
- ## usePwaUpdate
4
-
5
- PWA Service Worker update detection hook. Automatically polls for Service Worker updates every 5 minutes. When a new version is detected, shows a notification with a reload action button.
6
-
7
- **Automatic Integration:** Already integrated into `InitializeProvider` -- no manual setup required for most applications. The hook runs automatically inside the notification system.
8
-
9
- **Manual Usage (Custom Provider Tree):**
10
-
11
- ```tsx
12
- import { usePwaUpdate } from "@simplysm/solid";
13
-
14
- function MyProvider(props) {
15
- // Must be called inside NotificationProvider
16
- usePwaUpdate();
17
-
18
- return (
19
- <NotificationProvider>
20
- {props.children}
21
- </NotificationProvider>
22
- );
23
- }
24
- ```
25
-
26
- **Graceful No-ops:** Works safely in the following scenarios where Service Workers are unavailable:
27
- - HTTP protocol (non-HTTPS dev servers)
28
- - Browsers that don't support Service Workers
29
- - Development/test environments without SW registration
30
-
31
- **Requirements:**
32
- - Must be called inside `NotificationProvider` (to display the update notification)
33
- - `InitializeProvider` already includes both, so manual setup only needed for custom provider trees
34
-
35
- ---
36
-
37
3
  ## useTheme
38
4
 
39
- Hook to access theme (dark/light/system) state. Must be used inside `InitializeProvider`.
5
+ Hook to access theme (dark/light/system) state. Must be used inside `ThemeProvider`.
40
6
 
41
7
  ```tsx
42
8
  import { useTheme } from "@simplysm/solid";
@@ -76,7 +42,7 @@ const [token, setToken] = useLocalStorage<string | undefined>("auth-token", unde
76
42
 
77
43
  ## useSyncConfig
78
44
 
79
- Syncable config hook. Uses `syncStorage` if configured, falls back to `localStorage` otherwise. Keys are automatically prefixed as `{clientName}.{key}`. Use for user preferences that should sync across devices (theme, DataSheet column configs, filter presets).
45
+ Syncable config hook. Uses `SyncStorageProvider` storage if present, falls back to `localStorage` otherwise. Keys are automatically prefixed as `{clientName}.{key}`. Use for user preferences that should sync across devices (theme, DataSheet column configs, filter presets).
80
46
 
81
47
  ```tsx
82
48
  import { useSyncConfig } from "@simplysm/solid";
@@ -97,7 +63,7 @@ const [theme, setTheme, ready] = useSyncConfig("theme", "light");
97
63
 
98
64
  ## useLogger
99
65
 
100
- Logging hook. If `logger` adapter is configured in `AppConfig`, logs are sent to the adapter only. Otherwise, logs fall back to `consola`. Must be used inside `InitializeProvider`.
66
+ Logging hook. If `LoggerProvider` is present, logs are sent to the adapter only. Otherwise, logs fall back to `consola`.
101
67
 
102
68
  ```tsx
103
69
  import { useLogger } from "@simplysm/solid";
@@ -116,31 +82,31 @@ logger.warn("deprecation notice");
116
82
  | `warn` | `(...args: unknown[]) => void` | Log message (warning) |
117
83
  | `error` | `(...args: unknown[]) => void` | Log message (error) |
118
84
 
119
- **Global error capturing:** `InitializeProvider` automatically captures uncaught errors (`window.onerror`) and unhandled promise rejections (`unhandledrejection`) and logs them via `useLogger`. No additional setup required.
85
+ **Global error capturing:** `ErrorLoggerProvider` captures uncaught errors (`window.onerror`) and unhandled promise rejections (`unhandledrejection`) and logs them via `useLogger`.
120
86
 
121
87
  ---
122
88
 
123
89
  ## useNotification
124
90
 
125
- Hook to access notification system. Must be used inside `InitializeProvider`. See [Notification](feedback.md#notification) for detailed API.
91
+ Hook to access notification system. Must be used inside `NotificationProvider`. See [Notification](feedback.md#notification) for detailed API.
126
92
 
127
93
  ---
128
94
 
129
95
  ## useBusy
130
96
 
131
- Hook to access busy overlay. Must be used inside `InitializeProvider`. See [Busy](feedback.md#busy) for detailed API.
97
+ Hook to access busy overlay. Must be used inside `BusyProvider`. See [Busy](feedback.md#busy) for detailed API.
132
98
 
133
99
  ---
134
100
 
135
101
  ## usePrint
136
102
 
137
- Hook for printing and PDF generation. Must be used inside `InitializeProvider`. See [Print / usePrint](feedback.md#print--useprint) for detailed API.
103
+ Hook for printing and PDF generation. See [Print / usePrint](feedback.md#print--useprint) for detailed API.
138
104
 
139
105
  ---
140
106
 
141
107
  ## useConfig
142
108
 
143
- Hook to access app-wide configuration. Must be used inside `InitializeProvider`.
109
+ Hook to access app-wide configuration. Must be used inside `ConfigProvider`.
144
110
 
145
111
  ```tsx
146
112
  import { useConfig } from "@simplysm/solid";
package/docs/providers.md CHANGED
@@ -1,10 +1,123 @@
1
1
  # Providers
2
2
 
3
- ## InitializeProvider
3
+ Providers are composable and independent. Compose them at your app root in the recommended order:
4
4
 
5
- Root provider that wraps the entire application. Automatically sets up all required providers: configuration context, theme (dark/light/system), notification system with banner, global error capturing (window.onerror, unhandledrejection), busy overlay, programmatic dialog support, and form control clipboard value copy.
5
+ ```tsx
6
+ <ConfigProvider clientName="my-app">
7
+ <SyncStorageProvider storage={...}> {/* optional */}
8
+ <LoggerProvider adapter={...}> {/* optional */}
9
+ <NotificationProvider>
10
+ <NotificationBanner />
11
+ <ErrorLoggerProvider>
12
+ <PwaUpdateProvider>
13
+ <ClipboardProvider>
14
+ <ThemeProvider>
15
+ <BusyProvider>{/* app content */}</BusyProvider>
16
+ </ThemeProvider>
17
+ </ClipboardProvider>
18
+ </PwaUpdateProvider>
19
+ </ErrorLoggerProvider>
20
+ </NotificationProvider>
21
+ </LoggerProvider>
22
+ </SyncStorageProvider>
23
+ </ConfigProvider>
24
+ ```
25
+
26
+ ## ConfigProvider
27
+
28
+ Required root provider. Provides `clientName` used as storage key prefix.
29
+
30
+ ```tsx
31
+ <ConfigProvider clientName="my-app">
32
+ {/* app content */}
33
+ </ConfigProvider>
34
+ ```
35
+
36
+ | Prop | Type | Description |
37
+ |------|------|-------------|
38
+ | `clientName` | `string` | Client identifier (used as storage key prefix) |
39
+
40
+ ---
41
+
42
+ ## SyncStorageProvider
43
+
44
+ Optional provider for custom sync storage (cross-device sync). When present, `useSyncConfig` uses this storage instead of `localStorage`.
45
+
46
+ ```tsx
47
+ <SyncStorageProvider storage={myStorageAdapter}>
48
+ {/* children */}
49
+ </SyncStorageProvider>
50
+ ```
51
+
52
+ | Prop | Type | Description |
53
+ |------|------|-------------|
54
+ | `storage` | `StorageAdapter` | Storage adapter implementation |
55
+
56
+ ---
57
+
58
+ ## LoggerProvider
59
+
60
+ Optional provider for remote logging. When present, `useLogger` sends logs to the adapter instead of `consola`.
61
+
62
+ ```tsx
63
+ <LoggerProvider adapter={myLogAdapter}>
64
+ {/* children */}
65
+ </LoggerProvider>
66
+ ```
67
+
68
+ | Prop | Type | Description |
69
+ |------|------|-------------|
70
+ | `adapter` | `LogAdapter` | Log adapter implementation |
71
+
72
+ ---
73
+
74
+ ## ErrorLoggerProvider
75
+
76
+ Captures uncaught errors (`window.onerror`) and unhandled promise rejections (`unhandledrejection`) and logs them via `useLogger`.
77
+
78
+ ```tsx
79
+ <ErrorLoggerProvider>
80
+ {/* children */}
81
+ </ErrorLoggerProvider>
82
+ ```
6
83
 
7
- See the [Configuration](../README.md#configuration) section in the main README for setup instructions and `AppConfig` options.
84
+ ---
85
+
86
+ ## PwaUpdateProvider
87
+
88
+ PWA Service Worker update detection. Polls for SW updates every 5 minutes. When a new version is detected, shows a notification with a reload action. Must be inside `NotificationProvider`.
89
+
90
+ Graceful no-op when `navigator.serviceWorker` is unavailable (HTTP, unsupported browser, dev mode).
91
+
92
+ ```tsx
93
+ <PwaUpdateProvider>
94
+ {/* children */}
95
+ </PwaUpdateProvider>
96
+ ```
97
+
98
+ ---
99
+
100
+ ## ClipboardProvider
101
+
102
+ Intercepts `Ctrl+C` to copy form control values (input, textarea, select, checkbox) as plain text. Handles table structures as TSV format.
103
+
104
+ ```tsx
105
+ <ClipboardProvider>
106
+ {/* children */}
107
+ </ClipboardProvider>
108
+ ```
109
+
110
+ ---
111
+
112
+ ## ThemeProvider
113
+
114
+ Dark/light/system theme provider. Toggles the `dark` class on `<html>` and manages theme persistence via `useSyncConfig`.
115
+
116
+ ```tsx
117
+ <ThemeProvider>
118
+ {/* children */}
119
+ </ThemeProvider>
120
+ ```
8
121
 
9
122
  ---
10
123
 
package/docs/styling.md CHANGED
@@ -41,7 +41,7 @@
41
41
 
42
42
  ## Dark Mode
43
43
 
44
- Uses Tailwind's `class` strategy. `InitializeProvider` automatically toggles the `dark` class on the `<html>` element via the built-in theme provider.
44
+ Uses Tailwind's `class` strategy. `ThemeProvider` automatically toggles the `dark` class on the `<html>` element.
45
45
 
46
46
  ```html
47
47
  <!-- Light mode -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/solid",
3
- "version": "13.0.31",
3
+ "version": "13.0.33",
4
4
  "description": "심플리즘 패키지 - SolidJS 라이브러리",
5
5
  "author": "김석래",
6
6
  "license": "Apache-2.0",
@@ -28,18 +28,18 @@
28
28
  "@solid-primitives/storage": "^4.3.3",
29
29
  "@solidjs/router": "^0.15.4",
30
30
  "@tabler/icons-solidjs": "^3.36.1",
31
- "@tiptap/core": "^3.19.0",
32
- "@tiptap/extension-color": "^3.19.0",
33
- "@tiptap/extension-highlight": "^3.19.0",
34
- "@tiptap/extension-image": "^3.19.0",
35
- "@tiptap/extension-table": "^3.19.0",
36
- "@tiptap/extension-table-cell": "^3.19.0",
37
- "@tiptap/extension-table-header": "^3.19.0",
38
- "@tiptap/extension-table-row": "^3.19.0",
39
- "@tiptap/extension-text-align": "^3.19.0",
40
- "@tiptap/extension-text-style": "^3.19.0",
41
- "@tiptap/pm": "^3.19.0",
42
- "@tiptap/starter-kit": "^3.19.0",
31
+ "@tiptap/core": "^3.20.0",
32
+ "@tiptap/extension-color": "^3.20.0",
33
+ "@tiptap/extension-highlight": "^3.20.0",
34
+ "@tiptap/extension-image": "^3.20.0",
35
+ "@tiptap/extension-table": "^3.20.0",
36
+ "@tiptap/extension-table-cell": "^3.20.0",
37
+ "@tiptap/extension-table-header": "^3.20.0",
38
+ "@tiptap/extension-table-row": "^3.20.0",
39
+ "@tiptap/extension-text-align": "^3.20.0",
40
+ "@tiptap/extension-text-style": "^3.20.0",
41
+ "@tiptap/pm": "^3.20.0",
42
+ "@tiptap/starter-kit": "^3.20.0",
43
43
  "bwip-js": "^4.8.0",
44
44
  "clsx": "^2.1.1",
45
45
  "consola": "^3.4.2",
@@ -47,10 +47,10 @@
47
47
  "jspdf": "^4.1.0",
48
48
  "solid-js": "^1.9.11",
49
49
  "solid-tiptap": "^0.8.0",
50
- "tailwind-merge": "^3.4.1",
50
+ "tailwind-merge": "^3.5.0",
51
51
  "tailwindcss": "^3.4.19",
52
- "@simplysm/core-browser": "13.0.31",
53
- "@simplysm/core-common": "13.0.31"
52
+ "@simplysm/core-browser": "13.0.33",
53
+ "@simplysm/core-common": "13.0.33"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@solidjs/testing-library": "^0.8.10"
@@ -1,5 +1,5 @@
1
1
  import { consola } from "consola";
2
- import { useConfig, type LogAdapter } from "../providers/ConfigContext";
2
+ import { useLogAdapter, type LogAdapter } from "../providers/LoggerContext";
3
3
 
4
4
  type LogLevel = Parameters<LogAdapter["write"]>[0];
5
5
 
@@ -11,12 +11,12 @@ interface Logger {
11
11
  }
12
12
 
13
13
  export function useLogger(): Logger {
14
- const config = useConfig();
14
+ const logAdapter = useLogAdapter();
15
15
 
16
16
  const createLogFunction = (level: LogLevel) => {
17
17
  return (...args: unknown[]) => {
18
- if (config.logger) {
19
- void config.logger.write(level, ...args);
18
+ if (logAdapter) {
19
+ void logAdapter.write(level, ...args);
20
20
  } else {
21
21
  (consola as any)[level](...args);
22
22
  }
@@ -1,10 +1,11 @@
1
1
  import { type Accessor, type Setter, createEffect, createSignal } from "solid-js";
2
2
  import { useConfig } from "../providers/ConfigContext";
3
+ import { useSyncStorage } from "../providers/SyncStorageContext";
3
4
 
4
5
  /**
5
6
  * Creates a reactive signal that syncs configuration data to storage.
6
7
  *
7
- * Uses `syncStorage` from ConfigProvider if available, otherwise falls back to `localStorage`.
8
+ * Uses `SyncStorageProvider` storage if available, otherwise falls back to `localStorage`.
8
9
  * Designed for data that should persist and sync across devices (e.g., theme, user preferences, DataSheet configs).
9
10
  *
10
11
  * @param key - Storage key for the config value
@@ -27,13 +28,14 @@ export function useSyncConfig<TValue>(
27
28
  defaultValue: TValue,
28
29
  ): [Accessor<TValue>, Setter<TValue>, Accessor<boolean>] {
29
30
  const config = useConfig();
31
+ const syncStorage = useSyncStorage();
30
32
  const prefixedKey = `${config.clientName}.${key}`;
31
33
  const [value, setValue] = createSignal<TValue>(defaultValue);
32
34
  const [ready, setReady] = createSignal(false);
33
35
 
34
36
  // Initialize from storage
35
37
  const initializeFromStorage = async () => {
36
- if (!config.syncStorage) {
38
+ if (!syncStorage) {
37
39
  // Use localStorage synchronously
38
40
  try {
39
41
  const stored = localStorage.getItem(prefixedKey);
@@ -49,7 +51,7 @@ export function useSyncConfig<TValue>(
49
51
 
50
52
  // Use syncStorage asynchronously
51
53
  try {
52
- const stored = await config.syncStorage.getItem(prefixedKey);
54
+ const stored = await syncStorage.getItem(prefixedKey);
53
55
  if (stored !== null) {
54
56
  setValue(() => JSON.parse(stored) as TValue);
55
57
  }
@@ -77,7 +79,7 @@ export function useSyncConfig<TValue>(
77
79
  const currentValue = value();
78
80
  const serialized = JSON.stringify(currentValue);
79
81
 
80
- if (!config.syncStorage) {
82
+ if (!syncStorage) {
81
83
  // Use localStorage synchronously
82
84
  localStorage.setItem(prefixedKey, serialized);
83
85
  return;
@@ -86,7 +88,7 @@ export function useSyncConfig<TValue>(
86
88
  // Use syncStorage asynchronously
87
89
  void (async () => {
88
90
  try {
89
- await config.syncStorage!.setItem(prefixedKey, serialized);
91
+ await syncStorage.setItem(prefixedKey, serialized);
90
92
  } catch {
91
93
  // Fall back to localStorage on error
92
94
  localStorage.setItem(prefixedKey, serialized);
package/src/index.ts CHANGED
@@ -110,8 +110,12 @@ export * from "./components/feedback/Progress";
110
110
  //#region ========== Providers ==========
111
111
 
112
112
  export * from "./providers/ConfigContext";
113
- export * from "./providers/InitializeProvider";
114
- export { useTheme } from "./providers/ThemeContext";
113
+ export * from "./providers/SyncStorageContext";
114
+ export * from "./providers/LoggerContext";
115
+ export * from "./providers/ErrorLoggerProvider";
116
+ export * from "./providers/PwaUpdateProvider";
117
+ export * from "./providers/ClipboardProvider";
118
+ export { useTheme, ThemeProvider } from "./providers/ThemeContext";
115
119
  export type { ThemeMode, ResolvedTheme } from "./providers/ThemeContext";
116
120
  export * from "./providers/ServiceClientContext";
117
121
  export * from "./providers/ServiceClientProvider";
@@ -130,7 +134,6 @@ export * from "./hooks/usePrint";
130
134
  export { createControllableSignal } from "./hooks/createControllableSignal";
131
135
  export { createIMEHandler } from "./hooks/createIMEHandler";
132
136
  export { createMountTransition } from "./hooks/createMountTransition";
133
- export { usePwaUpdate } from "./hooks/usePwaUpdate";
134
137
  export { useRouterLink } from "./hooks/useRouterLink";
135
138
 
136
139
  //#endregion