@simplysm/solid 13.0.34 → 13.0.35
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.
- package/README.md +22 -42
- package/dist/components/disclosure/DialogContext.d.ts +29 -0
- package/dist/components/disclosure/DialogContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogContext.js.map +1 -1
- package/dist/components/disclosure/DialogInstanceContext.d.ts +14 -0
- package/dist/components/disclosure/DialogInstanceContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogInstanceContext.js.map +1 -1
- package/dist/components/feedback/busy/BusyContext.d.ts +18 -0
- package/dist/components/feedback/busy/BusyContext.d.ts.map +1 -1
- package/dist/components/feedback/busy/BusyContext.js.map +1 -1
- package/dist/components/feedback/busy/BusyProvider.d.ts +10 -0
- package/dist/components/feedback/busy/BusyProvider.d.ts.map +1 -1
- package/dist/components/feedback/busy/BusyProvider.js.map +1 -1
- package/dist/components/feedback/notification/NotificationContext.d.ts +29 -0
- package/dist/components/feedback/notification/NotificationContext.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationContext.js.map +1 -1
- package/dist/components/feedback/notification/NotificationProvider.d.ts +9 -0
- package/dist/components/feedback/notification/NotificationProvider.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationProvider.js.map +1 -1
- package/dist/hooks/useLogger.d.ts +4 -2
- package/dist/hooks/useLogger.d.ts.map +1 -1
- package/dist/hooks/useLogger.js +11 -4
- package/dist/hooks/useLogger.js.map +1 -1
- package/dist/hooks/useSyncConfig.d.ts +2 -0
- package/dist/hooks/useSyncConfig.d.ts.map +1 -1
- package/dist/hooks/useSyncConfig.js +30 -26
- package/dist/hooks/useSyncConfig.js.map +1 -1
- package/dist/index.d.ts +8 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -15
- package/dist/index.js.map +1 -1
- package/dist/providers/InitializeProvider.d.ts +33 -0
- package/dist/providers/InitializeProvider.d.ts.map +1 -0
- package/dist/providers/InitializeProvider.js +75 -0
- package/dist/providers/InitializeProvider.js.map +6 -0
- package/dist/providers/LoggerContext.d.ts +24 -8
- package/dist/providers/LoggerContext.d.ts.map +1 -1
- package/dist/providers/LoggerContext.js +13 -13
- package/dist/providers/LoggerContext.js.map +2 -2
- package/dist/providers/ServiceClientContext.d.ts +13 -0
- package/dist/providers/ServiceClientContext.d.ts.map +1 -1
- package/dist/providers/ServiceClientContext.js.map +1 -1
- package/dist/providers/ServiceClientProvider.d.ts +21 -0
- package/dist/providers/ServiceClientProvider.d.ts.map +1 -1
- package/dist/providers/ServiceClientProvider.js.map +1 -1
- package/dist/providers/SyncStorageContext.d.ts +25 -11
- package/dist/providers/SyncStorageContext.d.ts.map +1 -1
- package/dist/providers/SyncStorageContext.js +13 -13
- package/dist/providers/SyncStorageContext.js.map +2 -2
- package/dist/providers/shared-data/SharedDataChangeEvent.d.ts +8 -0
- package/dist/providers/shared-data/SharedDataChangeEvent.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataChangeEvent.js.map +1 -1
- package/dist/providers/shared-data/SharedDataContext.d.ts +39 -0
- package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataContext.js +1 -3
- package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.d.ts +30 -5
- package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.js +59 -38
- package/dist/providers/shared-data/SharedDataProvider.js.map +2 -2
- package/docs/providers.md +70 -195
- package/package.json +3 -3
- package/src/components/disclosure/DialogContext.ts +29 -0
- package/src/components/disclosure/DialogInstanceContext.ts +14 -0
- package/src/components/feedback/busy/BusyContext.ts +18 -0
- package/src/components/feedback/busy/BusyProvider.tsx +10 -0
- package/src/components/feedback/notification/NotificationContext.ts +29 -0
- package/src/components/feedback/notification/NotificationProvider.tsx +9 -0
- package/src/hooks/useLogger.ts +14 -4
- package/src/hooks/useSyncConfig.ts +42 -35
- package/src/index.ts +34 -14
- package/src/providers/InitializeProvider.tsx +74 -0
- package/src/providers/LoggerContext.tsx +39 -10
- package/src/providers/ServiceClientContext.ts +13 -0
- package/src/providers/ServiceClientProvider.tsx +21 -0
- package/src/providers/SyncStorageContext.tsx +40 -15
- package/src/providers/shared-data/SharedDataChangeEvent.ts +8 -0
- package/src/providers/shared-data/SharedDataContext.ts +40 -3
- package/src/providers/shared-data/SharedDataProvider.tsx +102 -54
|
@@ -1,22 +1,61 @@
|
|
|
1
1
|
import { type Accessor } from "solid-js";
|
|
2
|
+
/**
|
|
3
|
+
* 공유 데이터 정의
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* SharedDataProvider에 전달하여 서버 데이터 구독을 설정한다.
|
|
7
|
+
*/
|
|
2
8
|
export interface SharedDataDefinition<TData> {
|
|
9
|
+
/** 서비스 연결 key (useServiceClient의 connect key와 동일) */
|
|
3
10
|
serviceKey: string;
|
|
11
|
+
/** 데이터 조회 함수 (changeKeys가 있으면 해당 항목만 부분 갱신) */
|
|
4
12
|
fetch: (changeKeys?: Array<string | number>) => Promise<TData[]>;
|
|
13
|
+
/** 항목의 고유 key 추출 함수 */
|
|
5
14
|
getKey: (item: TData) => string | number;
|
|
15
|
+
/** 정렬 기준 배열 (여러 기준 적용 가능) */
|
|
6
16
|
orderBy: [(item: TData) => unknown, "asc" | "desc"][];
|
|
17
|
+
/** 서버 이벤트 필터 (같은 name의 이벤트 중 filter가 일치하는 것만 수신) */
|
|
7
18
|
filter?: unknown;
|
|
8
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* 공유 데이터 접근자
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* 각 데이터 key에 대한 반응형 접근 및 변경 알림을 제공한다.
|
|
25
|
+
*/
|
|
9
26
|
export interface SharedDataAccessor<TData> {
|
|
27
|
+
/** 반응형 항목 배열 */
|
|
10
28
|
items: Accessor<TData[]>;
|
|
29
|
+
/** key로 단일 항목 조회 */
|
|
11
30
|
get: (key: string | number | undefined) => TData | undefined;
|
|
31
|
+
/** 서버에 변경 이벤트 전파 (모든 구독자에게 refetch 트리거) */
|
|
12
32
|
emit: (changeKeys?: Array<string | number>) => Promise<void>;
|
|
13
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* 공유 데이터 Context 값
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* - configure 호출 전: wait, busy, configure만 접근 가능. 데이터 접근 시 throw
|
|
39
|
+
* - configure 호출 후: 각 데이터 key별 SharedDataAccessor와 전체 상태 관리 메서드 포함
|
|
40
|
+
*/
|
|
14
41
|
export type SharedDataValue<TSharedData extends Record<string, unknown>> = {
|
|
15
42
|
[K in keyof TSharedData]: SharedDataAccessor<TSharedData[K]>;
|
|
16
43
|
} & {
|
|
44
|
+
/** 모든 초기 fetch 완료까지 대기 */
|
|
17
45
|
wait: () => Promise<void>;
|
|
46
|
+
/** fetch 진행 중 여부 */
|
|
18
47
|
busy: Accessor<boolean>;
|
|
48
|
+
/** definitions를 설정하여 데이터 구독 시작 */
|
|
49
|
+
configure: (definitions: {
|
|
50
|
+
[K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]>;
|
|
51
|
+
}) => void;
|
|
19
52
|
};
|
|
53
|
+
/** 공유 데이터 Context */
|
|
20
54
|
export declare const SharedDataContext: import("solid-js").Context<SharedDataValue<Record<string, unknown>> | undefined>;
|
|
55
|
+
/**
|
|
56
|
+
* 공유 데이터에 접근하는 훅
|
|
57
|
+
*
|
|
58
|
+
* @throws SharedDataProvider가 없으면 에러 발생
|
|
59
|
+
*/
|
|
21
60
|
export declare function useSharedData<TSharedData extends Record<string, unknown> = Record<string, unknown>>(): SharedDataValue<TSharedData>;
|
|
22
61
|
//# sourceMappingURL=SharedDataContext.d.ts.map
|
|
@@ -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,MAAM,WAAW,oBAAoB,CAAC,KAAK;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACvC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IACzB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,CAAC;IAC7D,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED,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,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;
|
|
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"}
|
|
@@ -3,9 +3,7 @@ const SharedDataContext = createContext();
|
|
|
3
3
|
function useSharedData() {
|
|
4
4
|
const context = useContext(SharedDataContext);
|
|
5
5
|
if (!context) {
|
|
6
|
-
throw new Error(
|
|
7
|
-
"useSharedData\uB294 SharedDataProvider \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. SharedDataProvider\uB294 ServiceClientProvider \uC544\uB798\uC5D0 \uC704\uCE58\uD574\uC57C \uD569\uB2C8\uB2E4"
|
|
8
|
-
);
|
|
6
|
+
throw new Error("useSharedData\uB294 SharedDataProvider \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/shared-data/SharedDataContext.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAwB,eAAe,kBAAkB;
|
|
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;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
/**
|
|
3
|
+
* 공유 데이터 Provider
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* - ServiceClientProvider와 NotificationProvider 내부에서 사용해야 함
|
|
7
|
+
* - LoggerProvider가 있으면 fetch 실패를 로거에도 기록
|
|
8
|
+
* - configure() 호출 전: wait, busy, configure만 접근 가능. 데이터 접근 시 throw
|
|
9
|
+
* - configure() 호출 후: definitions의 각 key마다 서버 이벤트 리스너를 등록하여 실시간 동기화
|
|
10
|
+
* - 동시 fetch 호출 시 version counter로 데이터 역전 방지
|
|
11
|
+
* - fetch 실패 시 사용자에게 danger 알림 표시
|
|
12
|
+
* - cleanup 시 모든 이벤트 리스너 자동 해제
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <SharedDataProvider>
|
|
17
|
+
* <App />
|
|
18
|
+
* </SharedDataProvider>
|
|
19
|
+
*
|
|
20
|
+
* // 자식 컴포넌트에서 나중에 설정:
|
|
21
|
+
* useSharedData().configure({
|
|
22
|
+
* users: {
|
|
23
|
+
* serviceKey: "main",
|
|
24
|
+
* fetch: async (changeKeys) => fetchUsers(changeKeys),
|
|
25
|
+
* getKey: (item) => item.id,
|
|
26
|
+
* orderBy: [[(item) => item.name, "asc"]],
|
|
27
|
+
* },
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function SharedDataProvider(props: {
|
|
7
32
|
children: JSX.Element;
|
|
8
33
|
}): JSX.Element;
|
|
9
34
|
//# sourceMappingURL=SharedDataProvider.d.ts.map
|
|
@@ -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;
|
|
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"}
|
|
@@ -10,12 +10,15 @@ function SharedDataProvider(props) {
|
|
|
10
10
|
const serviceClient = useServiceClient();
|
|
11
11
|
const notification = useNotification();
|
|
12
12
|
const logger = useLogger();
|
|
13
|
+
let configured = false;
|
|
13
14
|
const [busyCount, setBusyCount] = createSignal(0);
|
|
14
15
|
const busy = () => busyCount() > 0;
|
|
15
16
|
const signalMap = /* @__PURE__ */ new Map();
|
|
16
17
|
const memoMap = /* @__PURE__ */ new Map();
|
|
17
18
|
const listenerKeyMap = /* @__PURE__ */ new Map();
|
|
18
19
|
const versionMap = /* @__PURE__ */ new Map();
|
|
20
|
+
const accessors = {};
|
|
21
|
+
let currentDefinitions;
|
|
19
22
|
function ordering(data, orderByList) {
|
|
20
23
|
let result = [...data];
|
|
21
24
|
for (const orderBy of [...orderByList].reverse()) {
|
|
@@ -57,54 +60,72 @@ function SharedDataProvider(props) {
|
|
|
57
60
|
async function wait() {
|
|
58
61
|
await waitUntil(() => busyCount() <= 0);
|
|
59
62
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
63
|
+
function configure(definitions) {
|
|
64
|
+
if (configured) {
|
|
65
|
+
throw new Error("SharedDataProvider: configure()\uB294 1\uD68C\uB9CC \uD638\uCD9C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
66
|
+
}
|
|
67
|
+
configured = true;
|
|
68
|
+
currentDefinitions = definitions;
|
|
69
|
+
for (const [name, def] of Object.entries(definitions)) {
|
|
70
|
+
const [items, setItems] = createSignal([]);
|
|
71
|
+
signalMap.set(name, [items, setItems]);
|
|
72
|
+
const itemMap = createMemo(() => {
|
|
73
|
+
const map = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const item of items()) {
|
|
75
|
+
map.set(def.getKey(item), item);
|
|
76
|
+
}
|
|
77
|
+
return map;
|
|
78
|
+
});
|
|
79
|
+
memoMap.set(name, itemMap);
|
|
80
|
+
const client = serviceClient.get(def.serviceKey);
|
|
81
|
+
void client.addEventListener(SharedDataChangeEvent, {
|
|
82
|
+
name,
|
|
83
|
+
filter: def.filter
|
|
84
|
+
}, async (changeKeys) => {
|
|
85
|
+
await loadData(name, def, changeKeys);
|
|
86
|
+
}).then((key) => {
|
|
87
|
+
listenerKeyMap.set(name, key);
|
|
88
|
+
});
|
|
89
|
+
void loadData(name, def);
|
|
90
|
+
accessors[name] = {
|
|
91
|
+
items,
|
|
92
|
+
get: (key) => {
|
|
93
|
+
if (key === void 0) return void 0;
|
|
94
|
+
return itemMap().get(key);
|
|
95
|
+
},
|
|
96
|
+
emit: async (changeKeys) => {
|
|
97
|
+
await client.emitToServer(SharedDataChangeEvent, (info) => info.name === name && objEqual(info.filter, def.filter), changeKeys);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
92
101
|
}
|
|
93
102
|
onCleanup(() => {
|
|
94
|
-
|
|
103
|
+
if (!currentDefinitions) return;
|
|
104
|
+
for (const [name] of Object.entries(currentDefinitions)) {
|
|
95
105
|
const listenerKey = listenerKeyMap.get(name);
|
|
96
106
|
if (listenerKey != null) {
|
|
97
|
-
const def =
|
|
107
|
+
const def = currentDefinitions[name];
|
|
98
108
|
const client = serviceClient.get(def.serviceKey);
|
|
99
109
|
void client.removeEventListener(listenerKey);
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
112
|
});
|
|
103
|
-
const
|
|
104
|
-
|
|
113
|
+
const KNOWN_KEYS = /* @__PURE__ */ new Set(["wait", "busy", "configure"]);
|
|
114
|
+
const contextValue = new Proxy({
|
|
105
115
|
wait,
|
|
106
|
-
busy
|
|
107
|
-
|
|
116
|
+
busy,
|
|
117
|
+
configure
|
|
118
|
+
}, {
|
|
119
|
+
get(target, prop) {
|
|
120
|
+
if (KNOWN_KEYS.has(prop)) {
|
|
121
|
+
return target[prop];
|
|
122
|
+
}
|
|
123
|
+
if (!configured) {
|
|
124
|
+
throw new Error("SharedDataProvider: configure()\uB97C \uBA3C\uC800 \uD638\uCD9C\uD574\uC57C \uD569\uB2C8\uB2E4");
|
|
125
|
+
}
|
|
126
|
+
return accessors[prop];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
108
129
|
return _$createComponent(SharedDataContext.Provider, {
|
|
109
130
|
value: contextValue,
|
|
110
131
|
get children() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/providers/shared-data/SharedDataProvider.tsx"],
|
|
4
|
-
"mappings": ";AAAA,SAAkCA,YAAYC,cAAcC,iBAAiB;AAC7E,SAASC,UAAUC,iBAAiB;AACpC,SACEC,yBAIK;AACP,SAASC,6BAA6B;AACtC,SAASC,wBAAwB;AACjC,SAASC,uBAAuB;AAChC,SAASC,iBAAiB;
|
|
5
|
-
"names": ["createMemo", "createSignal", "onCleanup", "objEqual", "waitUntil", "SharedDataContext", "SharedDataChangeEvent", "useServiceClient", "useNotification", "useLogger", "SharedDataProvider", "props", "serviceClient", "notification", "logger", "busyCount", "setBusyCount", "busy", "signalMap", "Map", "memoMap", "listenerKeyMap", "versionMap", "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", "
|
|
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"]
|
|
6
6
|
}
|
package/docs/providers.md
CHANGED
|
@@ -1,212 +1,103 @@
|
|
|
1
1
|
# Providers
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## InitializeProvider
|
|
4
4
|
|
|
5
|
-
|
|
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.
|
|
5
|
+
The only exported provider component. Wraps all internal providers in the correct dependency order. Use this to set up your app.
|
|
29
6
|
|
|
30
7
|
```tsx
|
|
31
|
-
|
|
32
|
-
{/* app content */}
|
|
33
|
-
</ConfigProvider>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
| Prop | Type | Description |
|
|
37
|
-
|------|------|-------------|
|
|
38
|
-
| `clientName` | `string` | Client identifier (used as storage key prefix) |
|
|
8
|
+
import { InitializeProvider } from "@simplysm/solid";
|
|
39
9
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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>
|
|
10
|
+
<InitializeProvider clientName="my-app">
|
|
11
|
+
<AppRoot />
|
|
12
|
+
</InitializeProvider>
|
|
50
13
|
```
|
|
51
14
|
|
|
52
|
-
|
|
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`.
|
|
15
|
+
Configuration is done via hooks inside child components:
|
|
61
16
|
|
|
62
17
|
```tsx
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
</LoggerProvider>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
| Prop | Type | Description |
|
|
69
|
-
|------|------|-------------|
|
|
70
|
-
| `adapter` | `LogAdapter` | Log adapter implementation |
|
|
18
|
+
function AppRoot() {
|
|
19
|
+
const serviceClient = useServiceClient();
|
|
71
20
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<ErrorLoggerProvider>
|
|
80
|
-
{/* children */}
|
|
81
|
-
</ErrorLoggerProvider>
|
|
21
|
+
onMount(async () => {
|
|
22
|
+
await serviceClient.connect("main", { port: 3000 });
|
|
23
|
+
useSyncStorage()!.configure(myStorageAdapter);
|
|
24
|
+
useLogger().configure(myLogAdapter);
|
|
25
|
+
useSharedData().configure(definitions);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
82
28
|
```
|
|
83
29
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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`.
|
|
30
|
+
| Prop | Type | Default | Description |
|
|
31
|
+
|------|------|---------|-------------|
|
|
32
|
+
| `clientName` | `string` | (required) | Client identifier (used as storage key prefix) |
|
|
33
|
+
| `busyVariant` | `BusyVariant` | `"spinner"` | Busy overlay display variant (`"spinner"` or `"bar"`) |
|
|
89
34
|
|
|
90
|
-
|
|
35
|
+
**Internal nesting order:**
|
|
91
36
|
|
|
92
|
-
```tsx
|
|
93
|
-
<PwaUpdateProvider>
|
|
94
|
-
{/* children */}
|
|
95
|
-
</PwaUpdateProvider>
|
|
96
37
|
```
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
```tsx
|
|
105
|
-
<ClipboardProvider>
|
|
106
|
-
{/* children */}
|
|
107
|
-
</ClipboardProvider>
|
|
38
|
+
ConfigProvider → SyncStorageProvider → LoggerProvider →
|
|
39
|
+
NotificationProvider + NotificationBanner →
|
|
40
|
+
ErrorLoggerProvider → PwaUpdateProvider →
|
|
41
|
+
ClipboardProvider → ThemeProvider →
|
|
42
|
+
ServiceClientProvider → SharedDataProvider →
|
|
43
|
+
BusyProvider → DialogProvider → {children}
|
|
108
44
|
```
|
|
109
45
|
|
|
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
|
-
```
|
|
46
|
+
Individual providers are not exported. All provider setup goes through `InitializeProvider`.
|
|
121
47
|
|
|
122
48
|
---
|
|
123
49
|
|
|
124
|
-
##
|
|
50
|
+
## Exported Types & Hooks
|
|
51
|
+
|
|
52
|
+
The following types, context objects, and hooks are exported for use with `InitializeProvider`:
|
|
53
|
+
|
|
54
|
+
| Export | Kind | Description |
|
|
55
|
+
|--------|------|-------------|
|
|
56
|
+
| `useConfig` | hook | App configuration access |
|
|
57
|
+
| `useTheme` | hook | Theme mode access and toggle |
|
|
58
|
+
| `useSyncStorage` | hook | Sync storage adapter access |
|
|
59
|
+
| `useServiceClient` | hook | WebSocket RPC client access |
|
|
60
|
+
| `useSharedData` | hook | Shared data subscription access |
|
|
61
|
+
| `useNotification` | hook | Notification system access |
|
|
62
|
+
| `useBusy` | hook | Busy overlay control |
|
|
63
|
+
| `useDialog` | hook | Programmatic dialog opening |
|
|
64
|
+
| `ConfigContext` | context | For mock injection in tests |
|
|
65
|
+
| `SyncStorageContext` | context | For mock injection in tests |
|
|
66
|
+
| `ServiceClientContext` | context | For mock injection in tests |
|
|
67
|
+
| `SharedDataContext` | context | For mock injection in tests |
|
|
68
|
+
| `AppConfig` | type | Config context value type |
|
|
69
|
+
| `StorageAdapter` | type | Sync storage adapter interface |
|
|
70
|
+
| `SyncStorageContextValue` | type | Sync storage context value type |
|
|
71
|
+
| `LogAdapter` | type | Log adapter interface |
|
|
72
|
+
| `LoggerContextValue` | type | Logger context value type |
|
|
73
|
+
| `ThemeMode` | type | `"light" \| "dark" \| "system"` |
|
|
74
|
+
| `ResolvedTheme` | type | `"light" \| "dark"` |
|
|
75
|
+
| `ServiceClientContextValue` | type | Service client context value type |
|
|
76
|
+
| `SharedDataDefinition` | type | Data subscription definition |
|
|
77
|
+
| `SharedDataAccessor` | type | Per-key data accessor |
|
|
78
|
+
| `SharedDataValue` | type | Full shared data context value |
|
|
79
|
+
| `BusyVariant` | type | `"spinner" \| "bar"` |
|
|
80
|
+
| `SharedDataChangeEvent` | class | Server-side change event definition |
|
|
125
81
|
|
|
126
|
-
|
|
82
|
+
---
|
|
127
83
|
|
|
128
|
-
|
|
84
|
+
## SharedData Usage
|
|
129
85
|
|
|
130
86
|
```tsx
|
|
131
|
-
import {
|
|
132
|
-
|
|
133
|
-
// Wrap your app
|
|
134
|
-
<ServiceClientProvider>
|
|
135
|
-
<App />
|
|
136
|
-
</ServiceClientProvider>
|
|
137
|
-
|
|
138
|
-
// In a component
|
|
139
|
-
function App() {
|
|
140
|
-
const client = useServiceClient();
|
|
87
|
+
import { useSharedData } from "@simplysm/solid";
|
|
141
88
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
});
|
|
89
|
+
function MyComponent() {
|
|
90
|
+
const sharedData = useSharedData<MySharedData>();
|
|
145
91
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
});
|
|
92
|
+
const users = () => sharedData.users.items(); // Accessor<TData[]>
|
|
93
|
+
const user = () => sharedData.users.get(userId()); // TData | undefined
|
|
149
94
|
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
const result = await svc.call("MyService", "myMethod", [arg1, arg2]);
|
|
95
|
+
const handleUpdate = async () => {
|
|
96
|
+
await sharedData.users.emit([updatedUserId]); // trigger refetch for keys
|
|
153
97
|
};
|
|
154
98
|
}
|
|
155
99
|
```
|
|
156
100
|
|
|
157
|
-
**useServiceClient API:**
|
|
158
|
-
|
|
159
|
-
| Method | Signature | Description |
|
|
160
|
-
|--------|-----------|-------------|
|
|
161
|
-
| `connect` | `(key: string, options?: Partial<ServiceConnectionConfig>) => Promise<void>` | Open WebSocket connection |
|
|
162
|
-
| `close` | `(key: string) => Promise<void>` | Close connection by key |
|
|
163
|
-
| `get` | `(key: string) => ServiceClient` | Get connected client by key (throws if not connected) |
|
|
164
|
-
| `isConnected` | `(key: string) => boolean` | Check connection state |
|
|
165
|
-
|
|
166
|
-
`ServiceConnectionConfig`: `{ host: string; port: number; ssl: boolean }`
|
|
167
|
-
|
|
168
|
-
Defaults for `host`, `port`, and `ssl` are derived from `window.location` when omitted.
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## SharedDataProvider
|
|
173
|
-
|
|
174
|
-
Shared data provider for managing server-side data subscriptions. Works with `ServiceClientProvider` to provide reactive shared data across components via `useSharedData`.
|
|
175
|
-
|
|
176
|
-
```tsx
|
|
177
|
-
import { SharedDataProvider, type SharedDataDefinition } from "@simplysm/solid";
|
|
178
|
-
|
|
179
|
-
interface MySharedData {
|
|
180
|
-
users: UserRecord;
|
|
181
|
-
products: ProductRecord;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const definitions: { [K in keyof MySharedData]: SharedDataDefinition<MySharedData[K]> } = {
|
|
185
|
-
users: {
|
|
186
|
-
serviceKey: "main",
|
|
187
|
-
fetch: async (changeKeys) => fetchUsers(changeKeys),
|
|
188
|
-
getKey: (item) => item.id,
|
|
189
|
-
orderBy: [(item) => item.name, "asc"],
|
|
190
|
-
},
|
|
191
|
-
products: {
|
|
192
|
-
serviceKey: "main",
|
|
193
|
-
fetch: async (changeKeys) => fetchProducts(changeKeys),
|
|
194
|
-
getKey: (item) => item.id,
|
|
195
|
-
orderBy: [(item) => item.name, "asc"],
|
|
196
|
-
},
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
<SharedDataProvider definitions={definitions}>
|
|
200
|
-
<App />
|
|
201
|
-
</SharedDataProvider>
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
**SharedDataProvider Props:**
|
|
205
|
-
|
|
206
|
-
| Prop | Type | Description |
|
|
207
|
-
|------|------|-------------|
|
|
208
|
-
| `definitions` | `{ [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]> }` | Map of data key to fetch definition |
|
|
209
|
-
|
|
210
101
|
**SharedDataDefinition type:**
|
|
211
102
|
|
|
212
103
|
```typescript
|
|
@@ -219,23 +110,6 @@ interface SharedDataDefinition<TData> {
|
|
|
219
110
|
}
|
|
220
111
|
```
|
|
221
112
|
|
|
222
|
-
**useSharedData API:**
|
|
223
|
-
|
|
224
|
-
```tsx
|
|
225
|
-
import { useSharedData } from "@simplysm/solid";
|
|
226
|
-
|
|
227
|
-
function MyComponent() {
|
|
228
|
-
const sharedData = useSharedData<MySharedData>();
|
|
229
|
-
|
|
230
|
-
const users = () => sharedData.users.items(); // Accessor<TData[]>
|
|
231
|
-
const user = () => sharedData.users.get(userId()); // TData | undefined
|
|
232
|
-
|
|
233
|
-
const handleUpdate = async () => {
|
|
234
|
-
await sharedData.users.emit([updatedUserId]); // trigger refetch for keys
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
113
|
**SharedDataAccessor API:**
|
|
240
114
|
|
|
241
115
|
| Property/Method | Type | Description |
|
|
@@ -250,10 +124,11 @@ function MyComponent() {
|
|
|
250
124
|
|-----------------|------|-------------|
|
|
251
125
|
| `wait` | `() => Promise<void>` | Wait until all initial fetches complete |
|
|
252
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) |
|
|
253
128
|
|
|
254
129
|
**SharedDataChangeEvent:**
|
|
255
130
|
|
|
256
|
-
`SharedDataChangeEvent` is the event definition used internally
|
|
131
|
+
`SharedDataChangeEvent` is the event definition used internally to communicate data changes between server and clients. Export it if you need to emit changes from the server side.
|
|
257
132
|
|
|
258
133
|
```typescript
|
|
259
134
|
import { SharedDataChangeEvent } from "@simplysm/solid";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.35",
|
|
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.
|
|
53
|
-
"@simplysm/core-common": "13.0.
|
|
52
|
+
"@simplysm/core-browser": "13.0.35",
|
|
53
|
+
"@simplysm/core-common": "13.0.35"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@solidjs/testing-library": "^0.8.10"
|