@chromahq/store 1.0.13 → 1.0.15
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/dist/index.cjs.js +39 -12
- package/dist/index.d.ts +6 -1
- package/dist/index.es.js +39 -12
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -118,20 +118,35 @@ class BridgeStore {
|
|
|
118
118
|
this.readyCallbacks = /* @__PURE__ */ new Set();
|
|
119
119
|
this.initializationAttempts = 0;
|
|
120
120
|
this.maxInitializationAttempts = 10;
|
|
121
|
+
this.initializationTimer = null;
|
|
122
|
+
this.isInitializing = false;
|
|
121
123
|
this.initialize = async () => {
|
|
124
|
+
if (this.isInitializing) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (this.initializationTimer) {
|
|
128
|
+
clearTimeout(this.initializationTimer);
|
|
129
|
+
this.initializationTimer = null;
|
|
130
|
+
}
|
|
122
131
|
this.initializationAttempts++;
|
|
132
|
+
this.isInitializing = true;
|
|
123
133
|
try {
|
|
124
134
|
if (this.initializationAttempts > this.maxInitializationAttempts) {
|
|
125
135
|
console.error(
|
|
126
136
|
`BridgeStore[${this.storeName}]: Max initialization attempts (${this.maxInitializationAttempts}) reached, giving up`
|
|
127
137
|
);
|
|
138
|
+
this.isInitializing = false;
|
|
128
139
|
return;
|
|
129
140
|
}
|
|
130
141
|
if (!this.bridge.isConnected) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
if (this.initializationAttempts === 1 || this.initializationAttempts % 3 === 0) {
|
|
143
|
+
console.log(
|
|
144
|
+
`BridgeStore[${this.storeName}]: Waiting for bridge connection (attempt ${this.initializationAttempts}/${this.maxInitializationAttempts})...`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
const delay = Math.min(500 * Math.pow(2, this.initializationAttempts - 1), 5e3);
|
|
148
|
+
this.isInitializing = false;
|
|
149
|
+
this.initializationTimer = setTimeout(() => this.initialize(), delay);
|
|
135
150
|
return;
|
|
136
151
|
}
|
|
137
152
|
const state = await this.bridge.send(`store:${this.storeName}:getState`);
|
|
@@ -142,20 +157,21 @@ class BridgeStore {
|
|
|
142
157
|
}
|
|
143
158
|
this.notifyListeners();
|
|
144
159
|
this.ready = true;
|
|
160
|
+
this.isInitializing = false;
|
|
161
|
+
console.log(`BridgeStore[${this.storeName}]: Initialized successfully`);
|
|
145
162
|
this.notifyReady();
|
|
146
163
|
} catch (error) {
|
|
164
|
+
this.isInitializing = false;
|
|
147
165
|
console.error(
|
|
148
166
|
`BridgeStore[${this.storeName}]: Failed to initialize (attempt ${this.initializationAttempts}):`,
|
|
149
167
|
error
|
|
150
168
|
);
|
|
151
|
-
if (this.
|
|
152
|
-
const delay = Math.min(
|
|
153
|
-
console.
|
|
154
|
-
setTimeout(() => this.initialize(), delay);
|
|
169
|
+
if (this.initializationAttempts < this.maxInitializationAttempts) {
|
|
170
|
+
const delay = Math.min(1e3 * Math.pow(2, this.initializationAttempts - 1), 1e4);
|
|
171
|
+
console.log(`BridgeStore[${this.storeName}]: Retrying initialization in ${delay}ms...`);
|
|
172
|
+
this.initializationTimer = setTimeout(() => this.initialize(), delay);
|
|
155
173
|
} else {
|
|
156
|
-
console.error(
|
|
157
|
-
`BridgeStore[${this.storeName}]: Bridge disconnected or max attempts reached, cannot retry`
|
|
158
|
-
);
|
|
174
|
+
console.error(`BridgeStore[${this.storeName}]: Max attempts reached, cannot retry`);
|
|
159
175
|
}
|
|
160
176
|
}
|
|
161
177
|
};
|
|
@@ -191,9 +207,14 @@ class BridgeStore {
|
|
|
191
207
|
};
|
|
192
208
|
// Additional StoreApi methods
|
|
193
209
|
this.destroy = () => {
|
|
210
|
+
if (this.initializationTimer) {
|
|
211
|
+
clearTimeout(this.initializationTimer);
|
|
212
|
+
this.initializationTimer = null;
|
|
213
|
+
}
|
|
194
214
|
if (this.listeners) {
|
|
195
215
|
this.listeners.clear();
|
|
196
216
|
}
|
|
217
|
+
this.readyCallbacks.clear();
|
|
197
218
|
};
|
|
198
219
|
this.getInitialState = () => {
|
|
199
220
|
return this.getState();
|
|
@@ -244,11 +265,16 @@ class BridgeStore {
|
|
|
244
265
|
this.readyCallbacks.clear();
|
|
245
266
|
};
|
|
246
267
|
/**
|
|
247
|
-
* Force re-initialization of the store (useful for debugging)
|
|
268
|
+
* Force re-initialization of the store (useful for debugging or after reconnection)
|
|
248
269
|
*/
|
|
249
270
|
this.forceInitialize = async () => {
|
|
250
271
|
console.debug(`BridgeStore[${this.storeName}]: Force re-initialization requested`);
|
|
272
|
+
if (this.initializationTimer) {
|
|
273
|
+
clearTimeout(this.initializationTimer);
|
|
274
|
+
this.initializationTimer = null;
|
|
275
|
+
}
|
|
251
276
|
this.ready = false;
|
|
277
|
+
this.isInitializing = false;
|
|
252
278
|
this.initializationAttempts = 0;
|
|
253
279
|
await this.initialize();
|
|
254
280
|
};
|
|
@@ -259,6 +285,7 @@ class BridgeStore {
|
|
|
259
285
|
return {
|
|
260
286
|
storeName: this.storeName,
|
|
261
287
|
ready: this.ready,
|
|
288
|
+
isInitializing: this.isInitializing,
|
|
262
289
|
bridgeConnected: this.bridge.isConnected,
|
|
263
290
|
hasCurrentState: this.currentState !== null,
|
|
264
291
|
hasInitialState: this.initialState !== null,
|
package/dist/index.d.ts
CHANGED
|
@@ -51,11 +51,13 @@ interface Bridge {
|
|
|
51
51
|
}
|
|
52
52
|
interface BridgeWithEvents extends Bridge {
|
|
53
53
|
on?: (key: string, handler: (payload: any) => void) => void;
|
|
54
|
+
off?: (key: string, handler: (payload: any) => void) => void;
|
|
54
55
|
}
|
|
55
56
|
interface BridgeWithHandlers extends Bridge {
|
|
56
57
|
register: (key: string, handler: (payload?: any) => any) => void;
|
|
57
58
|
broadcast: (key: string, payload: any) => void;
|
|
58
59
|
on?: (key: string, handler: (payload: any) => void) => void;
|
|
60
|
+
off?: (key: string, handler: (payload: any) => void) => void;
|
|
59
61
|
}
|
|
60
62
|
declare class BridgeStore<T> implements CentralStore<T> {
|
|
61
63
|
private bridge;
|
|
@@ -68,6 +70,8 @@ declare class BridgeStore<T> implements CentralStore<T> {
|
|
|
68
70
|
private readyCallbacks;
|
|
69
71
|
private initializationAttempts;
|
|
70
72
|
private readonly maxInitializationAttempts;
|
|
73
|
+
private initializationTimer;
|
|
74
|
+
private isInitializing;
|
|
71
75
|
constructor(bridge: BridgeWithEvents, initialState?: T, storeName?: string, readyCallbacks?: Set<() => void>);
|
|
72
76
|
initialize: () => Promise<void>;
|
|
73
77
|
private stateSyncSequence;
|
|
@@ -86,7 +90,7 @@ declare class BridgeStore<T> implements CentralStore<T> {
|
|
|
86
90
|
reset: () => void;
|
|
87
91
|
private notifyReady;
|
|
88
92
|
/**
|
|
89
|
-
* Force re-initialization of the store (useful for debugging)
|
|
93
|
+
* Force re-initialization of the store (useful for debugging or after reconnection)
|
|
90
94
|
*/
|
|
91
95
|
forceInitialize: () => Promise<void>;
|
|
92
96
|
/**
|
|
@@ -95,6 +99,7 @@ declare class BridgeStore<T> implements CentralStore<T> {
|
|
|
95
99
|
getDebugInfo: () => {
|
|
96
100
|
storeName: string;
|
|
97
101
|
ready: boolean;
|
|
102
|
+
isInitializing: boolean;
|
|
98
103
|
bridgeConnected: boolean;
|
|
99
104
|
hasCurrentState: boolean;
|
|
100
105
|
hasInitialState: boolean;
|
package/dist/index.es.js
CHANGED
|
@@ -98,20 +98,35 @@ class BridgeStore {
|
|
|
98
98
|
this.readyCallbacks = /* @__PURE__ */ new Set();
|
|
99
99
|
this.initializationAttempts = 0;
|
|
100
100
|
this.maxInitializationAttempts = 10;
|
|
101
|
+
this.initializationTimer = null;
|
|
102
|
+
this.isInitializing = false;
|
|
101
103
|
this.initialize = async () => {
|
|
104
|
+
if (this.isInitializing) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (this.initializationTimer) {
|
|
108
|
+
clearTimeout(this.initializationTimer);
|
|
109
|
+
this.initializationTimer = null;
|
|
110
|
+
}
|
|
102
111
|
this.initializationAttempts++;
|
|
112
|
+
this.isInitializing = true;
|
|
103
113
|
try {
|
|
104
114
|
if (this.initializationAttempts > this.maxInitializationAttempts) {
|
|
105
115
|
console.error(
|
|
106
116
|
`BridgeStore[${this.storeName}]: Max initialization attempts (${this.maxInitializationAttempts}) reached, giving up`
|
|
107
117
|
);
|
|
118
|
+
this.isInitializing = false;
|
|
108
119
|
return;
|
|
109
120
|
}
|
|
110
121
|
if (!this.bridge.isConnected) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
if (this.initializationAttempts === 1 || this.initializationAttempts % 3 === 0) {
|
|
123
|
+
console.log(
|
|
124
|
+
`BridgeStore[${this.storeName}]: Waiting for bridge connection (attempt ${this.initializationAttempts}/${this.maxInitializationAttempts})...`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
const delay = Math.min(500 * Math.pow(2, this.initializationAttempts - 1), 5e3);
|
|
128
|
+
this.isInitializing = false;
|
|
129
|
+
this.initializationTimer = setTimeout(() => this.initialize(), delay);
|
|
115
130
|
return;
|
|
116
131
|
}
|
|
117
132
|
const state = await this.bridge.send(`store:${this.storeName}:getState`);
|
|
@@ -122,20 +137,21 @@ class BridgeStore {
|
|
|
122
137
|
}
|
|
123
138
|
this.notifyListeners();
|
|
124
139
|
this.ready = true;
|
|
140
|
+
this.isInitializing = false;
|
|
141
|
+
console.log(`BridgeStore[${this.storeName}]: Initialized successfully`);
|
|
125
142
|
this.notifyReady();
|
|
126
143
|
} catch (error) {
|
|
144
|
+
this.isInitializing = false;
|
|
127
145
|
console.error(
|
|
128
146
|
`BridgeStore[${this.storeName}]: Failed to initialize (attempt ${this.initializationAttempts}):`,
|
|
129
147
|
error
|
|
130
148
|
);
|
|
131
|
-
if (this.
|
|
132
|
-
const delay = Math.min(
|
|
133
|
-
console.
|
|
134
|
-
setTimeout(() => this.initialize(), delay);
|
|
149
|
+
if (this.initializationAttempts < this.maxInitializationAttempts) {
|
|
150
|
+
const delay = Math.min(1e3 * Math.pow(2, this.initializationAttempts - 1), 1e4);
|
|
151
|
+
console.log(`BridgeStore[${this.storeName}]: Retrying initialization in ${delay}ms...`);
|
|
152
|
+
this.initializationTimer = setTimeout(() => this.initialize(), delay);
|
|
135
153
|
} else {
|
|
136
|
-
console.error(
|
|
137
|
-
`BridgeStore[${this.storeName}]: Bridge disconnected or max attempts reached, cannot retry`
|
|
138
|
-
);
|
|
154
|
+
console.error(`BridgeStore[${this.storeName}]: Max attempts reached, cannot retry`);
|
|
139
155
|
}
|
|
140
156
|
}
|
|
141
157
|
};
|
|
@@ -171,9 +187,14 @@ class BridgeStore {
|
|
|
171
187
|
};
|
|
172
188
|
// Additional StoreApi methods
|
|
173
189
|
this.destroy = () => {
|
|
190
|
+
if (this.initializationTimer) {
|
|
191
|
+
clearTimeout(this.initializationTimer);
|
|
192
|
+
this.initializationTimer = null;
|
|
193
|
+
}
|
|
174
194
|
if (this.listeners) {
|
|
175
195
|
this.listeners.clear();
|
|
176
196
|
}
|
|
197
|
+
this.readyCallbacks.clear();
|
|
177
198
|
};
|
|
178
199
|
this.getInitialState = () => {
|
|
179
200
|
return this.getState();
|
|
@@ -224,11 +245,16 @@ class BridgeStore {
|
|
|
224
245
|
this.readyCallbacks.clear();
|
|
225
246
|
};
|
|
226
247
|
/**
|
|
227
|
-
* Force re-initialization of the store (useful for debugging)
|
|
248
|
+
* Force re-initialization of the store (useful for debugging or after reconnection)
|
|
228
249
|
*/
|
|
229
250
|
this.forceInitialize = async () => {
|
|
230
251
|
console.debug(`BridgeStore[${this.storeName}]: Force re-initialization requested`);
|
|
252
|
+
if (this.initializationTimer) {
|
|
253
|
+
clearTimeout(this.initializationTimer);
|
|
254
|
+
this.initializationTimer = null;
|
|
255
|
+
}
|
|
231
256
|
this.ready = false;
|
|
257
|
+
this.isInitializing = false;
|
|
232
258
|
this.initializationAttempts = 0;
|
|
233
259
|
await this.initialize();
|
|
234
260
|
};
|
|
@@ -239,6 +265,7 @@ class BridgeStore {
|
|
|
239
265
|
return {
|
|
240
266
|
storeName: this.storeName,
|
|
241
267
|
ready: this.ready,
|
|
268
|
+
isInitializing: this.isInitializing,
|
|
242
269
|
bridgeConnected: this.bridge.isConnected,
|
|
243
270
|
hasCurrentState: this.currentState !== null,
|
|
244
271
|
hasInitialState: this.initialState !== null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chromahq/store",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Centralized, persistent store for Chrome extensions using zustand, accessible from service workers and React, with chrome.storage.local persistence.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs.js",
|