electron-pinia-sync 1.0.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/CONTRIBUTING.md +405 -0
- package/LICENSE +21 -0
- package/README.md +458 -0
- package/dist/main/index.d.ts +153 -0
- package/dist/main/index.js +221 -0
- package/dist/preload/index.d.ts +2 -0
- package/dist/preload/index.js +60 -0
- package/dist/renderer/index.d.ts +123 -0
- package/dist/renderer/index.js +199 -0
- package/package.json +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# electron-pinia-sync
|
|
2
|
+
|
|
3
|
+
> Synchronize Pinia stores between Electron Main and Renderer processes with persistence support
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/electron-pinia-sync)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🔄 **Bidirectional Sync**: Synchronize Pinia stores between Main and multiple Renderer processes
|
|
11
|
+
- 🎯 **Single Source of Truth**: Main process maintains the authoritative state
|
|
12
|
+
- 💾 **Persistent Storage**: Selective persistence to disk using `electron-store`
|
|
13
|
+
- 🔒 **Type-Safe**: Full TypeScript support with strict mode
|
|
14
|
+
- 🚀 **Zero Config**: Works out of the box with sensible defaults
|
|
15
|
+
- 🔁 **Echo Prevention**: Intelligent transaction tracking prevents infinite loops
|
|
16
|
+
- 📦 **ESM-Only**: Modern ES Modules build (~4 KB per module)
|
|
17
|
+
- ⚡ **Performance**: Efficient diffing with `microdiff` minimizes data transfer
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install electron-pinia-sync
|
|
23
|
+
# or
|
|
24
|
+
yarn add electron-pinia-sync
|
|
25
|
+
# or
|
|
26
|
+
pnpm add electron-pinia-sync
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Peer Dependencies
|
|
30
|
+
|
|
31
|
+
**Important**: This library does **not** bundle Electron, Pinia, or Vue. You must install them separately:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install electron pinia vue
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Required versions**:
|
|
38
|
+
- Electron >= 28
|
|
39
|
+
- Pinia >= 3.0
|
|
40
|
+
- Vue >= 3.5
|
|
41
|
+
- Node.js >= 20
|
|
42
|
+
|
|
43
|
+
**Why?** This keeps the bundle size small and prevents dependency conflicts. You use your own versions of Electron and Pinia.
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
### 1. Preload Script
|
|
48
|
+
|
|
49
|
+
Set up the secure IPC bridge in your preload script:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// preload.ts
|
|
53
|
+
import 'electron-pinia-sync/preload';
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Main Process
|
|
57
|
+
|
|
58
|
+
Initialize the sync manager in your main process:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// main.ts
|
|
62
|
+
import { app } from 'electron';
|
|
63
|
+
import { createMainSync } from 'electron-pinia-sync/main';
|
|
64
|
+
import { defineStore } from 'pinia';
|
|
65
|
+
|
|
66
|
+
const mainSync = createMainSync({
|
|
67
|
+
storeOptions: {
|
|
68
|
+
// Optional: electron-store configuration
|
|
69
|
+
name: 'my-app-store',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Get the Pinia instance
|
|
74
|
+
const store = mainSync.getPinia();
|
|
75
|
+
|
|
76
|
+
// Define your store
|
|
77
|
+
const useCounterStore = defineStore('counter', {
|
|
78
|
+
state: () => ({
|
|
79
|
+
count: 0,
|
|
80
|
+
name: 'Counter',
|
|
81
|
+
}),
|
|
82
|
+
actions: {
|
|
83
|
+
increment() {
|
|
84
|
+
this.count++;
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Create and register the store
|
|
90
|
+
const counterStore = useCounterStore(store);
|
|
91
|
+
mainSync.registerStore('counter', counterStore, {
|
|
92
|
+
persist: true, // Enable persistence for this store
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
app.on('quit', () => {
|
|
96
|
+
mainSync.destroy();
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3. Renderer Process
|
|
101
|
+
|
|
102
|
+
Set up the Pinia plugin in your renderer process:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// renderer.ts (or main.ts in your Vue app)
|
|
106
|
+
import { createApp } from 'vue';
|
|
107
|
+
import { createPinia, defineStore } from 'pinia';
|
|
108
|
+
import { createRendererSync } from 'electron-pinia-sync/renderer';
|
|
109
|
+
import App from './App.vue';
|
|
110
|
+
|
|
111
|
+
const pinia = createPinia();
|
|
112
|
+
|
|
113
|
+
// Add the sync plugin
|
|
114
|
+
pinia.use(createRendererSync());
|
|
115
|
+
|
|
116
|
+
const app = createApp(App);
|
|
117
|
+
app.use(pinia);
|
|
118
|
+
app.mount('#app');
|
|
119
|
+
|
|
120
|
+
// Define the same store (structure must match Main process)
|
|
121
|
+
export const useCounterStore = defineStore('counter', {
|
|
122
|
+
state: () => ({
|
|
123
|
+
count: 0,
|
|
124
|
+
name: 'Counter',
|
|
125
|
+
}),
|
|
126
|
+
actions: {
|
|
127
|
+
increment() {
|
|
128
|
+
this.count++;
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 4. Use in Vue Components
|
|
135
|
+
|
|
136
|
+
```vue
|
|
137
|
+
<template>
|
|
138
|
+
<div>
|
|
139
|
+
<h1>{{ counter.name }}</h1>
|
|
140
|
+
<p>Count: {{ counter.count }}</p>
|
|
141
|
+
<button @click="counter.increment()">Increment</button>
|
|
142
|
+
</div>
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<script setup lang="ts">
|
|
146
|
+
import { useCounterStore } from './stores/counter';
|
|
147
|
+
|
|
148
|
+
const counter = useCounterStore();
|
|
149
|
+
</script>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## API Reference
|
|
153
|
+
|
|
154
|
+
### Main Process
|
|
155
|
+
|
|
156
|
+
#### `createMainSync(options?)`
|
|
157
|
+
|
|
158
|
+
Creates and initializes the Main process sync manager.
|
|
159
|
+
|
|
160
|
+
**Options:**
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
interface MainSyncOptions {
|
|
164
|
+
// Custom Pinia instance (optional, will create one if not provided)
|
|
165
|
+
pinia?: Pinia;
|
|
166
|
+
|
|
167
|
+
// electron-store configuration
|
|
168
|
+
storeOptions?: {
|
|
169
|
+
name?: string;
|
|
170
|
+
cwd?: string;
|
|
171
|
+
encryptionKey?: string;
|
|
172
|
+
// ... other electron-store options
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Returns:** `MainSync` instance
|
|
178
|
+
|
|
179
|
+
#### `mainSync.registerStore(storeId, store, options?)`
|
|
180
|
+
|
|
181
|
+
Registers a Pinia store with the sync manager.
|
|
182
|
+
|
|
183
|
+
**Parameters:**
|
|
184
|
+
|
|
185
|
+
- `storeId` (string): Unique identifier for the store
|
|
186
|
+
- `store` (Store): Pinia store instance
|
|
187
|
+
- `options` (object, optional):
|
|
188
|
+
- `persist` (boolean | PersistOptions): Persistence configuration
|
|
189
|
+
|
|
190
|
+
**Persistence Options:**
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// Simple boolean
|
|
194
|
+
{ persist: true }
|
|
195
|
+
|
|
196
|
+
// Advanced configuration
|
|
197
|
+
{
|
|
198
|
+
persist: {
|
|
199
|
+
enabled: true,
|
|
200
|
+
key: 'custom-storage-key', // Optional custom key
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### `mainSync.getPinia()`
|
|
206
|
+
|
|
207
|
+
Returns the managed Pinia instance.
|
|
208
|
+
|
|
209
|
+
#### `mainSync.destroy()`
|
|
210
|
+
|
|
211
|
+
Cleanup IPC handlers. Call this when your app is shutting down.
|
|
212
|
+
|
|
213
|
+
### Renderer Process
|
|
214
|
+
|
|
215
|
+
#### `createRendererSync(options?)`
|
|
216
|
+
|
|
217
|
+
Creates the Pinia plugin for renderer process synchronization.
|
|
218
|
+
|
|
219
|
+
**Options:**
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
interface RendererSyncOptions {
|
|
223
|
+
// Custom logger (default: console)
|
|
224
|
+
logger?: {
|
|
225
|
+
warn: (message: string, ...args: any[]) => void;
|
|
226
|
+
error: (message: string, ...args: any[]) => void;
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Returns:** Pinia plugin function
|
|
232
|
+
|
|
233
|
+
## Advanced Usage
|
|
234
|
+
|
|
235
|
+
### Multiple Windows
|
|
236
|
+
|
|
237
|
+
The library automatically synchronizes state across all renderer processes:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// main.ts
|
|
241
|
+
import { BrowserWindow } from 'electron';
|
|
242
|
+
|
|
243
|
+
const window1 = new BrowserWindow({
|
|
244
|
+
webPreferences: {
|
|
245
|
+
preload: path.join(__dirname, 'preload.js'),
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const window2 = new BrowserWindow({
|
|
250
|
+
webPreferences: {
|
|
251
|
+
preload: path.join(__dirname, 'preload.js'),
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Both windows will stay in sync automatically
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Selective Persistence
|
|
259
|
+
|
|
260
|
+
Choose which stores to persist:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// Persist user settings
|
|
264
|
+
mainSync.registerStore('settings', settingsStore, { persist: true });
|
|
265
|
+
|
|
266
|
+
// Don't persist temporary UI state
|
|
267
|
+
mainSync.registerStore('ui', uiStore, { persist: false });
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Custom Storage Keys
|
|
271
|
+
|
|
272
|
+
Use custom keys for electron-store:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
mainSync.registerStore('user', userStore, {
|
|
276
|
+
persist: {
|
|
277
|
+
enabled: true,
|
|
278
|
+
key: 'app-user-data', // Custom key
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Error Handling
|
|
284
|
+
|
|
285
|
+
Provide a custom logger to handle errors:
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
const pinia = createPinia();
|
|
289
|
+
|
|
290
|
+
pinia.use(createRendererSync({
|
|
291
|
+
logger: {
|
|
292
|
+
warn: (msg, ...args) => {
|
|
293
|
+
// Custom warning handler
|
|
294
|
+
console.warn('[MyApp]', msg, ...args);
|
|
295
|
+
},
|
|
296
|
+
error: (msg, ...args) => {
|
|
297
|
+
// Custom error handler
|
|
298
|
+
Sentry.captureException(new Error(msg));
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
}));
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## How It Works
|
|
305
|
+
|
|
306
|
+
### Synchronization Flow
|
|
307
|
+
|
|
308
|
+
1. **Initialization**: When a renderer process starts, it pulls the current state from the Main process
|
|
309
|
+
2. **Renderer → Main**: When state changes in a renderer, a patch is sent to the Main process
|
|
310
|
+
3. **Main Processing**: Main process applies the patch and optionally persists to disk
|
|
311
|
+
4. **Main → Renderers**: Main process broadcasts the updated state to all renderer processes
|
|
312
|
+
5. **Echo Prevention**: Transaction IDs prevent the originating renderer from applying its own update
|
|
313
|
+
|
|
314
|
+
### Architecture
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
318
|
+
│ Main Process │
|
|
319
|
+
│ ┌────────────────────────────────────────────────────────┐ │
|
|
320
|
+
│ │ Pinia Store (Single Source of Truth) │ │
|
|
321
|
+
│ │ - Receives patches from renderers │ │
|
|
322
|
+
│ │ - Persists to electron-store │ │
|
|
323
|
+
│ │ - Broadcasts updates to all renderers │ │
|
|
324
|
+
│ └────────────────────────────────────────────────────────┘ │
|
|
325
|
+
└───────────────┬──────────────────────────┬──────────────────┘
|
|
326
|
+
│ │
|
|
327
|
+
IPC │ │ IPC
|
|
328
|
+
(patches) │ │ (updates)
|
|
329
|
+
│ │
|
|
330
|
+
┌───────────▼──────────┐ ┌──────────▼───────────┐
|
|
331
|
+
│ Renderer 1 │ │ Renderer 2 │
|
|
332
|
+
│ ┌────────────────┐ │ │ ┌────────────────┐ │
|
|
333
|
+
│ │ Pinia Store │ │ │ │ Pinia Store │ │
|
|
334
|
+
│ │ (Local Copy) │ │ │ │ (Local Copy) │ │
|
|
335
|
+
│ └────────────────┘ │ │ └────────────────┘ │
|
|
336
|
+
└─────────────────────┘ └──────────────────────┘
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## TypeScript Support
|
|
340
|
+
|
|
341
|
+
Full TypeScript support with type inference:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import { defineStore } from 'pinia';
|
|
345
|
+
|
|
346
|
+
interface CounterState {
|
|
347
|
+
count: number;
|
|
348
|
+
name: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export const useCounterStore = defineStore('counter', {
|
|
352
|
+
state: (): CounterState => ({
|
|
353
|
+
count: 0,
|
|
354
|
+
name: 'Counter',
|
|
355
|
+
}),
|
|
356
|
+
getters: {
|
|
357
|
+
doubleCount: (state) => state.count * 2,
|
|
358
|
+
},
|
|
359
|
+
actions: {
|
|
360
|
+
increment() {
|
|
361
|
+
this.count++;
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Full type inference in components
|
|
367
|
+
const counter = useCounterStore();
|
|
368
|
+
counter.count; // number
|
|
369
|
+
counter.name; // string
|
|
370
|
+
counter.doubleCount; // number
|
|
371
|
+
counter.increment(); // void
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Best Practices
|
|
375
|
+
|
|
376
|
+
1. **Store Definition**: Define stores with the same structure in both Main and Renderer processes
|
|
377
|
+
2. **Persistence**: Only persist stores that need to survive app restarts
|
|
378
|
+
3. **State Size**: Keep state size reasonable for IPC transfer performance
|
|
379
|
+
4. **Actions**: Actions can be defined only in Renderer (they're not synced, only state is)
|
|
380
|
+
5. **Initialization**: Wait for store initialization before using in components
|
|
381
|
+
|
|
382
|
+
## Debugging
|
|
383
|
+
|
|
384
|
+
Enable debug logging to see synchronization details:
|
|
385
|
+
|
|
386
|
+
**Main Process:**
|
|
387
|
+
```typescript
|
|
388
|
+
const mainSync = createMainSync({
|
|
389
|
+
debug: true, // or 'verbose' for detailed logs
|
|
390
|
+
});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Renderer Process:**
|
|
394
|
+
```typescript
|
|
395
|
+
pinia.use(createRendererSync({
|
|
396
|
+
debug: 'verbose', // Shows state diffs and patches
|
|
397
|
+
}));
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Debug Levels:**
|
|
401
|
+
- `false` (default): Only errors/warnings
|
|
402
|
+
- `true`: Important operations
|
|
403
|
+
- `'verbose'`: Detailed logs with state diffs
|
|
404
|
+
|
|
405
|
+
For advanced debugging, see [DEBUG.md](./DEBUG.md).
|
|
406
|
+
|
|
407
|
+
## Troubleshooting
|
|
408
|
+
|
|
409
|
+
### Store not syncing
|
|
410
|
+
|
|
411
|
+
**Problem**: Changes in one process don't reflect in others
|
|
412
|
+
|
|
413
|
+
**Solution**:
|
|
414
|
+
- Ensure the preload script is loaded correctly
|
|
415
|
+
- Check that store IDs match between Main and Renderer
|
|
416
|
+
- Verify `registerStore` is called in Main process
|
|
417
|
+
|
|
418
|
+
### State not persisting
|
|
419
|
+
|
|
420
|
+
**Problem**: State resets on app restart
|
|
421
|
+
|
|
422
|
+
**Solution**:
|
|
423
|
+
- Confirm `persist: true` is set when registering the store
|
|
424
|
+
- Check electron-store permissions and storage location
|
|
425
|
+
- Verify the Main process has write permissions
|
|
426
|
+
|
|
427
|
+
### Type errors with window.piniaSync
|
|
428
|
+
|
|
429
|
+
**Problem**: TypeScript doesn't recognize `window.piniaSync`
|
|
430
|
+
|
|
431
|
+
**Solution**:
|
|
432
|
+
- Import types: `import 'electron-pinia-sync/preload'`
|
|
433
|
+
- The types are automatically augmented to the global `Window` interface
|
|
434
|
+
|
|
435
|
+
## Examples
|
|
436
|
+
|
|
437
|
+
Check the `examples/` directory for complete working examples:
|
|
438
|
+
|
|
439
|
+
- **Basic Counter**: Simple counter app with persistence
|
|
440
|
+
- **Multi-Window**: Todo app synchronized across multiple windows
|
|
441
|
+
- **Complex State**: E-commerce app with nested state
|
|
442
|
+
|
|
443
|
+
## Contributing
|
|
444
|
+
|
|
445
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup and guidelines.
|
|
446
|
+
|
|
447
|
+
## License
|
|
448
|
+
|
|
449
|
+
MIT © simpli.fyi GbR
|
|
450
|
+
|
|
451
|
+
## Credits
|
|
452
|
+
|
|
453
|
+
Built with:
|
|
454
|
+
- [Electron](https://www.electronjs.org/)
|
|
455
|
+
- [Vue 3](https://vuejs.org/)
|
|
456
|
+
- [Pinia](https://pinia.vuejs.org/)
|
|
457
|
+
- [electron-store](https://github.com/sindresorhus/electron-store)
|
|
458
|
+
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { StateTree, Pinia, Store as Store$1 } from 'pinia';
|
|
2
|
+
import Store from 'electron-store';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Common types shared across Main, Renderer, and Preload processes
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Debug level configuration
|
|
10
|
+
*/
|
|
11
|
+
type DebugLevel$1 = boolean | 'verbose' | 'minimal';
|
|
12
|
+
/**
|
|
13
|
+
* Message sent from Main to Renderer when state is updated
|
|
14
|
+
*/
|
|
15
|
+
interface StateUpdateMessage {
|
|
16
|
+
/** Store ID */
|
|
17
|
+
storeId: string;
|
|
18
|
+
/** New state */
|
|
19
|
+
state: StateTree;
|
|
20
|
+
/** Transaction ID that caused this update (if any) */
|
|
21
|
+
transactionId?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options for configuring store persistence
|
|
25
|
+
*/
|
|
26
|
+
interface PersistOptions {
|
|
27
|
+
/** Whether to persist this store to disk */
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
/** Optional custom key for electron-store (defaults to storeId) */
|
|
30
|
+
key?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* API exposed to Renderer via contextBridge
|
|
34
|
+
*/
|
|
35
|
+
interface PiniaSyncAPI {
|
|
36
|
+
/**
|
|
37
|
+
* Pull initial state from Main process
|
|
38
|
+
*/
|
|
39
|
+
pullState: (storeId: string) => Promise<StateTree | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Send state patch to Main process
|
|
42
|
+
*/
|
|
43
|
+
patchState: (storeId: string, patch: Partial<StateTree>, transactionId: string) => Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Subscribe to state updates from Main process
|
|
46
|
+
*/
|
|
47
|
+
onStateUpdate: (callback: (message: StateUpdateMessage) => void) => () => void;
|
|
48
|
+
}
|
|
49
|
+
declare global {
|
|
50
|
+
interface Window {
|
|
51
|
+
piniaSync?: PiniaSyncAPI;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Debug utilities for electron-pinia-sync
|
|
57
|
+
*
|
|
58
|
+
* Enable debug logging programmatically:
|
|
59
|
+
* - { debug: true } - enable debug logging
|
|
60
|
+
* - { debug: 'verbose' } - enable verbose logging with state diffs
|
|
61
|
+
* - { debug: 'minimal' } - only log errors and warnings
|
|
62
|
+
*/
|
|
63
|
+
type DebugLevel = boolean | 'verbose' | 'minimal';
|
|
64
|
+
interface DebugLogger {
|
|
65
|
+
log: (message: string, ...args: unknown[]) => void;
|
|
66
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
67
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
68
|
+
debug: (message: string, ...args: unknown[]) => void;
|
|
69
|
+
verbose: (message: string, ...args: unknown[]) => void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a debug logger for a specific namespace
|
|
73
|
+
*/
|
|
74
|
+
declare function createDebugLogger(namespace: string, debugLevel?: DebugLevel, customLogger?: Partial<DebugLogger>): DebugLogger;
|
|
75
|
+
/**
|
|
76
|
+
* Format state for debug output (truncate large objects)
|
|
77
|
+
*/
|
|
78
|
+
declare function formatStateForDebug(state: unknown, maxLength?: number): string;
|
|
79
|
+
/**
|
|
80
|
+
* Format patch for debug output
|
|
81
|
+
*/
|
|
82
|
+
declare function formatPatchForDebug(patch: unknown): string;
|
|
83
|
+
|
|
84
|
+
interface MainSyncOptions {
|
|
85
|
+
/**
|
|
86
|
+
* electron-store configuration options
|
|
87
|
+
*/
|
|
88
|
+
storeOptions?: ConstructorParameters<typeof Store<Record<string, StateTree>>>[0];
|
|
89
|
+
/**
|
|
90
|
+
* Custom Pinia instance (optional, will create one if not provided)
|
|
91
|
+
*/
|
|
92
|
+
pinia?: Pinia;
|
|
93
|
+
/**
|
|
94
|
+
* Enable debug logging
|
|
95
|
+
* - true: enable debug logging
|
|
96
|
+
* - 'verbose': enable verbose logging with state diffs
|
|
97
|
+
* - 'minimal': only log errors and warnings
|
|
98
|
+
* - false: disable debug logging (default)
|
|
99
|
+
*/
|
|
100
|
+
debug?: DebugLevel$1;
|
|
101
|
+
/**
|
|
102
|
+
* Custom logger (for testing or custom logging)
|
|
103
|
+
*/
|
|
104
|
+
logger?: Partial<DebugLogger>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Main process synchronization manager
|
|
109
|
+
* Manages Pinia stores in the Main process and handles IPC communication
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
declare class MainSync {
|
|
113
|
+
private pinia;
|
|
114
|
+
private electronStore;
|
|
115
|
+
private storeMetadata;
|
|
116
|
+
private processingTransactions;
|
|
117
|
+
private readonly MAX_TRANSACTION_HISTORY;
|
|
118
|
+
private debug;
|
|
119
|
+
constructor(options?: MainSyncOptions);
|
|
120
|
+
/**
|
|
121
|
+
* Get the Pinia instance managed by this sync manager
|
|
122
|
+
*/
|
|
123
|
+
getPinia(): Pinia;
|
|
124
|
+
/**
|
|
125
|
+
* Register a store with the sync manager
|
|
126
|
+
*/
|
|
127
|
+
registerStore(storeId: string, store: Store$1, options?: {
|
|
128
|
+
persist?: boolean | PersistOptions;
|
|
129
|
+
}): void;
|
|
130
|
+
/**
|
|
131
|
+
* Normalize persist options to standard format
|
|
132
|
+
*/
|
|
133
|
+
private normalizePersistOptions;
|
|
134
|
+
/**
|
|
135
|
+
* Setup IPC handlers for communication with renderers
|
|
136
|
+
*/
|
|
137
|
+
private setupIpcHandlers;
|
|
138
|
+
private addTransaction;
|
|
139
|
+
/**
|
|
140
|
+
* Broadcast state update to all renderer processes
|
|
141
|
+
*/
|
|
142
|
+
private broadcastStateUpdate;
|
|
143
|
+
/**
|
|
144
|
+
* Cleanup IPC handlers
|
|
145
|
+
*/
|
|
146
|
+
destroy(): void;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Create and initialize the Main process sync manager
|
|
150
|
+
*/
|
|
151
|
+
declare function createMainSync(options?: MainSyncOptions): MainSync;
|
|
152
|
+
|
|
153
|
+
export { type DebugLevel, type DebugLogger, MainSync, createDebugLogger, createMainSync, formatPatchForDebug, formatStateForDebug };
|