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.
Files changed (97) hide show
  1. package/CLAUDE.md +254 -0
  2. package/LICENSE +21 -0
  3. package/README.md +753 -0
  4. package/README.zh-CN.md +743 -0
  5. package/bun.lock +542 -0
  6. package/bunfig.toml +7 -0
  7. package/dist/jotai.cjs +106 -0
  8. package/dist/jotai.d.cts +48 -0
  9. package/dist/jotai.d.cts.map +1 -0
  10. package/dist/jotai.d.ts +48 -0
  11. package/dist/jotai.d.ts.map +1 -0
  12. package/dist/jotai.js +105 -0
  13. package/dist/jotai.js.map +1 -0
  14. package/dist/main.cjs +177 -0
  15. package/dist/main.d.cts +26 -0
  16. package/dist/main.d.cts.map +1 -0
  17. package/dist/main.d.ts +26 -0
  18. package/dist/main.d.ts.map +1 -0
  19. package/dist/main.js +177 -0
  20. package/dist/main.js.map +1 -0
  21. package/dist/preact.cjs +46 -0
  22. package/dist/preact.d.cts +11 -0
  23. package/dist/preact.d.cts.map +1 -0
  24. package/dist/preact.d.ts +11 -0
  25. package/dist/preact.d.ts.map +1 -0
  26. package/dist/preact.js +46 -0
  27. package/dist/preact.js.map +1 -0
  28. package/dist/preload.cjs +51 -0
  29. package/dist/preload.d.cts +20 -0
  30. package/dist/preload.d.cts.map +1 -0
  31. package/dist/preload.d.ts +20 -0
  32. package/dist/preload.d.ts.map +1 -0
  33. package/dist/preload.js +51 -0
  34. package/dist/preload.js.map +1 -0
  35. package/dist/react-query.cjs +113 -0
  36. package/dist/react-query.d.cts +58 -0
  37. package/dist/react-query.d.cts.map +1 -0
  38. package/dist/react-query.d.ts +58 -0
  39. package/dist/react-query.d.ts.map +1 -0
  40. package/dist/react-query.js +112 -0
  41. package/dist/react-query.js.map +1 -0
  42. package/dist/react.cjs +46 -0
  43. package/dist/react.d.cts +11 -0
  44. package/dist/react.d.cts.map +1 -0
  45. package/dist/react.d.ts +11 -0
  46. package/dist/react.d.ts.map +1 -0
  47. package/dist/react.js +46 -0
  48. package/dist/react.js.map +1 -0
  49. package/dist/redux.cjs +148 -0
  50. package/dist/redux.d.cts +80 -0
  51. package/dist/redux.d.cts.map +1 -0
  52. package/dist/redux.d.ts +80 -0
  53. package/dist/redux.d.ts.map +1 -0
  54. package/dist/redux.js +146 -0
  55. package/dist/redux.js.map +1 -0
  56. package/dist/renderer/index.cjs +7 -0
  57. package/dist/renderer/index.d.cts +23 -0
  58. package/dist/renderer/index.d.cts.map +1 -0
  59. package/dist/renderer/index.d.ts +23 -0
  60. package/dist/renderer/index.d.ts.map +1 -0
  61. package/dist/renderer/index.js +3 -0
  62. package/dist/renderer-C7zF3UQm.js +57 -0
  63. package/dist/renderer-C7zF3UQm.js.map +1 -0
  64. package/dist/renderer-D3YziJ_U.cjs +86 -0
  65. package/dist/solid.cjs +74 -0
  66. package/dist/solid.d.cts +13 -0
  67. package/dist/solid.d.cts.map +1 -0
  68. package/dist/solid.d.ts +13 -0
  69. package/dist/solid.d.ts.map +1 -0
  70. package/dist/solid.js +74 -0
  71. package/dist/solid.js.map +1 -0
  72. package/dist/svelte.cjs +63 -0
  73. package/dist/svelte.d.cts +14 -0
  74. package/dist/svelte.d.cts.map +1 -0
  75. package/dist/svelte.d.ts +14 -0
  76. package/dist/svelte.d.ts.map +1 -0
  77. package/dist/svelte.js +63 -0
  78. package/dist/svelte.js.map +1 -0
  79. package/dist/types-7wPPX0ty.d.ts +37 -0
  80. package/dist/types-7wPPX0ty.d.ts.map +1 -0
  81. package/dist/types-C18dHgLI.d.cts +37 -0
  82. package/dist/types-C18dHgLI.d.cts.map +1 -0
  83. package/dist/vue.cjs +69 -0
  84. package/dist/vue.d.cts +15 -0
  85. package/dist/vue.d.cts.map +1 -0
  86. package/dist/vue.d.ts +15 -0
  87. package/dist/vue.d.ts.map +1 -0
  88. package/dist/vue.js +70 -0
  89. package/dist/vue.js.map +1 -0
  90. package/dist/zustand.cjs +193 -0
  91. package/dist/zustand.d.cts +61 -0
  92. package/dist/zustand.d.cts.map +1 -0
  93. package/dist/zustand.d.ts +61 -0
  94. package/dist/zustand.d.ts.map +1 -0
  95. package/dist/zustand.js +191 -0
  96. package/dist/zustand.js.map +1 -0
  97. package/package.json +162 -0
@@ -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,3 @@
1
+ import { a as resolveSyncStateBridge, i as createSyncStateChannels, n as initSyncState, r as SyncStateError, t as getGlobalConfig } from "../renderer-C7zF3UQm.js";
2
+
3
+ export { SyncStateError, createSyncStateChannels, getGlobalConfig, initSyncState, resolveSyncStateBridge };
@@ -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;
@@ -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"}
@@ -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