electron-state-sync 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +254 -0
- package/LICENSE +21 -0
- package/README.md +753 -0
- package/README.zh-CN.md +743 -0
- package/bun.lock +542 -0
- package/bunfig.toml +7 -0
- package/dist/jotai.cjs +106 -0
- package/dist/jotai.d.cts +48 -0
- package/dist/jotai.d.cts.map +1 -0
- package/dist/jotai.d.ts +48 -0
- package/dist/jotai.d.ts.map +1 -0
- package/dist/jotai.js +105 -0
- package/dist/jotai.js.map +1 -0
- package/dist/main.cjs +177 -0
- package/dist/main.d.cts +26 -0
- package/dist/main.d.cts.map +1 -0
- package/dist/main.d.ts +26 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +177 -0
- package/dist/main.js.map +1 -0
- package/dist/preact.cjs +46 -0
- package/dist/preact.d.cts +11 -0
- package/dist/preact.d.cts.map +1 -0
- package/dist/preact.d.ts +11 -0
- package/dist/preact.d.ts.map +1 -0
- package/dist/preact.js +46 -0
- package/dist/preact.js.map +1 -0
- package/dist/preload.cjs +51 -0
- package/dist/preload.d.cts +20 -0
- package/dist/preload.d.cts.map +1 -0
- package/dist/preload.d.ts +20 -0
- package/dist/preload.d.ts.map +1 -0
- package/dist/preload.js +51 -0
- package/dist/preload.js.map +1 -0
- package/dist/react-query.cjs +113 -0
- package/dist/react-query.d.cts +58 -0
- package/dist/react-query.d.cts.map +1 -0
- package/dist/react-query.d.ts +58 -0
- package/dist/react-query.d.ts.map +1 -0
- package/dist/react-query.js +112 -0
- package/dist/react-query.js.map +1 -0
- package/dist/react.cjs +46 -0
- package/dist/react.d.cts +11 -0
- package/dist/react.d.cts.map +1 -0
- package/dist/react.d.ts +11 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +46 -0
- package/dist/react.js.map +1 -0
- package/dist/redux.cjs +148 -0
- package/dist/redux.d.cts +80 -0
- package/dist/redux.d.cts.map +1 -0
- package/dist/redux.d.ts +80 -0
- package/dist/redux.d.ts.map +1 -0
- package/dist/redux.js +146 -0
- package/dist/redux.js.map +1 -0
- package/dist/renderer/index.cjs +7 -0
- package/dist/renderer/index.d.cts +23 -0
- package/dist/renderer/index.d.cts.map +1 -0
- package/dist/renderer/index.d.ts +23 -0
- package/dist/renderer/index.d.ts.map +1 -0
- package/dist/renderer/index.js +3 -0
- package/dist/renderer-C7zF3UQm.js +57 -0
- package/dist/renderer-C7zF3UQm.js.map +1 -0
- package/dist/renderer-D3YziJ_U.cjs +86 -0
- package/dist/solid.cjs +74 -0
- package/dist/solid.d.cts +13 -0
- package/dist/solid.d.cts.map +1 -0
- package/dist/solid.d.ts +13 -0
- package/dist/solid.d.ts.map +1 -0
- package/dist/solid.js +74 -0
- package/dist/solid.js.map +1 -0
- package/dist/svelte.cjs +63 -0
- package/dist/svelte.d.cts +14 -0
- package/dist/svelte.d.cts.map +1 -0
- package/dist/svelte.d.ts +14 -0
- package/dist/svelte.d.ts.map +1 -0
- package/dist/svelte.js +63 -0
- package/dist/svelte.js.map +1 -0
- package/dist/types-7wPPX0ty.d.ts +37 -0
- package/dist/types-7wPPX0ty.d.ts.map +1 -0
- package/dist/types-C18dHgLI.d.cts +37 -0
- package/dist/types-C18dHgLI.d.cts.map +1 -0
- package/dist/vue.cjs +69 -0
- package/dist/vue.d.cts +15 -0
- package/dist/vue.d.cts.map +1 -0
- package/dist/vue.d.ts +15 -0
- package/dist/vue.d.ts.map +1 -0
- package/dist/vue.js +70 -0
- package/dist/vue.js.map +1 -0
- package/dist/zustand.cjs +193 -0
- package/dist/zustand.d.cts +61 -0
- package/dist/zustand.d.cts.map +1 -0
- package/dist/zustand.d.ts +61 -0
- package/dist/zustand.d.ts.map +1 -0
- package/dist/zustand.js +191 -0
- package/dist/zustand.js.map +1 -0
- package/package.json +162 -0
package/dist/redux.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { a as SyncStateChannelOptions, t as SyncStateBridge } from "./types-7wPPX0ty.js";
|
|
2
|
+
import { Middleware, UnknownAction } from "@reduxjs/toolkit";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/redux.d.ts
|
|
5
|
+
interface SyncStateReduxOptions extends SyncStateChannelOptions {
|
|
6
|
+
bridge?: SyncStateBridge;
|
|
7
|
+
selector?: (state: unknown) => unknown;
|
|
8
|
+
actionType?: string;
|
|
9
|
+
}
|
|
10
|
+
interface SyncStateActionMeta {
|
|
11
|
+
syncState?: {
|
|
12
|
+
skipSync?: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
interface SyncStateAction<StateValue> extends UnknownAction {
|
|
16
|
+
payload: StateValue;
|
|
17
|
+
meta: SyncStateActionMeta;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Redux middleware for syncing state with Electron main process
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { configureStore } from '@reduxjs/toolkit';
|
|
25
|
+
* import { syncStateMiddleware } from 'electron-state-sync/redux';
|
|
26
|
+
*
|
|
27
|
+
* const store = configureStore({
|
|
28
|
+
* reducer: { counter: counterReducer },
|
|
29
|
+
* middleware: (getDefaultMiddleware) =>
|
|
30
|
+
* getDefaultMiddleware().concat(
|
|
31
|
+
* syncStateMiddleware({
|
|
32
|
+
* name: 'counter',
|
|
33
|
+
* selector: (state) => state.counter.value
|
|
34
|
+
* })
|
|
35
|
+
* )
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare const syncStateMiddleware: (options: SyncStateReduxOptions) => Middleware<object, any, never>;
|
|
40
|
+
/**
|
|
41
|
+
* Hook for accessing synced state in React components
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { useSyncState } from 'electron-state-sync/redux';
|
|
46
|
+
*
|
|
47
|
+
* function App() {
|
|
48
|
+
* const { state: count, isSynced } = useSyncState<number>({
|
|
49
|
+
* name: 'counter',
|
|
50
|
+
* selector: (state) => state.counter.value
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* return <div>{count}</div>;
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare const useSyncState: <StateValue>(options: SyncStateReduxOptions) => {
|
|
58
|
+
state: StateValue;
|
|
59
|
+
isSynced: boolean;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Hook to create an action creator that syncs with main process
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* import { createSyncActionCreator } from 'electron-state-sync/redux';
|
|
67
|
+
*
|
|
68
|
+
* const setCount = createSyncActionCreator<number>('counter/set', {
|
|
69
|
+
* name: 'counter'
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* // In component
|
|
73
|
+
* const dispatch = useDispatch();
|
|
74
|
+
* dispatch(setCount(42));
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare const createSyncActionCreator: <StateValue>(actionType: string, options: SyncStateReduxOptions) => ((value: StateValue) => SyncStateAction<StateValue>);
|
|
78
|
+
//#endregion
|
|
79
|
+
export { SyncStateReduxOptions, createSyncActionCreator, syncStateMiddleware, useSyncState as useReduxSyncState, useSyncState };
|
|
80
|
+
//# sourceMappingURL=redux.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redux.d.ts","names":[],"sources":["../src/renderer/redux.ts"],"sourcesContent":[],"mappings":";;;;UAUiB,qBAAA,SAA8B;EAA9B,MAAA,CAAA,EACN,eAD4B;EAqB7B,QAAA,CAAA,EAAA,CAAA,KAAA,EAAA,OAAmB,EAAA,GAAA,OAAA;EAOnB,UAAA,CAAA,EAAA,MAAe;;UAPf,mBAAA,CASF;EAFsC,SAAA,CAAA,EAAA;IAAa,QAAA,CAAA,EAAA,OAAA;EA+B9C,CAAA;AAqDb;AAkEA,UAtJU,eAsJG,CAAA,UAqBZ,CAAA,SA3K6C,aA2K7C,CAAA;EAnBU,OAAA,EAvJA,UAuJA;EACC,IAAA,EAvJJ,mBAuJI;;;;;;;;;;;;;;;;;;;;;;cA1HC,+BACF,0BACR;;;;;;;;;;;;;;;;;;cAmDU,oCACF;SACC;;;;;;;;;;;;;;;;;;;cAgEC,mEAEF,mCACC,eAAe,gBAAgB"}
|
package/dist/redux.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { a as resolveSyncStateBridge, t as getGlobalConfig } from "./renderer-C7zF3UQm.js";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
4
|
+
|
|
5
|
+
//#region src/renderer/redux.ts
|
|
6
|
+
const createChannelOptions = (options) => {
|
|
7
|
+
const globalConfig = getGlobalConfig();
|
|
8
|
+
return {
|
|
9
|
+
baseChannel: options.baseChannel ?? globalConfig.baseChannel,
|
|
10
|
+
name: options.name
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
const storeRemoteUpdates = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const channelStores = /* @__PURE__ */ new Map();
|
|
15
|
+
const shouldSkipSyncAction = (action) => {
|
|
16
|
+
const { meta } = action;
|
|
17
|
+
return Boolean(meta?.syncState?.skipSync);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Redux middleware for syncing state with Electron main process
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { configureStore } from '@reduxjs/toolkit';
|
|
25
|
+
* import { syncStateMiddleware } from 'electron-state-sync/redux';
|
|
26
|
+
*
|
|
27
|
+
* const store = configureStore({
|
|
28
|
+
* reducer: { counter: counterReducer },
|
|
29
|
+
* middleware: (getDefaultMiddleware) =>
|
|
30
|
+
* getDefaultMiddleware().concat(
|
|
31
|
+
* syncStateMiddleware({
|
|
32
|
+
* name: 'counter',
|
|
33
|
+
* selector: (state) => state.counter.value
|
|
34
|
+
* })
|
|
35
|
+
* )
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
const syncStateMiddleware = (options) => {
|
|
40
|
+
const globalConfig = getGlobalConfig();
|
|
41
|
+
const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);
|
|
42
|
+
const channelOptions = createChannelOptions(options);
|
|
43
|
+
return (storeAPI) => (next) => (action) => {
|
|
44
|
+
const channelKey = `${channelOptions.baseChannel}:${channelOptions.name}`;
|
|
45
|
+
channelStores.set(channelKey, storeAPI);
|
|
46
|
+
const result = next(action);
|
|
47
|
+
const nextState = storeAPI.getState();
|
|
48
|
+
if (storeRemoteUpdates.get(storeAPI)) {
|
|
49
|
+
storeRemoteUpdates.set(storeAPI, false);
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
if (shouldSkipSyncAction(action)) return result;
|
|
53
|
+
const selectedState = options.selector ? options.selector(nextState) : nextState;
|
|
54
|
+
bridge.set(channelOptions, selectedState);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Hook for accessing synced state in React components
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* import { useSyncState } from 'electron-state-sync/redux';
|
|
64
|
+
*
|
|
65
|
+
* function App() {
|
|
66
|
+
* const { state: count, isSynced } = useSyncState<number>({
|
|
67
|
+
* name: 'counter',
|
|
68
|
+
* selector: (state) => state.counter.value
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* return <div>{count}</div>;
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
const useSyncState = (options) => {
|
|
76
|
+
const [isSynced, setIsSynced] = useState(false);
|
|
77
|
+
const globalConfig = getGlobalConfig();
|
|
78
|
+
const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);
|
|
79
|
+
const channelOptions = useMemo(() => createChannelOptions(options), [options.baseChannel, options.name]);
|
|
80
|
+
const actionType = useMemo(() => options.actionType || `${channelOptions.baseChannel}/${channelOptions.name}/set`, [
|
|
81
|
+
options.actionType,
|
|
82
|
+
channelOptions.baseChannel,
|
|
83
|
+
channelOptions.name
|
|
84
|
+
]);
|
|
85
|
+
const state = useSelector((state$1) => options.selector ? options.selector(state$1) : state$1);
|
|
86
|
+
const dispatch = useDispatch();
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
const channelKey = `${channelOptions.baseChannel}:${channelOptions.name}`;
|
|
89
|
+
const unsubscribe = bridge.subscribe(channelOptions, (value) => {
|
|
90
|
+
const store = channelStores.get(channelKey);
|
|
91
|
+
if (store) storeRemoteUpdates.set(store, true);
|
|
92
|
+
dispatch({
|
|
93
|
+
payload: value,
|
|
94
|
+
type: actionType
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
bridge.get(channelOptions).then(() => {
|
|
98
|
+
setIsSynced(true);
|
|
99
|
+
});
|
|
100
|
+
return () => {
|
|
101
|
+
unsubscribe();
|
|
102
|
+
};
|
|
103
|
+
}, [
|
|
104
|
+
bridge,
|
|
105
|
+
channelOptions,
|
|
106
|
+
dispatch,
|
|
107
|
+
actionType
|
|
108
|
+
]);
|
|
109
|
+
return {
|
|
110
|
+
isSynced,
|
|
111
|
+
state
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Hook to create an action creator that syncs with main process
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* import { createSyncActionCreator } from 'electron-state-sync/redux';
|
|
120
|
+
*
|
|
121
|
+
* const setCount = createSyncActionCreator<number>('counter/set', {
|
|
122
|
+
* name: 'counter'
|
|
123
|
+
* });
|
|
124
|
+
*
|
|
125
|
+
* // In component
|
|
126
|
+
* const dispatch = useDispatch();
|
|
127
|
+
* dispatch(setCount(42));
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
const createSyncActionCreator = (actionType, options) => {
|
|
131
|
+
const globalConfig = getGlobalConfig();
|
|
132
|
+
const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);
|
|
133
|
+
const channelOptions = createChannelOptions(options);
|
|
134
|
+
return (value) => {
|
|
135
|
+
bridge.set(channelOptions, value);
|
|
136
|
+
return {
|
|
137
|
+
meta: { syncState: { skipSync: true } },
|
|
138
|
+
payload: value,
|
|
139
|
+
type: actionType
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
//#endregion
|
|
145
|
+
export { createSyncActionCreator, syncStateMiddleware, useSyncState as useReduxSyncState, useSyncState };
|
|
146
|
+
//# sourceMappingURL=redux.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redux.js","names":["state"],"sources":["../src/renderer/redux.ts"],"sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\n\nimport type { Middleware, UnknownAction } from \"@reduxjs/toolkit\";\nimport { useDispatch, useSelector } from \"react-redux\";\n\nimport type { SyncStateChannelOptions } from \"../channels\";\nimport type { SyncStateBridge } from \"../types\";\nimport { resolveSyncStateBridge } from \"./bridge\";\nimport { getGlobalConfig } from \"./index\";\n\nexport interface SyncStateReduxOptions extends SyncStateChannelOptions {\n bridge?: SyncStateBridge;\n selector?: (state: unknown) => unknown;\n actionType?: string;\n}\n\nconst createChannelOptions = (options: SyncStateReduxOptions): SyncStateChannelOptions => {\n const globalConfig = getGlobalConfig();\n return {\n baseChannel: options.baseChannel ?? globalConfig.baseChannel,\n name: options.name,\n };\n};\n\n// Track remote updates per store\nconst storeRemoteUpdates = new WeakMap<object, boolean>();\n\n// Store references to stores keyed by channel key, so useSyncState can access them\nconst channelStores = new Map<string, object>();\n\n// 标记需要跳过中间件同步的 action 元信息\ninterface SyncStateActionMeta {\n syncState?: {\n skipSync?: boolean;\n };\n}\n\n// 同步 action 的结构定义\ninterface SyncStateAction<StateValue> extends UnknownAction {\n payload: StateValue;\n meta: SyncStateActionMeta;\n}\n\n// 检查 action 是否需要跳过同步\nconst shouldSkipSyncAction = (action: UnknownAction): boolean => {\n const { meta } = action as { meta?: SyncStateActionMeta };\n return Boolean(meta?.syncState?.skipSync);\n};\n\n/**\n * Redux middleware for syncing state with Electron main process\n *\n * @example\n * ```typescript\n * import { configureStore } from '@reduxjs/toolkit';\n * import { syncStateMiddleware } from 'electron-state-sync/redux';\n *\n * const store = configureStore({\n * reducer: { counter: counterReducer },\n * middleware: (getDefaultMiddleware) =>\n * getDefaultMiddleware().concat(\n * syncStateMiddleware({\n * name: 'counter',\n * selector: (state) => state.counter.value\n * })\n * )\n * });\n * ```\n */\nexport const syncStateMiddleware = (\n options: SyncStateReduxOptions,\n): Middleware<object, any, never> => {\n const globalConfig = getGlobalConfig();\n const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);\n const channelOptions = createChannelOptions(options);\n\n return (storeAPI) => (next) => (action) => {\n // Store reference to this store for useSyncState to access\n const channelKey = `${channelOptions.baseChannel}:${channelOptions.name}`;\n channelStores.set(channelKey, storeAPI);\n const result = next(action);\n const nextState = storeAPI.getState();\n\n // Check if applying remote update\n const isRemote = storeRemoteUpdates.get(storeAPI);\n if (isRemote) {\n storeRemoteUpdates.set(storeAPI, false);\n return result;\n }\n\n // 如果 action 已经触发同步,跳过重复发送\n if (shouldSkipSyncAction(action as UnknownAction)) {\n return result;\n }\n\n // Select state to sync\n const selectedState = options.selector ? options.selector(nextState) : nextState;\n\n // Local update - sync to main process\n void bridge.set(channelOptions, selectedState as unknown);\n\n return result;\n };\n};\n\n/**\n * Hook for accessing synced state in React components\n *\n * @example\n * ```typescript\n * import { useSyncState } from 'electron-state-sync/redux';\n *\n * function App() {\n * const { state: count, isSynced } = useSyncState<number>({\n * name: 'counter',\n * selector: (state) => state.counter.value\n * });\n *\n * return <div>{count}</div>;\n * }\n * ```\n */\nexport const useSyncState = <StateValue>(\n options: SyncStateReduxOptions,\n): { state: StateValue; isSynced: boolean } => {\n const [isSynced, setIsSynced] = useState(false);\n const globalConfig = getGlobalConfig();\n const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);\n const channelOptions = useMemo(\n () => createChannelOptions(options),\n [options.baseChannel, options.name],\n );\n const actionType = useMemo(\n () => options.actionType || `${channelOptions.baseChannel}/${channelOptions.name}/set`,\n [options.actionType, channelOptions.baseChannel, channelOptions.name],\n );\n\n // Select state from Redux store\n const state = useSelector((state: unknown) =>\n options.selector ? (options.selector(state) as StateValue) : (state as StateValue),\n );\n\n // Subscribe to remote updates\n const dispatch = useDispatch();\n useEffect(() => {\n const channelKey = `${channelOptions.baseChannel}:${channelOptions.name}`;\n const unsubscribe = bridge.subscribe<StateValue>(channelOptions, (value) => {\n // Mark as remote update by setting the flag before dispatching\n const store = channelStores.get(channelKey);\n if (store) {\n storeRemoteUpdates.set(store, true);\n }\n dispatch({\n payload: value,\n type: actionType,\n } as UnknownAction);\n });\n\n void bridge.get<StateValue>(channelOptions).then(() => {\n setIsSynced(true);\n });\n\n return () => {\n unsubscribe();\n };\n }, [bridge, channelOptions, dispatch, actionType]);\n\n return { isSynced, state };\n};\n\nexport { useSyncState as useReduxSyncState };\n\n/**\n * Hook to create an action creator that syncs with main process\n *\n * @example\n * ```typescript\n * import { createSyncActionCreator } from 'electron-state-sync/redux';\n *\n * const setCount = createSyncActionCreator<number>('counter/set', {\n * name: 'counter'\n * });\n *\n * // In component\n * const dispatch = useDispatch();\n * dispatch(setCount(42));\n * ```\n */\nexport const createSyncActionCreator = <StateValue>(\n actionType: string,\n options: SyncStateReduxOptions,\n): ((value: StateValue) => SyncStateAction<StateValue>) => {\n const globalConfig = getGlobalConfig();\n const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);\n const channelOptions = createChannelOptions(options);\n\n return (value: StateValue) => {\n void bridge.set(channelOptions, value);\n return {\n // 标记为已同步,避免中间件重复发送\n meta: {\n syncState: {\n skipSync: true,\n },\n },\n payload: value,\n type: actionType,\n };\n };\n};\n"],"mappings":";;;;;AAgBA,MAAM,wBAAwB,YAA4D;CACxF,MAAM,eAAe,iBAAiB;AACtC,QAAO;EACL,aAAa,QAAQ,eAAe,aAAa;EACjD,MAAM,QAAQ;EACf;;AAIH,MAAM,qCAAqB,IAAI,SAA0B;AAGzD,MAAM,gCAAgB,IAAI,KAAqB;AAgB/C,MAAM,wBAAwB,WAAmC;CAC/D,MAAM,EAAE,SAAS;AACjB,QAAO,QAAQ,MAAM,WAAW,SAAS;;;;;;;;;;;;;;;;;;;;;;AAuB3C,MAAa,uBACX,YACmC;CACnC,MAAM,eAAe,iBAAiB;CACtC,MAAM,SAAS,uBAAuB,QAAQ,UAAU,aAAa,OAAO;CAC5E,MAAM,iBAAiB,qBAAqB,QAAQ;AAEpD,SAAQ,cAAc,UAAU,WAAW;EAEzC,MAAM,aAAa,GAAG,eAAe,YAAY,GAAG,eAAe;AACnE,gBAAc,IAAI,YAAY,SAAS;EACvC,MAAM,SAAS,KAAK,OAAO;EAC3B,MAAM,YAAY,SAAS,UAAU;AAIrC,MADiB,mBAAmB,IAAI,SAAS,EACnC;AACZ,sBAAmB,IAAI,UAAU,MAAM;AACvC,UAAO;;AAIT,MAAI,qBAAqB,OAAwB,CAC/C,QAAO;EAIT,MAAM,gBAAgB,QAAQ,WAAW,QAAQ,SAAS,UAAU,GAAG;AAGvE,EAAK,OAAO,IAAI,gBAAgB,cAAyB;AAEzD,SAAO;;;;;;;;;;;;;;;;;;;;AAqBX,MAAa,gBACX,YAC6C;CAC7C,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAC/C,MAAM,eAAe,iBAAiB;CACtC,MAAM,SAAS,uBAAuB,QAAQ,UAAU,aAAa,OAAO;CAC5E,MAAM,iBAAiB,cACf,qBAAqB,QAAQ,EACnC,CAAC,QAAQ,aAAa,QAAQ,KAAK,CACpC;CACD,MAAM,aAAa,cACX,QAAQ,cAAc,GAAG,eAAe,YAAY,GAAG,eAAe,KAAK,OACjF;EAAC,QAAQ;EAAY,eAAe;EAAa,eAAe;EAAK,CACtE;CAGD,MAAM,QAAQ,aAAa,YACzB,QAAQ,WAAY,QAAQ,SAASA,QAAM,GAAmBA,QAC/D;CAGD,MAAM,WAAW,aAAa;AAC9B,iBAAgB;EACd,MAAM,aAAa,GAAG,eAAe,YAAY,GAAG,eAAe;EACnE,MAAM,cAAc,OAAO,UAAsB,iBAAiB,UAAU;GAE1E,MAAM,QAAQ,cAAc,IAAI,WAAW;AAC3C,OAAI,MACF,oBAAmB,IAAI,OAAO,KAAK;AAErC,YAAS;IACP,SAAS;IACT,MAAM;IACP,CAAkB;IACnB;AAEF,EAAK,OAAO,IAAgB,eAAe,CAAC,WAAW;AACrD,eAAY,KAAK;IACjB;AAEF,eAAa;AACX,gBAAa;;IAEd;EAAC;EAAQ;EAAgB;EAAU;EAAW,CAAC;AAElD,QAAO;EAAE;EAAU;EAAO;;;;;;;;;;;;;;;;;;AAqB5B,MAAa,2BACX,YACA,YACyD;CACzD,MAAM,eAAe,iBAAiB;CACtC,MAAM,SAAS,uBAAuB,QAAQ,UAAU,aAAa,OAAO;CAC5E,MAAM,iBAAiB,qBAAqB,QAAQ;AAEpD,SAAQ,UAAsB;AAC5B,EAAK,OAAO,IAAI,gBAAgB,MAAM;AACtC,SAAO;GAEL,MAAM,EACJ,WAAW,EACT,UAAU,MACX,EACF;GACD,SAAS;GACT,MAAM;GACP"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const require_renderer = require('../renderer-D3YziJ_U.cjs');
|
|
2
|
+
|
|
3
|
+
exports.SyncStateError = require_renderer.SyncStateError;
|
|
4
|
+
exports.createSyncStateChannels = require_renderer.createSyncStateChannels;
|
|
5
|
+
exports.getGlobalConfig = require_renderer.getGlobalConfig;
|
|
6
|
+
exports.initSyncState = require_renderer.initSyncState;
|
|
7
|
+
exports.resolveSyncStateBridge = require_renderer.resolveSyncStateBridge;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { a as SyncStateChannelOptions, i as SyncStateListener, n as SyncStateError, o as SyncStateChannels, r as SyncStateErrorCode, s as createSyncStateChannels, t as SyncStateBridge } from "../types-C18dHgLI.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/renderer/window.d.ts
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
syncState?: SyncStateBridge;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=window.d.ts.map
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/renderer/bridge.d.ts
|
|
12
|
+
declare const resolveSyncStateBridge: (bridge?: SyncStateBridge) => SyncStateBridge;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/renderer/index.d.ts
|
|
15
|
+
interface SyncStateRendererGlobalConfig {
|
|
16
|
+
baseChannel?: string;
|
|
17
|
+
bridge?: SyncStateBridge;
|
|
18
|
+
}
|
|
19
|
+
declare const initSyncState: (config: SyncStateRendererGlobalConfig) => void;
|
|
20
|
+
declare const getGlobalConfig: () => SyncStateRendererGlobalConfig;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { type SyncStateBridge, type SyncStateChannelOptions, type SyncStateChannels, SyncStateError, type SyncStateErrorCode, type SyncStateListener, SyncStateRendererGlobalConfig, createSyncStateChannels, getGlobalConfig, initSyncState, resolveSyncStateBridge };
|
|
23
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/renderer/window.ts","../../src/renderer/bridge.ts","../../src/renderer/index.ts"],"sourcesContent":[],"mappings":";;;;;IAAgD,SAAA,CAAA,EAIhC,eAJgC;EAAA;;;;;cCMnC,kCAAmC,oBAAkB;;;ADFnC,UEQd,6BAAA,CFRc;;WEUpB;;ADRE,cCaA,aDJZ,EAAA,CAAA,MAT+C,ECaV,6BDJrC,EAAA,GAAA,IAAA;cCQY,uBAAsB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { a as SyncStateChannelOptions, i as SyncStateListener, n as SyncStateError, o as SyncStateChannels, r as SyncStateErrorCode, s as createSyncStateChannels, t as SyncStateBridge } from "../types-7wPPX0ty.js";
|
|
2
|
+
|
|
3
|
+
//#region src/renderer/window.d.ts
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
syncState?: SyncStateBridge;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=window.d.ts.map
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/renderer/bridge.d.ts
|
|
12
|
+
declare const resolveSyncStateBridge: (bridge?: SyncStateBridge) => SyncStateBridge;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/renderer/index.d.ts
|
|
15
|
+
interface SyncStateRendererGlobalConfig {
|
|
16
|
+
baseChannel?: string;
|
|
17
|
+
bridge?: SyncStateBridge;
|
|
18
|
+
}
|
|
19
|
+
declare const initSyncState: (config: SyncStateRendererGlobalConfig) => void;
|
|
20
|
+
declare const getGlobalConfig: () => SyncStateRendererGlobalConfig;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { type SyncStateBridge, type SyncStateChannelOptions, type SyncStateChannels, SyncStateError, type SyncStateErrorCode, type SyncStateListener, SyncStateRendererGlobalConfig, createSyncStateChannels, getGlobalConfig, initSyncState, resolveSyncStateBridge };
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/renderer/window.ts","../../src/renderer/bridge.ts","../../src/renderer/index.ts"],"sourcesContent":[],"mappings":";;;;;IAAgD,SAAA,CAAA,EAIhC,eAJgC;EAAA;;;;;cCMnC,kCAAmC,oBAAkB;;;ADFnC,UEQd,6BAAA,CFRc;;WEUpB;;ADRE,cCaA,aDJZ,EAAA,CAAA,MAT+C,ECaV,6BDJrC,EAAA,GAAA,IAAA;cCQY,uBAAsB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//#region src/renderer/bridge.ts
|
|
2
|
+
const resolveSyncStateBridge = (bridge) => {
|
|
3
|
+
const globalBridge = globalThis.syncState;
|
|
4
|
+
const resolvedBridge = bridge ?? globalBridge;
|
|
5
|
+
if (!resolvedBridge) throw new Error("globalThis.syncState not injected, please check preload configuration");
|
|
6
|
+
return resolvedBridge;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/channels.ts
|
|
11
|
+
const createSyncStateChannels = (options) => {
|
|
12
|
+
const channelPrefix = `${options.baseChannel ?? "state"}:${options.name}`;
|
|
13
|
+
return {
|
|
14
|
+
getChannel: `${channelPrefix}:get`,
|
|
15
|
+
setChannel: `${channelPrefix}:set`,
|
|
16
|
+
subscribeChannel: `${channelPrefix}:subscribe`,
|
|
17
|
+
unsubscribeChannel: `${channelPrefix}:unsubscribe`,
|
|
18
|
+
updateChannel: `${channelPrefix}:update`
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/types.ts
|
|
24
|
+
var SyncStateError = class SyncStateError extends Error {
|
|
25
|
+
code;
|
|
26
|
+
stateName;
|
|
27
|
+
baseChannel;
|
|
28
|
+
cause;
|
|
29
|
+
constructor(code, message, context) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.name = "SyncStateError";
|
|
33
|
+
this.stateName = context?.stateName;
|
|
34
|
+
this.baseChannel = context?.baseChannel;
|
|
35
|
+
this.cause = context?.cause;
|
|
36
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, SyncStateError);
|
|
37
|
+
}
|
|
38
|
+
getFullMessage() {
|
|
39
|
+
const parts = [this.message];
|
|
40
|
+
if (this.stateName) parts.push(`\n State name: "${this.stateName}"`);
|
|
41
|
+
if (this.baseChannel) parts.push(`\n Channel prefix: "${this.baseChannel}"`);
|
|
42
|
+
if (this.cause) parts.push(`\n Original error: ${this.cause.message}`);
|
|
43
|
+
return parts.join("");
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/renderer/index.ts
|
|
49
|
+
let globalConfig = {};
|
|
50
|
+
const initSyncState = (config) => {
|
|
51
|
+
globalConfig = { ...config };
|
|
52
|
+
};
|
|
53
|
+
const getGlobalConfig = () => globalConfig;
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { resolveSyncStateBridge as a, createSyncStateChannels as i, initSyncState as n, SyncStateError as r, getGlobalConfig as t };
|
|
57
|
+
//# sourceMappingURL=renderer-C7zF3UQm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-C7zF3UQm.js","names":[],"sources":["../src/renderer/bridge.ts","../src/channels.ts","../src/types.ts","../src/renderer/index.ts"],"sourcesContent":["import type { SyncStateBridge } from \"../types\";\n\ninterface SyncStateGlobal {\n syncState?: SyncStateBridge;\n}\n\nexport const resolveSyncStateBridge = (bridge?: SyncStateBridge): SyncStateBridge => {\n const globalBridge = (globalThis as SyncStateGlobal).syncState;\n const resolvedBridge = bridge ?? globalBridge;\n\n if (!resolvedBridge) {\n throw new Error(\"globalThis.syncState not injected, please check preload configuration\");\n }\n\n return resolvedBridge;\n};\n","export interface SyncStateChannelOptions {\n name: string;\n baseChannel?: string;\n}\n\nexport interface SyncStateChannels {\n getChannel: string;\n setChannel: string;\n subscribeChannel: string;\n unsubscribeChannel: string;\n updateChannel: string;\n}\n\nexport const createSyncStateChannels = (options: SyncStateChannelOptions): SyncStateChannels => {\n const baseChannel = options.baseChannel ?? \"state\";\n const channelPrefix = `${baseChannel}:${options.name}`;\n\n return {\n getChannel: `${channelPrefix}:get`,\n setChannel: `${channelPrefix}:set`,\n subscribeChannel: `${channelPrefix}:subscribe`,\n unsubscribeChannel: `${channelPrefix}:unsubscribe`,\n updateChannel: `${channelPrefix}:update`,\n };\n};\n","import type { SyncStateChannelOptions } from \"./channels\";\n\nexport type SyncStateListener<StateValue> = (value: StateValue) => void;\n\nexport type SyncStateErrorCode = \"RENDERER_READONLY\" | \"RENDERER_INVALID_VALUE\";\n\nexport class SyncStateError extends Error {\n public readonly code: SyncStateErrorCode;\n public readonly stateName?: string;\n public readonly baseChannel?: string;\n public readonly cause?: Error;\n\n public constructor(\n code: SyncStateErrorCode,\n message: string,\n context?: { stateName?: string; baseChannel?: string; cause?: Error },\n ) {\n super(message);\n this.code = code;\n this.name = \"SyncStateError\";\n this.stateName = context?.stateName;\n this.baseChannel = context?.baseChannel;\n this.cause = context?.cause;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, SyncStateError);\n }\n }\n\n public getFullMessage(): string {\n const parts = [this.message];\n if (this.stateName) {\n parts.push(`\\n State name: \"${this.stateName}\"`);\n }\n if (this.baseChannel) {\n parts.push(`\\n Channel prefix: \"${this.baseChannel}\"`);\n }\n if (this.cause) {\n parts.push(`\\n Original error: ${this.cause.message}`);\n }\n return parts.join(\"\");\n }\n}\n\nexport interface SyncStateBridge {\n get: <StateValue>(options: SyncStateChannelOptions) => Promise<StateValue>;\n set: <StateValue>(options: SyncStateChannelOptions, value: StateValue) => Promise<void>;\n subscribe: <StateValue>(\n options: SyncStateChannelOptions,\n listener: SyncStateListener<StateValue>,\n ) => () => void;\n}\n","import \"./window\";\n\nimport type { SyncStateBridge } from \"../types\";\n\nexport { resolveSyncStateBridge } from \"./bridge\";\n\nexport { createSyncStateChannels } from \"../channels\";\nexport type { SyncStateChannelOptions, SyncStateChannels } from \"../channels\";\n\nexport { SyncStateError } from \"../types\";\nexport type { SyncStateBridge, SyncStateErrorCode, SyncStateListener } from \"../types\";\n\nexport interface SyncStateRendererGlobalConfig {\n baseChannel?: string;\n bridge?: SyncStateBridge;\n}\n\nlet globalConfig: SyncStateRendererGlobalConfig = {};\n\nexport const initSyncState = (config: SyncStateRendererGlobalConfig): void => {\n globalConfig = { ...config };\n};\n\nexport const getGlobalConfig = (): SyncStateRendererGlobalConfig => globalConfig;\n"],"mappings":";AAMA,MAAa,0BAA0B,WAA8C;CACnF,MAAM,eAAgB,WAA+B;CACrD,MAAM,iBAAiB,UAAU;AAEjC,KAAI,CAAC,eACH,OAAM,IAAI,MAAM,wEAAwE;AAG1F,QAAO;;;;;ACDT,MAAa,2BAA2B,YAAwD;CAE9F,MAAM,gBAAgB,GADF,QAAQ,eAAe,QACN,GAAG,QAAQ;AAEhD,QAAO;EACL,YAAY,GAAG,cAAc;EAC7B,YAAY,GAAG,cAAc;EAC7B,kBAAkB,GAAG,cAAc;EACnC,oBAAoB,GAAG,cAAc;EACrC,eAAe,GAAG,cAAc;EACjC;;;;;ACjBH,IAAa,iBAAb,MAAa,uBAAuB,MAAM;CACxC,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAEhB,AAAO,YACL,MACA,SACA,SACA;AACA,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,OAAO;AACZ,OAAK,YAAY,SAAS;AAC1B,OAAK,cAAc,SAAS;AAC5B,OAAK,QAAQ,SAAS;AAEtB,MAAI,MAAM,kBACR,OAAM,kBAAkB,MAAM,eAAe;;CAIjD,AAAO,iBAAyB;EAC9B,MAAM,QAAQ,CAAC,KAAK,QAAQ;AAC5B,MAAI,KAAK,UACP,OAAM,KAAK,oBAAoB,KAAK,UAAU,GAAG;AAEnD,MAAI,KAAK,YACP,OAAM,KAAK,wBAAwB,KAAK,YAAY,GAAG;AAEzD,MAAI,KAAK,MACP,OAAM,KAAK,uBAAuB,KAAK,MAAM,UAAU;AAEzD,SAAO,MAAM,KAAK,GAAG;;;;;;ACvBzB,IAAI,eAA8C,EAAE;AAEpD,MAAa,iBAAiB,WAAgD;AAC5E,gBAAe,EAAE,GAAG,QAAQ;;AAG9B,MAAa,wBAAuD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/renderer/bridge.ts
|
|
3
|
+
const resolveSyncStateBridge = (bridge) => {
|
|
4
|
+
const globalBridge = globalThis.syncState;
|
|
5
|
+
const resolvedBridge = bridge ?? globalBridge;
|
|
6
|
+
if (!resolvedBridge) throw new Error("globalThis.syncState not injected, please check preload configuration");
|
|
7
|
+
return resolvedBridge;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/channels.ts
|
|
12
|
+
const createSyncStateChannels = (options) => {
|
|
13
|
+
const channelPrefix = `${options.baseChannel ?? "state"}:${options.name}`;
|
|
14
|
+
return {
|
|
15
|
+
getChannel: `${channelPrefix}:get`,
|
|
16
|
+
setChannel: `${channelPrefix}:set`,
|
|
17
|
+
subscribeChannel: `${channelPrefix}:subscribe`,
|
|
18
|
+
unsubscribeChannel: `${channelPrefix}:unsubscribe`,
|
|
19
|
+
updateChannel: `${channelPrefix}:update`
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/types.ts
|
|
25
|
+
var SyncStateError = class SyncStateError extends Error {
|
|
26
|
+
code;
|
|
27
|
+
stateName;
|
|
28
|
+
baseChannel;
|
|
29
|
+
cause;
|
|
30
|
+
constructor(code, message, context) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.code = code;
|
|
33
|
+
this.name = "SyncStateError";
|
|
34
|
+
this.stateName = context?.stateName;
|
|
35
|
+
this.baseChannel = context?.baseChannel;
|
|
36
|
+
this.cause = context?.cause;
|
|
37
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, SyncStateError);
|
|
38
|
+
}
|
|
39
|
+
getFullMessage() {
|
|
40
|
+
const parts = [this.message];
|
|
41
|
+
if (this.stateName) parts.push(`\n State name: "${this.stateName}"`);
|
|
42
|
+
if (this.baseChannel) parts.push(`\n Channel prefix: "${this.baseChannel}"`);
|
|
43
|
+
if (this.cause) parts.push(`\n Original error: ${this.cause.message}`);
|
|
44
|
+
return parts.join("");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/renderer/index.ts
|
|
50
|
+
let globalConfig = {};
|
|
51
|
+
const initSyncState = (config) => {
|
|
52
|
+
globalConfig = { ...config };
|
|
53
|
+
};
|
|
54
|
+
const getGlobalConfig = () => globalConfig;
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
Object.defineProperty(exports, 'SyncStateError', {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
get: function () {
|
|
60
|
+
return SyncStateError;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(exports, 'createSyncStateChannels', {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
get: function () {
|
|
66
|
+
return createSyncStateChannels;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(exports, 'getGlobalConfig', {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
get: function () {
|
|
72
|
+
return getGlobalConfig;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
Object.defineProperty(exports, 'initSyncState', {
|
|
76
|
+
enumerable: true,
|
|
77
|
+
get: function () {
|
|
78
|
+
return initSyncState;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(exports, 'resolveSyncStateBridge', {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: function () {
|
|
84
|
+
return resolveSyncStateBridge;
|
|
85
|
+
}
|
|
86
|
+
});
|
package/dist/solid.cjs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const require_renderer = require('./renderer-D3YziJ_U.cjs');
|
|
2
|
+
let solid_js = require("solid-js");
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/solid.ts
|
|
5
|
+
const createChannelOptions = (options) => {
|
|
6
|
+
const globalConfig = require_renderer.getGlobalConfig();
|
|
7
|
+
return {
|
|
8
|
+
baseChannel: options.baseChannel ?? globalConfig.baseChannel,
|
|
9
|
+
name: options.name
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
const createRemoteUpdateTracker = (setState, setIsSynced) => {
|
|
13
|
+
let isRemoteUpdate = false;
|
|
14
|
+
const applyRemoteValue = (value) => {
|
|
15
|
+
isRemoteUpdate = true;
|
|
16
|
+
setState(value);
|
|
17
|
+
setIsSynced(true);
|
|
18
|
+
isRemoteUpdate = false;
|
|
19
|
+
};
|
|
20
|
+
const shouldSkipLocalSync = () => {
|
|
21
|
+
if (!isRemoteUpdate) return false;
|
|
22
|
+
isRemoteUpdate = false;
|
|
23
|
+
return true;
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
applyRemoteValue,
|
|
27
|
+
shouldSkipLocalSync
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const createSyncSetter = (options) => (value) => {
|
|
31
|
+
const { accessor, bridge, channelOptions, setState, tracker } = options;
|
|
32
|
+
let nextValue = value;
|
|
33
|
+
if (typeof value === "function") nextValue = value(accessor());
|
|
34
|
+
if (tracker.shouldSkipLocalSync()) return setState(nextValue);
|
|
35
|
+
const resultValue = setState(nextValue);
|
|
36
|
+
bridge.set(channelOptions, nextValue);
|
|
37
|
+
return resultValue;
|
|
38
|
+
};
|
|
39
|
+
const useSyncState = (initialValue, options) => {
|
|
40
|
+
const [rawStateValue, rawSetStateValue] = (0, solid_js.createSignal)(initialValue);
|
|
41
|
+
const stateValue = rawStateValue;
|
|
42
|
+
const [isSynced, setIsSynced] = (0, solid_js.createSignal)(false);
|
|
43
|
+
const setStateValue = (value) => {
|
|
44
|
+
rawSetStateValue(value);
|
|
45
|
+
return value;
|
|
46
|
+
};
|
|
47
|
+
const globalConfig = require_renderer.getGlobalConfig();
|
|
48
|
+
const bridge = require_renderer.resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);
|
|
49
|
+
const channelOptions = createChannelOptions(options);
|
|
50
|
+
const tracker = createRemoteUpdateTracker(setStateValue, setIsSynced);
|
|
51
|
+
const setAndSync = createSyncSetter({
|
|
52
|
+
accessor: stateValue,
|
|
53
|
+
bridge,
|
|
54
|
+
channelOptions,
|
|
55
|
+
setState: setStateValue,
|
|
56
|
+
tracker
|
|
57
|
+
});
|
|
58
|
+
(0, solid_js.onMount)(() => {
|
|
59
|
+
const unsubscribe = bridge.subscribe(channelOptions, tracker.applyRemoteValue);
|
|
60
|
+
bridge.get(channelOptions).then(tracker.applyRemoteValue);
|
|
61
|
+
(0, solid_js.onCleanup)(() => {
|
|
62
|
+
unsubscribe();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
return [
|
|
66
|
+
stateValue,
|
|
67
|
+
setAndSync,
|
|
68
|
+
isSynced
|
|
69
|
+
];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
exports.useSyncState = useSyncState;
|
|
74
|
+
exports.useSyncStateSolid = useSyncState;
|
package/dist/solid.d.cts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { a as SyncStateChannelOptions, t as SyncStateBridge } from "./types-C18dHgLI.cjs";
|
|
2
|
+
import { Accessor } from "solid-js";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/solid.d.ts
|
|
5
|
+
interface UseSyncStateSolidOptions extends SyncStateChannelOptions {
|
|
6
|
+
bridge?: SyncStateBridge;
|
|
7
|
+
}
|
|
8
|
+
type SyncStateSolidSetter<StateValue> = (value: StateValue | ((prev: StateValue) => StateValue)) => StateValue;
|
|
9
|
+
type UseSyncStateSolidResult<StateValue> = readonly [Accessor<StateValue>, SyncStateSolidSetter<StateValue>, Accessor<boolean>];
|
|
10
|
+
declare const useSyncState: <StateValue>(initialValue: StateValue, options: UseSyncStateSolidOptions) => UseSyncStateSolidResult<StateValue>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { SyncStateSolidSetter, UseSyncStateSolidOptions, UseSyncStateSolidResult, useSyncState, useSyncState as useSyncStateSolid };
|
|
13
|
+
//# sourceMappingURL=solid.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solid.d.cts","names":[],"sources":["../src/renderer/solid.ts"],"sourcesContent":[],"mappings":";;;;UAOiB,wBAAA,SAAiC;EAAjC,MAAA,CAAA,EACN,eADM;AAKjB;AACS,KADG,oBACH,CAAA,UAAA,CAAA,GAAA,CAAA,KAAA,EAAA,UAAA,GAAA,CAAA,CAAA,IAAA,EAAqB,UAArB,EAAA,GAAoC,UAApC,CAAA,EAAA,GACJ,UADI;AAAqB,KAIlB,uBAJkB,CAAA,UAAA,CAAA,GAAA,SAAA,CAK5B,QAL2C,CAKlC,UALkC,CAAA,EAM3C,oBALG,CAKkB,UALlB,CAAA,EAMH,QANa,CAAA,OAAA,CAAA,CAGf;AACW,cA+EE,YA/EF,EAAA,CAAA,UAAA,CAAA,CAAA,YAAA,EAgFK,UAhFL,EAAA,OAAA,EAiFA,wBAjFA,EAAA,GAkFR,uBAlFQ,CAkFgB,UAlFhB,CAAA"}
|
package/dist/solid.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { a as SyncStateChannelOptions, t as SyncStateBridge } from "./types-7wPPX0ty.js";
|
|
2
|
+
import { Accessor } from "solid-js";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/solid.d.ts
|
|
5
|
+
interface UseSyncStateSolidOptions extends SyncStateChannelOptions {
|
|
6
|
+
bridge?: SyncStateBridge;
|
|
7
|
+
}
|
|
8
|
+
type SyncStateSolidSetter<StateValue> = (value: StateValue | ((prev: StateValue) => StateValue)) => StateValue;
|
|
9
|
+
type UseSyncStateSolidResult<StateValue> = readonly [Accessor<StateValue>, SyncStateSolidSetter<StateValue>, Accessor<boolean>];
|
|
10
|
+
declare const useSyncState: <StateValue>(initialValue: StateValue, options: UseSyncStateSolidOptions) => UseSyncStateSolidResult<StateValue>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { SyncStateSolidSetter, UseSyncStateSolidOptions, UseSyncStateSolidResult, useSyncState, useSyncState as useSyncStateSolid };
|
|
13
|
+
//# sourceMappingURL=solid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solid.d.ts","names":[],"sources":["../src/renderer/solid.ts"],"sourcesContent":[],"mappings":";;;;UAOiB,wBAAA,SAAiC;EAAjC,MAAA,CAAA,EACN,eADM;AAKjB;AACS,KADG,oBACH,CAAA,UAAA,CAAA,GAAA,CAAA,KAAA,EAAA,UAAA,GAAA,CAAA,CAAA,IAAA,EAAqB,UAArB,EAAA,GAAoC,UAApC,CAAA,EAAA,GACJ,UADI;AAAqB,KAIlB,uBAJkB,CAAA,UAAA,CAAA,GAAA,SAAA,CAK5B,QAL2C,CAKlC,UALkC,CAAA,EAM3C,oBALG,CAKkB,UALlB,CAAA,EAMH,QANa,CAAA,OAAA,CAAA,CAGf;AACW,cA+EE,YA/EF,EAAA,CAAA,UAAA,CAAA,CAAA,YAAA,EAgFK,UAhFL,EAAA,OAAA,EAiFA,wBAjFA,EAAA,GAkFR,uBAlFQ,CAkFgB,UAlFhB,CAAA"}
|
package/dist/solid.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { a as resolveSyncStateBridge, t as getGlobalConfig } from "./renderer-C7zF3UQm.js";
|
|
2
|
+
import { createSignal, onCleanup, onMount } from "solid-js";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/solid.ts
|
|
5
|
+
const createChannelOptions = (options) => {
|
|
6
|
+
const globalConfig = getGlobalConfig();
|
|
7
|
+
return {
|
|
8
|
+
baseChannel: options.baseChannel ?? globalConfig.baseChannel,
|
|
9
|
+
name: options.name
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
const createRemoteUpdateTracker = (setState, setIsSynced) => {
|
|
13
|
+
let isRemoteUpdate = false;
|
|
14
|
+
const applyRemoteValue = (value) => {
|
|
15
|
+
isRemoteUpdate = true;
|
|
16
|
+
setState(value);
|
|
17
|
+
setIsSynced(true);
|
|
18
|
+
isRemoteUpdate = false;
|
|
19
|
+
};
|
|
20
|
+
const shouldSkipLocalSync = () => {
|
|
21
|
+
if (!isRemoteUpdate) return false;
|
|
22
|
+
isRemoteUpdate = false;
|
|
23
|
+
return true;
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
applyRemoteValue,
|
|
27
|
+
shouldSkipLocalSync
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const createSyncSetter = (options) => (value) => {
|
|
31
|
+
const { accessor, bridge, channelOptions, setState, tracker } = options;
|
|
32
|
+
let nextValue = value;
|
|
33
|
+
if (typeof value === "function") nextValue = value(accessor());
|
|
34
|
+
if (tracker.shouldSkipLocalSync()) return setState(nextValue);
|
|
35
|
+
const resultValue = setState(nextValue);
|
|
36
|
+
bridge.set(channelOptions, nextValue);
|
|
37
|
+
return resultValue;
|
|
38
|
+
};
|
|
39
|
+
const useSyncState = (initialValue, options) => {
|
|
40
|
+
const [rawStateValue, rawSetStateValue] = createSignal(initialValue);
|
|
41
|
+
const stateValue = rawStateValue;
|
|
42
|
+
const [isSynced, setIsSynced] = createSignal(false);
|
|
43
|
+
const setStateValue = (value) => {
|
|
44
|
+
rawSetStateValue(value);
|
|
45
|
+
return value;
|
|
46
|
+
};
|
|
47
|
+
const globalConfig = getGlobalConfig();
|
|
48
|
+
const bridge = resolveSyncStateBridge(options.bridge ?? globalConfig.bridge);
|
|
49
|
+
const channelOptions = createChannelOptions(options);
|
|
50
|
+
const tracker = createRemoteUpdateTracker(setStateValue, setIsSynced);
|
|
51
|
+
const setAndSync = createSyncSetter({
|
|
52
|
+
accessor: stateValue,
|
|
53
|
+
bridge,
|
|
54
|
+
channelOptions,
|
|
55
|
+
setState: setStateValue,
|
|
56
|
+
tracker
|
|
57
|
+
});
|
|
58
|
+
onMount(() => {
|
|
59
|
+
const unsubscribe = bridge.subscribe(channelOptions, tracker.applyRemoteValue);
|
|
60
|
+
bridge.get(channelOptions).then(tracker.applyRemoteValue);
|
|
61
|
+
onCleanup(() => {
|
|
62
|
+
unsubscribe();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
return [
|
|
66
|
+
stateValue,
|
|
67
|
+
setAndSync,
|
|
68
|
+
isSynced
|
|
69
|
+
];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { useSyncState, useSyncState as useSyncStateSolid };
|
|
74
|
+
//# sourceMappingURL=solid.js.map
|