@simplysm/solid 13.0.35 → 13.0.37

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 (34) hide show
  1. package/README.md +3 -3
  2. package/dist/hooks/useLogger.d.ts +1 -1
  3. package/dist/hooks/useLogger.d.ts.map +1 -1
  4. package/dist/hooks/useLogger.js +2 -2
  5. package/dist/hooks/useLogger.js.map +1 -1
  6. package/dist/providers/InitializeProvider.d.ts +3 -3
  7. package/dist/providers/LoggerContext.d.ts +14 -8
  8. package/dist/providers/LoggerContext.d.ts.map +1 -1
  9. package/dist/providers/LoggerContext.js +6 -2
  10. package/dist/providers/LoggerContext.js.map +2 -2
  11. package/dist/providers/SyncStorageContext.d.ts +12 -8
  12. package/dist/providers/SyncStorageContext.d.ts.map +1 -1
  13. package/dist/providers/SyncStorageContext.js +7 -2
  14. package/dist/providers/SyncStorageContext.js.map +2 -2
  15. package/dist/providers/shared-data/SharedDataContext.d.ts +4 -2
  16. package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
  17. package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
  18. package/dist/providers/shared-data/SharedDataProvider.d.ts +2 -2
  19. package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
  20. package/dist/providers/shared-data/SharedDataProvider.js +2 -1
  21. package/dist/providers/shared-data/SharedDataProvider.js.map +2 -2
  22. package/docs/disclosure.md +8 -12
  23. package/docs/form-controls.md +1 -1
  24. package/docs/hooks.md +15 -0
  25. package/docs/layout.md +16 -2
  26. package/docs/providers.md +4 -4
  27. package/docs/styling.md +3 -2
  28. package/package.json +3 -3
  29. package/src/hooks/useLogger.ts +3 -3
  30. package/src/providers/InitializeProvider.tsx +3 -3
  31. package/src/providers/LoggerContext.tsx +21 -10
  32. package/src/providers/SyncStorageContext.tsx +23 -10
  33. package/src/providers/shared-data/SharedDataContext.ts +8 -4
  34. package/src/providers/shared-data/SharedDataProvider.tsx +9 -3
package/README.md CHANGED
@@ -56,9 +56,9 @@ function AppRoot() {
56
56
 
57
57
  onMount(async () => {
58
58
  await serviceClient.connect("main", { port: 3000 });
59
- useSyncStorage()!.configure(myStorageAdapter);
60
- useLogger().configure(myLogAdapter);
61
- useSharedData().configure(definitions);
59
+ useSyncStorage()!.configure((origin) => myStorageAdapter);
60
+ useLogger().configure((origin) => myLogAdapter);
61
+ useSharedData().configure((origin) => definitions);
62
62
  });
63
63
  }
64
64
  ```
@@ -5,7 +5,7 @@ export interface Logger {
5
5
  warn: (...args: unknown[]) => void;
6
6
  error: (...args: unknown[]) => void;
7
7
  /** LogAdapter를 나중에 주입. LoggerProvider 내부에서만 사용 가능 */
8
- configure: (adapter: LogAdapter) => void;
8
+ configure: (fn: (origin: LogAdapter) => LogAdapter) => void;
9
9
  }
10
10
  export declare function useLogger(): Logger;
11
11
  //# sourceMappingURL=useLogger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLogger.d.ts","sourceRoot":"","sources":["../../src/hooks/useLogger.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAI5E,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,qDAAqD;IACrD,SAAS,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;CAC1C;AAED,wBAAgB,SAAS,IAAI,MAAM,CA2BlC"}
1
+ {"version":3,"file":"useLogger.d.ts","sourceRoot":"","sources":["../../src/hooks/useLogger.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAI5E,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,qDAAqD;IACrD,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,KAAK,IAAI,CAAC;CAC7D;AAED,wBAAgB,SAAS,IAAI,MAAM,CA2BlC"}
@@ -17,11 +17,11 @@ function useLogger() {
17
17
  info: createLogFunction("info"),
18
18
  warn: createLogFunction("warn"),
19
19
  error: createLogFunction("error"),
20
- configure: (adapter) => {
20
+ configure: (fn) => {
21
21
  if (!loggerCtx) {
22
22
  throw new Error("configure()\uB294 LoggerProvider \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
23
23
  }
24
- loggerCtx.configure(adapter);
24
+ loggerCtx.configure(fn);
25
25
  }
26
26
  };
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hooks/useLogger.ts"],
4
- "mappings": "AAAA,SAAS,eAAe;AACxB,SAAS,qBAAsC;AAaxC,SAAS,YAAoB;AAClC,QAAM,YAAY,cAAc;AAEhC,QAAM,oBAAoB,CAAC,UAAoB;AAC7C,WAAO,IAAI,SAAoB;AAE7B,YAAM,UAAU,uCAAW;AAC3B,UAAI,SAAS;AACX,aAAK,QAAQ,MAAM,OAAO,GAAG,IAAI;AAAA,MACnC,OAAO;AACL,QAAC,QAAgB,KAAK,EAAE,GAAG,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK,kBAAkB,KAAK;AAAA,IAC5B,MAAM,kBAAkB,MAAM;AAAA,IAC9B,MAAM,kBAAkB,MAAM;AAAA,IAC9B,OAAO,kBAAkB,OAAO;AAAA,IAChC,WAAW,CAAC,YAAwB;AAClC,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,oHAA8C;AAAA,MAChE;AACA,gBAAU,UAAU,OAAO;AAAA,IAC7B;AAAA,EACF;AACF;",
4
+ "mappings": "AAAA,SAAS,eAAe;AACxB,SAAS,qBAAsC;AAaxC,SAAS,YAAoB;AAClC,QAAM,YAAY,cAAc;AAEhC,QAAM,oBAAoB,CAAC,UAAoB;AAC7C,WAAO,IAAI,SAAoB;AAE7B,YAAM,UAAU,uCAAW;AAC3B,UAAI,SAAS;AACX,aAAK,QAAQ,MAAM,OAAO,GAAG,IAAI;AAAA,MACnC,OAAO;AACL,QAAC,QAAgB,KAAK,EAAE,GAAG,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK,kBAAkB,KAAK;AAAA,IAC5B,MAAM,kBAAkB,MAAM;AAAA,IAC9B,MAAM,kBAAkB,MAAM;AAAA,IAC9B,OAAO,kBAAkB,OAAO;AAAA,IAChC,WAAW,CAAC,OAA2C;AACrD,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,oHAA8C;AAAA,MAChE;AACA,gBAAU,UAAU,EAAE;AAAA,IACxB;AAAA,EACF;AACF;",
5
5
  "names": []
6
6
  }
@@ -19,9 +19,9 @@ export type { BusyVariant };
19
19
  * const serviceClient = useServiceClient();
20
20
  * onMount(async () => {
21
21
  * await serviceClient.connect("main", { port: 3000 });
22
- * useSyncStorage()!.configure(myStorageAdapter);
23
- * useLogger().configure(myLogAdapter);
24
- * useSharedData().configure(definitions);
22
+ * useSyncStorage()!.configure((origin) => myStorageAdapter);
23
+ * useLogger().configure((origin) => myLogAdapter);
24
+ * useSharedData().configure((origin) => definitions);
25
25
  * });
26
26
  * }
27
27
  * ```
@@ -13,18 +13,18 @@ export interface LogAdapter {
13
13
  * 로그 어댑터 Context 값
14
14
  *
15
15
  * @remarks
16
- * - `adapter`: 현재 설정된 LogAdapter (signal). configure 전에는 undefined
17
- * - `configure`: adapter를 나중에 주입하는 함수
16
+ * - `adapter`: 현재 설정된 LogAdapter (signal). 기본값은 consola 기반 adapter
17
+ * - `configure`: decorator function으로 adapter를 설정/체이닝하는 함수
18
18
  */
19
19
  export interface LoggerContextValue {
20
- adapter: Accessor<LogAdapter | undefined>;
21
- configure: (adapter: LogAdapter) => void;
20
+ adapter: Accessor<LogAdapter>;
21
+ configure: (fn: (origin: LogAdapter) => LogAdapter) => void;
22
22
  }
23
23
  /**
24
24
  * 로그 어댑터 Context
25
25
  *
26
26
  * @remarks
27
- * Provider가 없으면 `undefined` (useLogger에서 consola fallback)
27
+ * Provider가 없으면 `undefined` (useLogger에서 consola 기본 adapter 사용)
28
28
  */
29
29
  export declare const LoggerContext: import("solid-js").Context<LoggerContextValue | undefined>;
30
30
  /**
@@ -38,7 +38,8 @@ export declare function useLogAdapter(): LoggerContextValue | undefined;
38
38
  *
39
39
  * @remarks
40
40
  * - prop 없이 사용. adapter는 `useLogger().configure()`로 나중에 주입
41
- * - configure 전에는 useLogger가 consola로 fallback
41
+ * - 기본값은 consola 기반 adapter
42
+ * - configure는 decorator function을 받아 기존 adapter를 감싸거나 교체
42
43
  *
43
44
  * @example
44
45
  * ```tsx
@@ -46,8 +47,13 @@ export declare function useLogAdapter(): LoggerContextValue | undefined;
46
47
  * <App />
47
48
  * </LoggerProvider>
48
49
  *
49
- * // 자식 컴포넌트에서 나중에 설정:
50
- * useLogger().configure(myLogAdapter);
50
+ * // 자식 컴포넌트에서 decorator로 설정:
51
+ * useLogger().configure((origin) => ({
52
+ * write: (...args) => {
53
+ * origin.write(...args);
54
+ * sendToServer(...args);
55
+ * },
56
+ * }));
51
57
  * ```
52
58
  */
53
59
  export declare const LoggerProvider: ParentComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"LoggerContext.d.ts","sourceRoot":"","sources":["../../src/providers/LoggerContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAIb,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAElB;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1F;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC1C,SAAS,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;CAC1C;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,4DAAsC,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,kBAAkB,GAAG,SAAS,CAE9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,EAAE,eAS5B,CAAC"}
1
+ {"version":3,"file":"LoggerContext.d.ts","sourceRoot":"","sources":["../../src/providers/LoggerContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAIb,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAGlB;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1F;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC9B,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,4DAAsC,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,kBAAkB,GAAG,SAAS,CAE9D;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,cAAc,EAAE,eAS5B,CAAC"}
@@ -1,14 +1,18 @@
1
1
  import { createComponent as _$createComponent } from "solid-js/web";
2
2
  import { createContext, createSignal, useContext } from "solid-js";
3
+ import { consola } from "consola";
4
+ const defaultLogAdapter = {
5
+ write: (severity, ...data) => consola[severity](...data)
6
+ };
3
7
  const LoggerContext = createContext();
4
8
  function useLogAdapter() {
5
9
  return useContext(LoggerContext);
6
10
  }
7
11
  const LoggerProvider = (props) => {
8
- const [adapter, setAdapter] = createSignal();
12
+ const [adapter, setAdapter] = createSignal(defaultLogAdapter);
9
13
  const value = {
10
14
  adapter,
11
- configure: (a) => setAdapter(() => a)
15
+ configure: (fn) => setAdapter((prev) => fn(prev))
12
16
  };
13
17
  return _$createComponent(LoggerContext.Provider, {
14
18
  value,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/providers/LoggerContext.tsx"],
4
- "mappings": ";AAAA,SAEEA,eACAC,cACAC,kBAEK;AA+BA,MAAMC,gBAAgBH,cAAkC;AAOxD,SAASI,gBAAgD;AAC9D,SAAOF,WAAWC,aAAa;AACjC;AAmBO,MAAME,iBAAmCC,WAAU;AACxD,QAAM,CAACC,SAASC,UAAU,IAAIP,aAAqC;AAEnE,QAAMQ,QAA4B;IAChCF;IACAG,WAAYC,OAAkBH,WAAW,MAAMG,CAAC;EAClD;AAEA,SAAAC,kBAAQT,cAAcU,UAAQ;IAACJ;IAAY,IAAAK,WAAA;AAAA,aAAGR,MAAMQ;IAAQ;EAAA,CAAA;AAC9D;",
5
- "names": ["createContext", "createSignal", "useContext", "LoggerContext", "useLogAdapter", "LoggerProvider", "props", "adapter", "setAdapter", "value", "configure", "a", "_$createComponent", "Provider", "children"]
4
+ "mappings": ";AAAA,SAEEA,eACAC,cACAC,kBAEK;AACP,SAASC,eAAe;AAaxB,MAAMC,oBAAgC;EACpCC,OAAOA,CAACC,aAAaC,SAAUJ,QAAgBG,QAAQ,EAAE,GAAGC,IAAI;AAClE;AAoBO,MAAMC,gBAAgBR,cAAkC;AAOxD,SAASS,gBAAgD;AAC9D,SAAOP,WAAWM,aAAa;AACjC;AAyBO,MAAME,iBAAmCC,WAAU;AACxD,QAAM,CAACC,SAASC,UAAU,IAAIZ,aAAyBG,iBAAiB;AAExE,QAAMU,QAA4B;IAChCF;IACAG,WAAYC,QAA2CH,WAAYI,UAASD,GAAGC,IAAI,CAAC;EACtF;AAEA,SAAAC,kBAAQV,cAAcW,UAAQ;IAACL;IAAY,IAAAM,WAAA;AAAA,aAAGT,MAAMS;IAAQ;EAAA,CAAA;AAC9D;",
5
+ "names": ["createContext", "createSignal", "useContext", "consola", "defaultLogAdapter", "write", "severity", "data", "LoggerContext", "useLogAdapter", "LoggerProvider", "props", "adapter", "setAdapter", "value", "configure", "fn", "prev", "_$createComponent", "Provider", "children"]
6
6
  }
@@ -15,12 +15,12 @@ export interface StorageAdapter {
15
15
  * 동기화 저장소 Context 값
16
16
  *
17
17
  * @remarks
18
- * - `adapter`: 현재 설정된 StorageAdapter (signal). configure 전에는 undefined
19
- * - `configure`: adapter를 나중에 주입하는 함수
18
+ * - `adapter`: 현재 설정된 StorageAdapter (signal). 기본값은 localStorage 기반 어댑터
19
+ * - `configure`: decorator 함수를 받아 기존 adapter를 감싸서 adapter를 설정하는 함수
20
20
  */
21
21
  export interface SyncStorageContextValue {
22
- adapter: Accessor<StorageAdapter | undefined>;
23
- configure: (adapter: StorageAdapter) => void;
22
+ adapter: Accessor<StorageAdapter>;
23
+ configure: (fn: (origin: StorageAdapter) => StorageAdapter) => void;
24
24
  }
25
25
  /**
26
26
  * 동기화 저장소 Context
@@ -39,8 +39,8 @@ export declare function useSyncStorage(): SyncStorageContextValue | undefined;
39
39
  * 동기화 저장소 Provider
40
40
  *
41
41
  * @remarks
42
- * - prop 없이 사용. adapter는 `useSyncStorage().configure()`로 나중에 주입
43
- * - configure 전에는 useSyncConfig이 localStorage로 fallback
42
+ * - prop 없이 사용. 기본적으로 localStorage 기반 어댑터가 설정됨
43
+ * - `configure()`로 decorator 함수를 전달하여 기존 adapter를 감싸거나 교체 가능
44
44
  *
45
45
  * @example
46
46
  * ```tsx
@@ -48,8 +48,12 @@ export declare function useSyncStorage(): SyncStorageContextValue | undefined;
48
48
  * <App />
49
49
  * </SyncStorageProvider>
50
50
  *
51
- * // 자식 컴포넌트에서 나중에 설정:
52
- * useSyncStorage()!.configure(myStorageAdapter);
51
+ * // 자식 컴포넌트에서 decorator 패턴으로 adapter 커스터마이징:
52
+ * useSyncStorage()!.configure((origin) => ({
53
+ * getItem: (key) => myCustomGetItem(key),
54
+ * setItem: origin.setItem,
55
+ * removeItem: origin.removeItem,
56
+ * }));
53
57
  * ```
54
58
  */
55
59
  export declare const SyncStorageProvider: ParentComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"SyncStorageContext.d.ts","sourceRoot":"","sources":["../../src/providers/SyncStorageContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAIb,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAElB;;;;;;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;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,QAAQ,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC9C,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CAC9C;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,iEAA2C,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,uBAAuB,GAAG,SAAS,CAEpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,EAAE,eASjC,CAAC"}
1
+ {"version":3,"file":"SyncStorageContext.d.ts","sourceRoot":"","sources":["../../src/providers/SyncStorageContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAIb,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAElB;;;;;;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;AAWD;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAClC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,cAAc,KAAK,IAAI,CAAC;CACrE;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,iEAA2C,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,uBAAuB,GAAG,SAAS,CAEpE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mBAAmB,EAAE,eASjC,CAAC"}
@@ -1,14 +1,19 @@
1
1
  import { createComponent as _$createComponent } from "solid-js/web";
2
2
  import { createContext, createSignal, useContext } from "solid-js";
3
+ const defaultStorageAdapter = {
4
+ getItem: (key) => localStorage.getItem(key),
5
+ setItem: (key, value) => localStorage.setItem(key, value),
6
+ removeItem: (key) => localStorage.removeItem(key)
7
+ };
3
8
  const SyncStorageContext = createContext();
4
9
  function useSyncStorage() {
5
10
  return useContext(SyncStorageContext);
6
11
  }
7
12
  const SyncStorageProvider = (props) => {
8
- const [adapter, setAdapter] = createSignal();
13
+ const [adapter, setAdapter] = createSignal(defaultStorageAdapter);
9
14
  const value = {
10
15
  adapter,
11
- configure: (a) => setAdapter(() => a)
16
+ configure: (fn) => setAdapter((prev) => fn(prev))
12
17
  };
13
18
  return _$createComponent(SyncStorageContext.Provider, {
14
19
  value,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/providers/SyncStorageContext.tsx"],
4
- "mappings": ";AAAA,SAEEA,eACAC,cACAC,kBAEK;AAiCA,MAAMC,qBAAqBH,cAAuC;AAOlE,SAASI,iBAAsD;AACpE,SAAOF,WAAWC,kBAAkB;AACtC;AAmBO,MAAME,sBAAwCC,WAAU;AAC7D,QAAM,CAACC,SAASC,UAAU,IAAIP,aAAyC;AAEvE,QAAMQ,QAAiC;IACrCF;IACAG,WAAYC,OAAsBH,WAAW,MAAMG,CAAC;EACtD;AAEA,SAAAC,kBAAQT,mBAAmBU,UAAQ;IAACJ;IAAY,IAAAK,WAAA;AAAA,aAAGR,MAAMQ;IAAQ;EAAA,CAAA;AACnE;",
5
- "names": ["createContext", "createSignal", "useContext", "SyncStorageContext", "useSyncStorage", "SyncStorageProvider", "props", "adapter", "setAdapter", "value", "configure", "a", "_$createComponent", "Provider", "children"]
4
+ "mappings": ";AAAA,SAEEA,eACAC,cACAC,kBAEK;AAkBP,MAAMC,wBAAwC;EAC5CC,SAAUC,SAAQC,aAAaF,QAAQC,GAAG;EAC1CE,SAASA,CAACF,KAAKG,UAAUF,aAAaC,QAAQF,KAAKG,KAAK;EACxDC,YAAaJ,SAAQC,aAAaG,WAAWJ,GAAG;AAClD;AAoBO,MAAMK,qBAAqBV,cAAuC;AAOlE,SAASW,iBAAsD;AACpE,SAAOT,WAAWQ,kBAAkB;AACtC;AAuBO,MAAME,sBAAwCC,WAAU;AAC7D,QAAM,CAACC,SAASC,UAAU,IAAId,aAA6BE,qBAAqB;AAEhF,QAAMK,QAAiC;IACrCM;IACAE,WAAYC,QAAmDF,WAAYG,UAASD,GAAGC,IAAI,CAAC;EAC9F;AAEA,SAAAC,kBAAQT,mBAAmBU,UAAQ;IAACZ;IAAY,IAAAa,WAAA;AAAA,aAAGR,MAAMQ;IAAQ;EAAA,CAAA;AACnE;",
5
+ "names": ["createContext", "createSignal", "useContext", "defaultStorageAdapter", "getItem", "key", "localStorage", "setItem", "value", "removeItem", "SyncStorageContext", "useSyncStorage", "SyncStorageProvider", "props", "adapter", "setAdapter", "configure", "fn", "prev", "_$createComponent", "Provider", "children"]
6
6
  }
@@ -45,8 +45,10 @@ export type SharedDataValue<TSharedData extends Record<string, unknown>> = {
45
45
  wait: () => Promise<void>;
46
46
  /** fetch 진행 중 여부 */
47
47
  busy: Accessor<boolean>;
48
- /** definitions를 설정하여 데이터 구독 시작 */
49
- configure: (definitions: {
48
+ /** definitions를 설정하여 데이터 구독 시작 (decorator 패턴) */
49
+ configure: (fn: (origin: {
50
+ [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]>;
51
+ }) => {
50
52
  [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]>;
51
53
  }) => void;
52
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SharedDataContext.d.ts","sourceRoot":"","sources":["../../../src/providers/shared-data/SharedDataContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAA6B,MAAM,UAAU,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK;IACzC,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjE,uBAAuB;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;IACzC,6BAA6B;IAC7B,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IACtD,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACvC,gBAAgB;IAChB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IACzB,oBAAoB;IACpB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,CAAC;IAC7D,2CAA2C;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACxE,CAAC,IAAI,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAC7D,GAAG;IACF,0BAA0B;IAC1B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,oBAAoB;IACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxB,kCAAkC;IAClC,SAAS,EAAE,CAAC,WAAW,EAAE;SACtB,CAAC,IAAI,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;KAC/D,KAAK,IAAI,CAAC;CACZ,CAAC;AAEF,qBAAqB;AACrB,eAAO,MAAM,iBAAiB,kFAA4D,CAAC;AAE3F;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAClE,eAAe,CAAC,WAAW,CAAC,CAMhC"}
1
+ {"version":3,"file":"SharedDataContext.d.ts","sourceRoot":"","sources":["../../../src/providers/shared-data/SharedDataContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAA6B,MAAM,UAAU,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK;IACzC,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjE,uBAAuB;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;IACzC,6BAA6B;IAC7B,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IACtD,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACvC,gBAAgB;IAChB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IACzB,oBAAoB;IACpB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,CAAC;IAC7D,2CAA2C;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACxE,CAAC,IAAI,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAC7D,GAAG;IACF,0BAA0B;IAC1B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,oBAAoB;IACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxB,iDAAiD;IACjD,SAAS,EAAE,CACT,EAAE,EAAE,CAAC,MAAM,EAAE;SACV,CAAC,IAAI,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;KAC/D,KAAK;SACH,CAAC,IAAI,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;KAC/D,KACE,IAAI,CAAC;CACX,CAAC;AAEF,qBAAqB;AACrB,eAAO,MAAM,iBAAiB,kFAA4D,CAAC;AAE3F;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAClE,eAAe,CAAC,WAAW,CAAC,CAMhC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/providers/shared-data/SharedDataContext.ts"],
4
- "mappings": "AAAA,SAAwB,eAAe,kBAAkB;AAyDlD,MAAM,oBAAoB,cAAwD;AAOlF,SAAS,gBAEkB;AAChC,QAAM,UAAU,WAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0HAAoD;AAAA,EACtE;AACA,SAAO;AACT;",
4
+ "mappings": "AAAA,SAAwB,eAAe,kBAAkB;AA6DlD,MAAM,oBAAoB,cAAwD;AAOlF,SAAS,gBAEkB;AAChC,QAAM,UAAU,WAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0HAAoD;AAAA,EACtE;AACA,SAAO;AACT;",
5
5
  "names": []
6
6
  }
@@ -18,14 +18,14 @@ import { type JSX } from "solid-js";
18
18
  * </SharedDataProvider>
19
19
  *
20
20
  * // 자식 컴포넌트에서 나중에 설정:
21
- * useSharedData().configure({
21
+ * useSharedData().configure(() => ({
22
22
  * users: {
23
23
  * serviceKey: "main",
24
24
  * fetch: async (changeKeys) => fetchUsers(changeKeys),
25
25
  * getKey: (item) => item.id,
26
26
  * orderBy: [[(item) => item.name, "asc"]],
27
27
  * },
28
- * });
28
+ * }));
29
29
  * ```
30
30
  */
31
31
  export declare function SharedDataProvider(props: {
@@ -1 +1 @@
1
- {"version":3,"file":"SharedDataProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/shared-data/SharedDataProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAuC,MAAM,UAAU,CAAC;AAaxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAkKhF"}
1
+ {"version":3,"file":"SharedDataProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/shared-data/SharedDataProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAuC,MAAM,UAAU,CAAC;AAaxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAwKhF"}
@@ -60,11 +60,12 @@ function SharedDataProvider(props) {
60
60
  async function wait() {
61
61
  await waitUntil(() => busyCount() <= 0);
62
62
  }
63
- function configure(definitions) {
63
+ function configure(fn) {
64
64
  if (configured) {
65
65
  throw new Error("SharedDataProvider: configure()\uB294 1\uD68C\uB9CC \uD638\uCD9C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
66
66
  }
67
67
  configured = true;
68
+ const definitions = fn({});
68
69
  currentDefinitions = definitions;
69
70
  for (const [name, def] of Object.entries(definitions)) {
70
71
  const [items, setItems] = createSignal([]);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/providers/shared-data/SharedDataProvider.tsx"],
4
- "mappings": "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",
5
- "names": ["createMemo", "createSignal", "onCleanup", "objEqual", "waitUntil", "SharedDataContext", "SharedDataChangeEvent", "useServiceClient", "useNotification", "useLogger", "SharedDataProvider", "props", "serviceClient", "notification", "logger", "configured", "busyCount", "setBusyCount", "busy", "signalMap", "Map", "memoMap", "listenerKeyMap", "versionMap", "accessors", "currentDefinitions", "ordering", "data", "orderByList", "result", "orderBy", "reverse", "selector", "item", "orderByDesc", "loadData", "name", "def", "changeKeys", "currentVersion", "get", "set", "c", "signal", "Error", "setItems", "resData", "fetch", "prev", "filtered", "filter", "includes", "getKey", "push", "err", "error", "danger", "message", "wait", "configure", "definitions", "Object", "entries", "items", "itemMap", "map", "client", "serviceKey", "addEventListener", "then", "key", "undefined", "emit", "emitToServer", "info", "listenerKey", "removeEventListener", "KNOWN_KEYS", "Set", "contextValue", "Proxy", "target", "prop", "has", "_$createComponent", "Provider", "value", "children"]
4
+ "mappings": "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",
5
+ "names": ["createMemo", "createSignal", "onCleanup", "objEqual", "waitUntil", "SharedDataContext", "SharedDataChangeEvent", "useServiceClient", "useNotification", "useLogger", "SharedDataProvider", "props", "serviceClient", "notification", "logger", "configured", "busyCount", "setBusyCount", "busy", "signalMap", "Map", "memoMap", "listenerKeyMap", "versionMap", "accessors", "currentDefinitions", "ordering", "data", "orderByList", "result", "orderBy", "reverse", "selector", "item", "orderByDesc", "loadData", "name", "def", "changeKeys", "currentVersion", "get", "set", "c", "signal", "Error", "setItems", "resData", "fetch", "prev", "filtered", "filter", "includes", "getKey", "push", "err", "error", "danger", "message", "wait", "configure", "fn", "definitions", "Object", "entries", "items", "itemMap", "map", "client", "serviceKey", "addEventListener", "then", "key", "undefined", "emit", "emitToServer", "info", "listenerKey", "removeEventListener", "KNOWN_KEYS", "Set", "contextValue", "Proxy", "target", "prop", "has", "_$createComponent", "Provider", "value", "children"]
6
6
  }
@@ -210,19 +210,15 @@ function MyPage() {
210
210
  |--------|-----------|-------------|
211
211
  | `close` | `(result?: T) => void` | Close dialog with optional return value |
212
212
 
213
- **DialogProvider:**
213
+ **Dialog Defaults:**
214
214
 
215
- `DialogProvider` is the provider component that enables `useDialog`. Use it in your provider tree to enable programmatic dialogs.
215
+ `DialogDefaultsContext` and `DialogDefaults` are exported for advanced use cases such as providing default dialog options to a subtree. `InitializeProvider` already sets up the dialog system internally — most apps do not need these directly.
216
216
 
217
- ```tsx
218
- import { DialogProvider } from "@simplysm/solid";
219
-
220
- <DialogProvider closeOnEscape closeOnBackdrop>
221
- <App />
222
- </DialogProvider>
217
+ ```typescript
218
+ import { DialogDefaultsContext, type DialogDefaults } from "@simplysm/solid";
223
219
  ```
224
220
 
225
- | Prop | Type | Default | Description |
226
- |------|------|---------|-------------|
227
- | `closeOnEscape` | `boolean` | - | Default `closeOnEscape` for all dialogs opened via `useDialog` |
228
- | `closeOnBackdrop` | `boolean` | - | Default `closeOnBackdrop` for all dialogs opened via `useDialog` |
221
+ | Export | Kind | Description |
222
+ |--------|------|-------------|
223
+ | `DialogDefaultsContext` | context | Context for providing default dialog options |
224
+ | `DialogDefaults` | interface | `{ closeOnEscape?: boolean; closeOnBackdrop?: boolean }` |
@@ -579,7 +579,7 @@ import { ColorPicker } from "@simplysm/solid";
579
579
  |------|------|---------|-------------|
580
580
  | `value` | `string` | `"#000000"` | Color value (#RRGGBB format) |
581
581
  | `onValueChange` | `(value: string) => void` | - | Value change callback |
582
- | `size` | `"sm" \| "lg" \| "xl"` | - | Size |
582
+ | `size` | `"sm" \| "lg"` | - | Size |
583
583
  | `disabled` | `boolean` | - | Disabled state |
584
584
  | `required` | `boolean` | - | Required field (error: "필수 입력 항목입니다") |
585
585
  | `validate` | `(value: string \| undefined) => string \| undefined` | - | Custom validation function |
package/docs/hooks.md CHANGED
@@ -82,6 +82,21 @@ logger.warn("deprecation notice");
82
82
  | `warn` | `(...args: unknown[]) => void` | Log message (warning) |
83
83
  | `error` | `(...args: unknown[]) => void` | Log message (error) |
84
84
 
85
+ **Configuring a custom adapter (decorator pattern):**
86
+
87
+ ```tsx
88
+ // Replace default consola adapter
89
+ useLogger().configure((origin) => myLogAdapter);
90
+
91
+ // Wrap default adapter (chaining)
92
+ useLogger().configure((origin) => ({
93
+ write(severity, ...data) {
94
+ sendToServer(severity, ...data);
95
+ origin.write(severity, ...data); // also log to consola
96
+ },
97
+ }));
98
+ ```
99
+
85
100
  **Global error capturing:** `ErrorLoggerProvider` captures uncaught errors (`window.onerror`) and unhandled promise rejections (`unhandledrejection`) and logs them via `useLogger`.
86
101
 
87
102
  ---
package/docs/layout.md CHANGED
@@ -67,14 +67,28 @@ interface SidebarMenuItem {
67
67
  }
68
68
  ```
69
69
 
70
- **useSidebarContext hook:**
70
+ **useSidebarContext / useSidebarContextOptional hooks:**
71
71
 
72
72
  ```tsx
73
- import { useSidebarContext } from "@simplysm/solid";
73
+ import { useSidebarContext, useSidebarContextOptional } from "@simplysm/solid";
74
74
 
75
+ // Throws if not inside Sidebar.Container
75
76
  const sidebar = useSidebarContext();
76
77
  sidebar.toggle(); // current open/closed state
77
78
  sidebar.setToggle(false); // programmatically close
79
+
80
+ // Returns undefined if not inside Sidebar.Container (no error)
81
+ const sidebarOpt = useSidebarContextOptional();
82
+ ```
83
+
84
+ **SM_MEDIA_QUERY constant:**
85
+
86
+ Exported media query string matching the Tailwind `sm:` breakpoint (640px). Use this to align custom responsive logic with sidebar behavior.
87
+
88
+ ```typescript
89
+ import { SM_MEDIA_QUERY } from "@simplysm/solid";
90
+
91
+ const mql = window.matchMedia(SM_MEDIA_QUERY); // "(min-width: 640px)"
78
92
  ```
79
93
 
80
94
  ---
package/docs/providers.md CHANGED
@@ -20,9 +20,9 @@ function AppRoot() {
20
20
 
21
21
  onMount(async () => {
22
22
  await serviceClient.connect("main", { port: 3000 });
23
- useSyncStorage()!.configure(myStorageAdapter);
24
- useLogger().configure(myLogAdapter);
25
- useSharedData().configure(definitions);
23
+ useSyncStorage()!.configure((origin) => myStorageAdapter);
24
+ useLogger().configure((origin) => myLogAdapter);
25
+ useSharedData().configure((origin) => definitions);
26
26
  });
27
27
  }
28
28
  ```
@@ -124,7 +124,7 @@ interface SharedDataDefinition<TData> {
124
124
  |-----------------|------|-------------|
125
125
  | `wait` | `() => Promise<void>` | Wait until all initial fetches complete |
126
126
  | `busy` | `Accessor<boolean>` | True while any fetch is in progress |
127
- | `configure` | `(definitions) => void` | Set up data subscriptions (call once after service client connects) |
127
+ | `configure` | `(fn: (origin) => definitions) => void` | Set up data subscriptions via decorator function (call once after service client connects) |
128
128
 
129
129
  **SharedDataChangeEvent:**
130
130
 
package/docs/styling.md CHANGED
@@ -76,8 +76,9 @@ const className = twMerge(baseClass, props.class);
76
76
 
77
77
  ```typescript
78
78
  import {
79
- type ComponentSize, // "sm" | "lg" | "xl"
80
- type SemanticTheme, // "primary" | "info" | "success" | "warning" | "danger" | "base"
79
+ type ComponentSize, // "sm" | "lg" | "xl"
80
+ type ComponentSizeCompact, // "sm" | "lg" (used by ColorPicker, Progress)
81
+ type SemanticTheme, // "primary" | "info" | "success" | "warning" | "danger" | "base"
81
82
  borderDefault, // Tailwind classes for default border color
82
83
  borderSubtle, // Tailwind classes for subtle border color
83
84
  bgSurface, // Tailwind classes for surface background
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/solid",
3
- "version": "13.0.35",
3
+ "version": "13.0.37",
4
4
  "description": "심플리즘 패키지 - SolidJS 라이브러리",
5
5
  "author": "김석래",
6
6
  "license": "Apache-2.0",
@@ -49,8 +49,8 @@
49
49
  "solid-tiptap": "^0.8.0",
50
50
  "tailwind-merge": "^3.5.0",
51
51
  "tailwindcss": "^3.4.19",
52
- "@simplysm/core-browser": "13.0.35",
53
- "@simplysm/core-common": "13.0.35"
52
+ "@simplysm/core-browser": "13.0.37",
53
+ "@simplysm/core-common": "13.0.37"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@solidjs/testing-library": "^0.8.10"
@@ -9,7 +9,7 @@ export interface Logger {
9
9
  warn: (...args: unknown[]) => void;
10
10
  error: (...args: unknown[]) => void;
11
11
  /** LogAdapter를 나중에 주입. LoggerProvider 내부에서만 사용 가능 */
12
- configure: (adapter: LogAdapter) => void;
12
+ configure: (fn: (origin: LogAdapter) => LogAdapter) => void;
13
13
  }
14
14
 
15
15
  export function useLogger(): Logger {
@@ -32,11 +32,11 @@ export function useLogger(): Logger {
32
32
  info: createLogFunction("info"),
33
33
  warn: createLogFunction("warn"),
34
34
  error: createLogFunction("error"),
35
- configure: (adapter: LogAdapter) => {
35
+ configure: (fn: (origin: LogAdapter) => LogAdapter) => {
36
36
  if (!loggerCtx) {
37
37
  throw new Error("configure()는 LoggerProvider 내부에서만 사용할 수 있습니다");
38
38
  }
39
- loggerCtx.configure(adapter);
39
+ loggerCtx.configure(fn);
40
40
  },
41
41
  };
42
42
  }
@@ -34,9 +34,9 @@ export type { BusyVariant };
34
34
  * const serviceClient = useServiceClient();
35
35
  * onMount(async () => {
36
36
  * await serviceClient.connect("main", { port: 3000 });
37
- * useSyncStorage()!.configure(myStorageAdapter);
38
- * useLogger().configure(myLogAdapter);
39
- * useSharedData().configure(definitions);
37
+ * useSyncStorage()!.configure((origin) => myStorageAdapter);
38
+ * useLogger().configure((origin) => myLogAdapter);
39
+ * useSharedData().configure((origin) => definitions);
40
40
  * });
41
41
  * }
42
42
  * ```
@@ -5,6 +5,7 @@ import {
5
5
  useContext,
6
6
  type ParentComponent,
7
7
  } from "solid-js";
8
+ import { consola } from "consola";
8
9
 
9
10
  /**
10
11
  * 로그 어댑터 인터페이스
@@ -17,23 +18,27 @@ export interface LogAdapter {
17
18
  write(severity: "error" | "warn" | "info" | "log", ...data: any[]): Promise<void> | void;
18
19
  }
19
20
 
21
+ const defaultLogAdapter: LogAdapter = {
22
+ write: (severity, ...data) => (consola as any)[severity](...data),
23
+ };
24
+
20
25
  /**
21
26
  * 로그 어댑터 Context 값
22
27
  *
23
28
  * @remarks
24
- * - `adapter`: 현재 설정된 LogAdapter (signal). configure 전에는 undefined
25
- * - `configure`: adapter를 나중에 주입하는 함수
29
+ * - `adapter`: 현재 설정된 LogAdapter (signal). 기본값은 consola 기반 adapter
30
+ * - `configure`: decorator function으로 adapter를 설정/체이닝하는 함수
26
31
  */
27
32
  export interface LoggerContextValue {
28
- adapter: Accessor<LogAdapter | undefined>;
29
- configure: (adapter: LogAdapter) => void;
33
+ adapter: Accessor<LogAdapter>;
34
+ configure: (fn: (origin: LogAdapter) => LogAdapter) => void;
30
35
  }
31
36
 
32
37
  /**
33
38
  * 로그 어댑터 Context
34
39
  *
35
40
  * @remarks
36
- * Provider가 없으면 `undefined` (useLogger에서 consola fallback)
41
+ * Provider가 없으면 `undefined` (useLogger에서 consola 기본 adapter 사용)
37
42
  */
38
43
  export const LoggerContext = createContext<LoggerContextValue>();
39
44
 
@@ -51,7 +56,8 @@ export function useLogAdapter(): LoggerContextValue | undefined {
51
56
  *
52
57
  * @remarks
53
58
  * - prop 없이 사용. adapter는 `useLogger().configure()`로 나중에 주입
54
- * - configure 전에는 useLogger가 consola로 fallback
59
+ * - 기본값은 consola 기반 adapter
60
+ * - configure는 decorator function을 받아 기존 adapter를 감싸거나 교체
55
61
  *
56
62
  * @example
57
63
  * ```tsx
@@ -59,16 +65,21 @@ export function useLogAdapter(): LoggerContextValue | undefined {
59
65
  * <App />
60
66
  * </LoggerProvider>
61
67
  *
62
- * // 자식 컴포넌트에서 나중에 설정:
63
- * useLogger().configure(myLogAdapter);
68
+ * // 자식 컴포넌트에서 decorator로 설정:
69
+ * useLogger().configure((origin) => ({
70
+ * write: (...args) => {
71
+ * origin.write(...args);
72
+ * sendToServer(...args);
73
+ * },
74
+ * }));
64
75
  * ```
65
76
  */
66
77
  export const LoggerProvider: ParentComponent = (props) => {
67
- const [adapter, setAdapter] = createSignal<LogAdapter | undefined>();
78
+ const [adapter, setAdapter] = createSignal<LogAdapter>(defaultLogAdapter);
68
79
 
69
80
  const value: LoggerContextValue = {
70
81
  adapter,
71
- configure: (a: LogAdapter) => setAdapter(() => a),
82
+ configure: (fn: (origin: LogAdapter) => LogAdapter) => setAdapter((prev) => fn(prev)),
72
83
  };
73
84
 
74
85
  return <LoggerContext.Provider value={value}>{props.children}</LoggerContext.Provider>;
@@ -19,16 +19,25 @@ export interface StorageAdapter {
19
19
  removeItem(key: string): void | Promise<void>;
20
20
  }
21
21
 
22
+ /**
23
+ * 기본 localStorage 기반 어댑터
24
+ */
25
+ const defaultStorageAdapter: StorageAdapter = {
26
+ getItem: (key) => localStorage.getItem(key),
27
+ setItem: (key, value) => localStorage.setItem(key, value),
28
+ removeItem: (key) => localStorage.removeItem(key),
29
+ };
30
+
22
31
  /**
23
32
  * 동기화 저장소 Context 값
24
33
  *
25
34
  * @remarks
26
- * - `adapter`: 현재 설정된 StorageAdapter (signal). configure 전에는 undefined
27
- * - `configure`: adapter를 나중에 주입하는 함수
35
+ * - `adapter`: 현재 설정된 StorageAdapter (signal). 기본값은 localStorage 기반 어댑터
36
+ * - `configure`: decorator 함수를 받아 기존 adapter를 감싸서 adapter를 설정하는 함수
28
37
  */
29
38
  export interface SyncStorageContextValue {
30
- adapter: Accessor<StorageAdapter | undefined>;
31
- configure: (adapter: StorageAdapter) => void;
39
+ adapter: Accessor<StorageAdapter>;
40
+ configure: (fn: (origin: StorageAdapter) => StorageAdapter) => void;
32
41
  }
33
42
 
34
43
  /**
@@ -52,8 +61,8 @@ export function useSyncStorage(): SyncStorageContextValue | undefined {
52
61
  * 동기화 저장소 Provider
53
62
  *
54
63
  * @remarks
55
- * - prop 없이 사용. adapter는 `useSyncStorage().configure()`로 나중에 주입
56
- * - configure 전에는 useSyncConfig이 localStorage로 fallback
64
+ * - prop 없이 사용. 기본적으로 localStorage 기반 어댑터가 설정됨
65
+ * - `configure()`로 decorator 함수를 전달하여 기존 adapter를 감싸거나 교체 가능
57
66
  *
58
67
  * @example
59
68
  * ```tsx
@@ -61,16 +70,20 @@ export function useSyncStorage(): SyncStorageContextValue | undefined {
61
70
  * <App />
62
71
  * </SyncStorageProvider>
63
72
  *
64
- * // 자식 컴포넌트에서 나중에 설정:
65
- * useSyncStorage()!.configure(myStorageAdapter);
73
+ * // 자식 컴포넌트에서 decorator 패턴으로 adapter 커스터마이징:
74
+ * useSyncStorage()!.configure((origin) => ({
75
+ * getItem: (key) => myCustomGetItem(key),
76
+ * setItem: origin.setItem,
77
+ * removeItem: origin.removeItem,
78
+ * }));
66
79
  * ```
67
80
  */
68
81
  export const SyncStorageProvider: ParentComponent = (props) => {
69
- const [adapter, setAdapter] = createSignal<StorageAdapter | undefined>();
82
+ const [adapter, setAdapter] = createSignal<StorageAdapter>(defaultStorageAdapter);
70
83
 
71
84
  const value: SyncStorageContextValue = {
72
85
  adapter,
73
- configure: (a: StorageAdapter) => setAdapter(() => a),
86
+ configure: (fn: (origin: StorageAdapter) => StorageAdapter) => setAdapter((prev) => fn(prev)),
74
87
  };
75
88
 
76
89
  return <SyncStorageContext.Provider value={value}>{props.children}</SyncStorageContext.Provider>;
@@ -48,10 +48,14 @@ export type SharedDataValue<TSharedData extends Record<string, unknown>> = {
48
48
  wait: () => Promise<void>;
49
49
  /** fetch 진행 중 여부 */
50
50
  busy: Accessor<boolean>;
51
- /** definitions를 설정하여 데이터 구독 시작 */
52
- configure: (definitions: {
53
- [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]>;
54
- }) => void;
51
+ /** definitions를 설정하여 데이터 구독 시작 (decorator 패턴) */
52
+ configure: (
53
+ fn: (origin: {
54
+ [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]>;
55
+ }) => {
56
+ [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]>;
57
+ },
58
+ ) => void;
55
59
  };
56
60
 
57
61
  /** 공유 데이터 Context */
@@ -30,14 +30,14 @@ import { useLogger } from "../../hooks/useLogger";
30
30
  * </SharedDataProvider>
31
31
  *
32
32
  * // 자식 컴포넌트에서 나중에 설정:
33
- * useSharedData().configure({
33
+ * useSharedData().configure(() => ({
34
34
  * users: {
35
35
  * serviceKey: "main",
36
36
  * fetch: async (changeKeys) => fetchUsers(changeKeys),
37
37
  * getKey: (item) => item.id,
38
38
  * orderBy: [[(item) => item.name, "asc"]],
39
39
  * },
40
- * });
40
+ * }));
41
41
  * ```
42
42
  */
43
43
  export function SharedDataProvider(props: { children: JSX.Element }): JSX.Element {
@@ -115,11 +115,17 @@ export function SharedDataProvider(props: { children: JSX.Element }): JSX.Elemen
115
115
  await waitUntil(() => busyCount() <= 0);
116
116
  }
117
117
 
118
- function configure(definitions: Record<string, SharedDataDefinition<unknown>>): void {
118
+ function configure(
119
+ fn: (
120
+ origin: Record<string, SharedDataDefinition<unknown>>,
121
+ ) => Record<string, SharedDataDefinition<unknown>>,
122
+ ): void {
119
123
  if (configured) {
120
124
  throw new Error("SharedDataProvider: configure()는 1회만 호출할 수 있습니다");
121
125
  }
122
126
  configured = true;
127
+
128
+ const definitions = fn({});
123
129
  currentDefinitions = definitions;
124
130
 
125
131
  for (const [name, def] of Object.entries(definitions)) {