@omnistreamai/data-core 0.1.0 → 0.1.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @omnistreamai/data-core
2
+
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Initial release of data-sync packages
8
+
9
+ ## 0.1.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Publish beta version with ESM and CJS support
package/dist/index.d.mts CHANGED
@@ -167,8 +167,8 @@ type Adapter = LocalAdapter | RemoteAdapter;
167
167
  interface StoreOptions<_T extends Record<string, unknown>> {
168
168
  localAdapter: LocalAdapter | null;
169
169
  remoteAdapter: RemoteAdapter | null;
170
- idKey: string;
171
- indexes?: string[];
170
+ idKey: keyof _T;
171
+ indexes?: Array<keyof _T>;
172
172
  /**
173
173
  * Maximum number of local storage entries
174
174
  * When local storage entries exceed this limit, oldest entries will be automatically deleted
@@ -182,7 +182,7 @@ interface StoreOptions<_T extends Record<string, unknown>> {
182
182
  * If not specified, entries will be deleted in default array order (usually insertion order)
183
183
  * Supports number and string type field values
184
184
  */
185
- sortByKey?: string;
185
+ sortByKey?: keyof _T;
186
186
  onChange?: () => void;
187
187
  notThrowLocalError: boolean;
188
188
  }
@@ -243,7 +243,7 @@ declare class Store<T extends Record<string, unknown>> {
243
243
  /**
244
244
  * Get query object for list data
245
245
  */
246
- getListQuery(options?: QueryOptions<T>): Promise<QueryResult<T[]>>;
246
+ getListQuery(options?: QueryOptions<T>): QueryResult<T[]>;
247
247
  /**
248
248
  * Clear store
249
249
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/store.ts","../src/sync-manager.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/store.ts","../src/sync-manager.ts"],"sourcesContent":[],"mappings":"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"}
@@ -0,0 +1,290 @@
1
+ //#region src/types.d.ts
2
+ /**
3
+ * Adapter type: local or remote
4
+ */
5
+ declare enum AdapterType {
6
+ Local = "local",
7
+ Remote = "remote",
8
+ }
9
+ /**
10
+ * Authentication type
11
+ */
12
+ declare enum AuthType {
13
+ Token = "token",
14
+ Basic = "basic",
15
+ Bearer = "bearer",
16
+ }
17
+ /**
18
+ * Token authentication configuration
19
+ */
20
+ interface TokenAuth {
21
+ access_token: string;
22
+ token_type: string;
23
+ expires_in?: number;
24
+ refresh_token?: string;
25
+ [key: string]: unknown;
26
+ }
27
+ /**
28
+ * Authentication configuration
29
+ */
30
+ interface Authentication {
31
+ authType: AuthType;
32
+ token?: TokenAuth;
33
+ username?: string;
34
+ password?: string;
35
+ bearer?: string;
36
+ }
37
+ /**
38
+ * Service configuration (for remote adapters)
39
+ */
40
+ interface ServiceConfig {
41
+ endpoint: string;
42
+ authentication?: Authentication;
43
+ }
44
+ /**
45
+ * Query options
46
+ */
47
+ interface QueryOptions<T = Record<string, unknown>> {
48
+ source?: 'local' | 'remote';
49
+ page?: number;
50
+ limit?: number;
51
+ where?: Partial<T>;
52
+ }
53
+ /**
54
+ * Paginated result
55
+ */
56
+ interface PaginatedResult<T> {
57
+ data: T[];
58
+ totalCount: number;
59
+ page: number;
60
+ limit: number;
61
+ }
62
+ /**
63
+ * Query function and initial data (for React Query, etc.)
64
+ */
65
+ interface QueryResult<T> {
66
+ queryKey: unknown[];
67
+ queryFn: () => Promise<T>;
68
+ getInitialData: () => Promise<T>;
69
+ }
70
+ /**
71
+ * Store configuration
72
+ */
73
+ interface StoreConfig {
74
+ indexes?: string[];
75
+ idKey?: string;
76
+ maxLocalEntries?: number;
77
+ onChange?: () => void;
78
+ }
79
+ /**
80
+ * Base adapter interface
81
+ */
82
+ interface BaseAdapter {
83
+ readonly type: AdapterType;
84
+ readonly name: string;
85
+ }
86
+ /**
87
+ * Local adapter interface
88
+ */
89
+ interface LocalAdapter extends BaseAdapter {
90
+ readonly type: AdapterType.Local;
91
+ /**
92
+ * Add data
93
+ */
94
+ add<T extends Record<string, unknown>>(storeName: string, data: T, idKey?: string): Promise<T>;
95
+ /**
96
+ * Update data
97
+ */
98
+ update<T extends Record<string, unknown>>(storeName: string, id: string, data: Partial<T>, idKey?: string): Promise<T>;
99
+ /**
100
+ * Delete data
101
+ */
102
+ delete(storeName: string, id: string, idKey?: string): Promise<void>;
103
+ /**
104
+ * Get data by ID
105
+ */
106
+ getData<T extends Record<string, unknown>>(storeName: string, id: string, idKey?: string): Promise<T | null>;
107
+ /**
108
+ * Get list data (with pagination support)
109
+ */
110
+ getList<T extends Record<string, unknown>>(storeName: string, options?: QueryOptions<T>, idKey?: string): Promise<T[]>;
111
+ /**
112
+ * Clear store
113
+ */
114
+ clear(storeName: string): Promise<void>;
115
+ /**
116
+ * Initialize store
117
+ */
118
+ initStore(storeName: string, indexes?: string[], idKey?: string): Promise<void>;
119
+ }
120
+ /**
121
+ * Remote adapter interface
122
+ */
123
+ interface RemoteAdapter extends BaseAdapter {
124
+ readonly type: AdapterType.Remote;
125
+ /**
126
+ * 添加数据
127
+ */
128
+ add<T extends Record<string, unknown>>(storeName: string, data: T, idKey?: string): Promise<T>;
129
+ /**
130
+ * Update data
131
+ */
132
+ update<T extends Record<string, unknown>>(storeName: string, id: string, data: Partial<T>, idKey?: string): Promise<T>;
133
+ /**
134
+ * Delete data
135
+ */
136
+ delete(storeName: string, id: string, idKey?: string): Promise<void>;
137
+ /**
138
+ * Get data by ID
139
+ */
140
+ getData<T extends Record<string, unknown>>(storeName: string, id: string, idKey?: string): Promise<T | null>;
141
+ /**
142
+ * Get list data (with pagination support)
143
+ */
144
+ getList<T extends Record<string, unknown>>(storeName: string, options?: QueryOptions<T>, idKey?: string): Promise<PaginatedResult<T>>;
145
+ /**
146
+ * Clear store
147
+ */
148
+ clear(storeName: string): Promise<void>;
149
+ /**
150
+ * Initialize store (create if not exists)
151
+ */
152
+ initStore(storeName: string, indexes?: string[], idKey?: string): Promise<void>;
153
+ /**
154
+ * Set service configuration
155
+ */
156
+ setService(service: ServiceConfig): void;
157
+ }
158
+ /**
159
+ * Adapter union type
160
+ */
161
+ type Adapter = LocalAdapter | RemoteAdapter;
162
+ //#endregion
163
+ //#region src/store.d.ts
164
+ /**
165
+ * Store configuration
166
+ */
167
+ interface StoreOptions<_T extends Record<string, unknown>> {
168
+ localAdapter: LocalAdapter | null;
169
+ remoteAdapter: RemoteAdapter | null;
170
+ idKey: keyof _T;
171
+ indexes?: Array<keyof _T>;
172
+ /**
173
+ * Maximum number of local storage entries
174
+ * When local storage entries exceed this limit, oldest entries will be automatically deleted
175
+ * Can be used with sortByKey parameter to specify sorting field for deletion order
176
+ * If not set, no limit on local storage entries
177
+ */
178
+ maxLocalEntries?: number;
179
+ /**
180
+ * Field name for sorting when maxLocalEntries is in effect
181
+ * If this field is specified, entries will be sorted by this field's value before deleting oldest entries
182
+ * If not specified, entries will be deleted in default array order (usually insertion order)
183
+ * Supports number and string type field values
184
+ */
185
+ sortByKey?: keyof _T;
186
+ onChange?: () => void;
187
+ notThrowLocalError: boolean;
188
+ }
189
+ /**
190
+ * Store class
191
+ */
192
+ declare class Store<T extends Record<string, unknown>> {
193
+ private storeName;
194
+ private localAdapter;
195
+ private remoteAdapter;
196
+ private idKey;
197
+ private indexes?;
198
+ private maxLocalEntries?;
199
+ private sortByKey?;
200
+ private onChange?;
201
+ private notThrowLocalError;
202
+ private initialized;
203
+ constructor(storeName: string, options: StoreOptions<T>);
204
+ /**
205
+ * Initialize Store
206
+ */
207
+ init(): Promise<void>;
208
+ private ensureInitialized;
209
+ private triggerChange;
210
+ private executeLocal;
211
+ private executeRemote;
212
+ /**
213
+ * Enforce maximum local storage entries limit
214
+ */
215
+ private enforceMaxLocalEntries;
216
+ /**
217
+ * Sort entries by specified field
218
+ * @param entries Array of entries to sort
219
+ * @param key Sorting field name
220
+ * @returns Sorted array of entries
221
+ */
222
+ private sortEntries;
223
+ /**
224
+ * Add data
225
+ */
226
+ add(data: T): Promise<T>;
227
+ /**
228
+ * Update data
229
+ */
230
+ update(id: string, data: Partial<T>): Promise<T>;
231
+ /**
232
+ * Delete data
233
+ */
234
+ delete(id: string): Promise<void>;
235
+ /**
236
+ * Get data by ID
237
+ */
238
+ getData(id: string): Promise<T | null>;
239
+ /**
240
+ * Get list data
241
+ */
242
+ getList(options?: QueryOptions<T>): Promise<T[]>;
243
+ /**
244
+ * Get query object for list data
245
+ */
246
+ getListQuery(options?: QueryOptions<T>): QueryResult<T[]>;
247
+ /**
248
+ * Clear store
249
+ */
250
+ clear(): Promise<void>;
251
+ }
252
+ //#endregion
253
+ //#region src/sync-manager.d.ts
254
+ /**
255
+ * SyncManager configuration options
256
+ */
257
+ interface SyncManagerOptions {
258
+ localAdapter?: LocalAdapter;
259
+ remoteAdapter?: RemoteAdapter;
260
+ notThrowLocalError?: boolean;
261
+ }
262
+ /**
263
+ * Sync manager
264
+ */
265
+ declare class SyncManager {
266
+ private localAdapter;
267
+ private remoteAdapter;
268
+ private notThrowLocalError;
269
+ private stores;
270
+ constructor(options?: SyncManagerOptions);
271
+ /**
272
+ * Set local adapter
273
+ */
274
+ setLocalAdapter(adapter: LocalAdapter): void;
275
+ /**
276
+ * Set remote adapter
277
+ */
278
+ setRemoteAdapter(adapter: RemoteAdapter): void;
279
+ /**
280
+ * Create Store
281
+ */
282
+ createStore<T extends Record<string, unknown>>(storeName: string, config?: StoreConfig): Store<T>;
283
+ }
284
+ /**
285
+ * Create sync manager
286
+ */
287
+ declare function createSyncManager(options?: SyncManagerOptions): SyncManager;
288
+ //#endregion
289
+ export { Adapter, AdapterType, AuthType, Authentication, BaseAdapter, LocalAdapter, PaginatedResult, QueryOptions, QueryResult, RemoteAdapter, ServiceConfig, Store, StoreConfig, StoreOptions, SyncManager, SyncManagerOptions, TokenAuth, createSyncManager };
290
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/store.ts","../src/sync-manager.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,307 @@
1
+
2
+ //#region src/types.ts
3
+ /**
4
+ * Adapter type: local or remote
5
+ */
6
+ let AdapterType = /* @__PURE__ */ function(AdapterType$1) {
7
+ AdapterType$1["Local"] = "local";
8
+ AdapterType$1["Remote"] = "remote";
9
+ return AdapterType$1;
10
+ }({});
11
+ /**
12
+ * Authentication type
13
+ */
14
+ let AuthType = /* @__PURE__ */ function(AuthType$1) {
15
+ AuthType$1["Token"] = "token";
16
+ AuthType$1["Basic"] = "basic";
17
+ AuthType$1["Bearer"] = "bearer";
18
+ return AuthType$1;
19
+ }({});
20
+
21
+ //#endregion
22
+ //#region src/store.ts
23
+ /**
24
+ * Store class
25
+ */
26
+ var Store = class {
27
+ storeName;
28
+ localAdapter;
29
+ remoteAdapter;
30
+ idKey;
31
+ indexes;
32
+ maxLocalEntries;
33
+ sortByKey;
34
+ onChange;
35
+ notThrowLocalError;
36
+ initialized = false;
37
+ constructor(storeName, options) {
38
+ this.storeName = storeName;
39
+ this.localAdapter = options.localAdapter;
40
+ this.remoteAdapter = options.remoteAdapter;
41
+ this.idKey = options.idKey;
42
+ this.indexes = options.indexes;
43
+ this.maxLocalEntries = options.maxLocalEntries;
44
+ this.sortByKey = options.sortByKey;
45
+ this.onChange = options.onChange;
46
+ this.notThrowLocalError = options.notThrowLocalError;
47
+ }
48
+ /**
49
+ * Initialize Store
50
+ */
51
+ async init() {
52
+ if (this.initialized) return;
53
+ const promises = [];
54
+ if (this.localAdapter) promises.push(this.executeLocal(() => this.localAdapter.initStore(this.storeName, this.indexes, this.idKey)));
55
+ if (this.remoteAdapter) promises.push(this.executeRemote(() => this.remoteAdapter.initStore(this.storeName, this.indexes, this.idKey)));
56
+ await Promise.all(promises);
57
+ this.initialized = true;
58
+ }
59
+ async ensureInitialized() {
60
+ if (!this.initialized) await this.init();
61
+ }
62
+ triggerChange() {
63
+ if (this.onChange) this.onChange();
64
+ }
65
+ async executeLocal(operation) {
66
+ if (!this.localAdapter) return null;
67
+ try {
68
+ return await operation();
69
+ } catch (error) {
70
+ if (this.notThrowLocalError) {
71
+ console.warn("Local adapter error:", error);
72
+ return null;
73
+ }
74
+ throw error;
75
+ }
76
+ }
77
+ async executeRemote(operation) {
78
+ return await operation();
79
+ }
80
+ /**
81
+ * Enforce maximum local storage entries limit
82
+ */
83
+ async enforceMaxLocalEntries() {
84
+ if (!this.localAdapter || !this.maxLocalEntries) return;
85
+ try {
86
+ let currentEntries = await this.localAdapter.getList(this.storeName, {}, this.idKey);
87
+ if (currentEntries.length > this.maxLocalEntries) {
88
+ if (this.sortByKey) currentEntries = this.sortEntries(currentEntries, this.sortByKey);
89
+ const entriesToDelete = currentEntries.length - this.maxLocalEntries;
90
+ for (let i = 0; i < entriesToDelete; i++) {
91
+ const entryToDelete = currentEntries[i];
92
+ if (entryToDelete) {
93
+ const id = String(entryToDelete[this.idKey]);
94
+ await this.executeLocal(() => this.localAdapter.delete(this.storeName, id, this.idKey));
95
+ }
96
+ }
97
+ }
98
+ } catch (error) {
99
+ if (this.notThrowLocalError) console.warn("Failed to enforce max local entries:", error);
100
+ else throw error;
101
+ }
102
+ }
103
+ /**
104
+ * Sort entries by specified field
105
+ * @param entries Array of entries to sort
106
+ * @param key Sorting field name
107
+ * @returns Sorted array of entries
108
+ */
109
+ sortEntries(entries, key) {
110
+ return [...entries].sort((a, b) => {
111
+ const aValue = a[key];
112
+ const bValue = b[key];
113
+ if (aValue == null && bValue == null) return 0;
114
+ if (aValue == null) return 1;
115
+ if (bValue == null) return -1;
116
+ if (typeof aValue === "number" && typeof bValue === "number") return aValue - bValue;
117
+ if (typeof aValue === "string" && typeof bValue === "string") return aValue.localeCompare(bValue);
118
+ if (typeof aValue === "string" && typeof bValue === "string") {
119
+ const aDate = new Date(aValue);
120
+ const bDate = new Date(bValue);
121
+ if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) return aDate.getTime() - bDate.getTime();
122
+ }
123
+ return String(aValue).localeCompare(String(bValue));
124
+ });
125
+ }
126
+ /**
127
+ * Add data
128
+ */
129
+ async add(data) {
130
+ await this.ensureInitialized();
131
+ const promises = [];
132
+ if (this.localAdapter) {
133
+ const localResult = await this.executeLocal(() => this.localAdapter.add(this.storeName, data, this.idKey));
134
+ if (localResult) {
135
+ promises.push(Promise.resolve(localResult));
136
+ await this.enforceMaxLocalEntries();
137
+ }
138
+ }
139
+ if (this.remoteAdapter) promises.push(this.remoteAdapter.add(this.storeName, data, this.idKey));
140
+ await Promise.all(promises);
141
+ this.triggerChange();
142
+ return data;
143
+ }
144
+ /**
145
+ * Update data
146
+ */
147
+ async update(id, data) {
148
+ await this.ensureInitialized();
149
+ const promises = [];
150
+ if (this.localAdapter) {
151
+ const localResult = await this.executeLocal(() => this.localAdapter.update(this.storeName, id, data, this.idKey));
152
+ if (localResult) promises.push(Promise.resolve(localResult));
153
+ }
154
+ if (this.remoteAdapter) promises.push(this.remoteAdapter.update(this.storeName, id, data, this.idKey));
155
+ const results = await Promise.all(promises);
156
+ this.triggerChange();
157
+ return results.find((result) => result !== null && result !== void 0);
158
+ }
159
+ /**
160
+ * Delete data
161
+ */
162
+ async delete(id) {
163
+ await this.ensureInitialized();
164
+ const promises = [];
165
+ if (this.localAdapter) promises.push(this.executeLocal(() => this.localAdapter.delete(this.storeName, id, this.idKey)));
166
+ if (this.remoteAdapter) promises.push(this.remoteAdapter.delete(this.storeName, id, this.idKey));
167
+ await Promise.all(promises);
168
+ this.triggerChange();
169
+ }
170
+ /**
171
+ * Get data by ID
172
+ */
173
+ async getData(id) {
174
+ await this.ensureInitialized();
175
+ if (this.localAdapter) try {
176
+ const localResult = await this.executeLocal(() => this.localAdapter.getData(this.storeName, id, this.idKey));
177
+ if (localResult) return localResult;
178
+ } catch (error) {
179
+ if (!this.notThrowLocalError) throw error;
180
+ }
181
+ if (this.remoteAdapter) return await this.remoteAdapter.getData(this.storeName, id, this.idKey);
182
+ return null;
183
+ }
184
+ /**
185
+ * Get list data
186
+ */
187
+ async getList(options = {}) {
188
+ await this.ensureInitialized();
189
+ const source = options.source;
190
+ if (source === "local" && this.localAdapter) return await this.localAdapter.getList(this.storeName, options, this.idKey);
191
+ if (source === "remote" && this.remoteAdapter) return (await this.remoteAdapter.getList(this.storeName, options, this.idKey)).data;
192
+ if (this.remoteAdapter) try {
193
+ const result = await this.remoteAdapter.getList(this.storeName, options, this.idKey);
194
+ if (this.localAdapter && result.data.length > 0) {
195
+ await Promise.all(result.data.map((item) => this.executeLocal(() => this.localAdapter.add(this.storeName, item, this.idKey))));
196
+ await this.enforceMaxLocalEntries();
197
+ }
198
+ return result.data;
199
+ } catch (error) {
200
+ if (this.localAdapter) return await this.localAdapter.getList(this.storeName, options, this.idKey);
201
+ throw error;
202
+ }
203
+ if (this.localAdapter) return await this.localAdapter.getList(this.storeName, options, this.idKey);
204
+ return [];
205
+ }
206
+ /**
207
+ * Get query object for list data
208
+ */
209
+ getListQuery(options = {}) {
210
+ const source = options.source;
211
+ const queryKey = [
212
+ "store",
213
+ this.storeName,
214
+ source || "default",
215
+ options
216
+ ];
217
+ const queryFn = async () => {
218
+ return this.getList(options);
219
+ };
220
+ const getInitialData = async () => {
221
+ await this.ensureInitialized();
222
+ if (this.localAdapter) try {
223
+ return await this.localAdapter.getList(this.storeName, options, this.idKey);
224
+ } catch (error) {
225
+ return [];
226
+ }
227
+ return [];
228
+ };
229
+ return {
230
+ queryKey,
231
+ queryFn,
232
+ getInitialData
233
+ };
234
+ }
235
+ /**
236
+ * Clear store
237
+ */
238
+ async clear() {
239
+ await this.ensureInitialized();
240
+ const promises = [];
241
+ if (this.localAdapter) await this.executeLocal(() => this.localAdapter.clear(this.storeName));
242
+ if (this.remoteAdapter) promises.push(this.remoteAdapter.clear(this.storeName));
243
+ await Promise.all(promises);
244
+ this.triggerChange();
245
+ }
246
+ };
247
+
248
+ //#endregion
249
+ //#region src/sync-manager.ts
250
+ /**
251
+ * Sync manager
252
+ */
253
+ var SyncManager = class {
254
+ localAdapter = null;
255
+ remoteAdapter = null;
256
+ notThrowLocalError;
257
+ stores = /* @__PURE__ */ new Map();
258
+ constructor(options = {}) {
259
+ this.localAdapter = options.localAdapter ?? null;
260
+ this.remoteAdapter = options.remoteAdapter ?? null;
261
+ this.notThrowLocalError = options.notThrowLocalError ?? false;
262
+ }
263
+ /**
264
+ * Set local adapter
265
+ */
266
+ setLocalAdapter(adapter) {
267
+ this.localAdapter = adapter;
268
+ }
269
+ /**
270
+ * Set remote adapter
271
+ */
272
+ setRemoteAdapter(adapter) {
273
+ this.remoteAdapter = adapter;
274
+ }
275
+ /**
276
+ * Create Store
277
+ */
278
+ createStore(storeName, config = {}) {
279
+ const existingStore = this.stores.get(storeName);
280
+ if (existingStore) return existingStore;
281
+ const store = new Store(storeName, {
282
+ localAdapter: this.localAdapter,
283
+ remoteAdapter: this.remoteAdapter,
284
+ idKey: config.idKey ?? "id",
285
+ indexes: config.indexes,
286
+ maxLocalEntries: config.maxLocalEntries,
287
+ onChange: config.onChange,
288
+ notThrowLocalError: this.notThrowLocalError
289
+ });
290
+ this.stores.set(storeName, store);
291
+ return store;
292
+ }
293
+ };
294
+ /**
295
+ * Create sync manager
296
+ */
297
+ function createSyncManager(options = {}) {
298
+ return new SyncManager(options);
299
+ }
300
+
301
+ //#endregion
302
+ exports.AdapterType = AdapterType;
303
+ exports.AuthType = AuthType;
304
+ exports.Store = Store;
305
+ exports.SyncManager = SyncManager;
306
+ exports.createSyncManager = createSyncManager;
307
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["promises: Promise<void | null>[]","promises: Promise<T>[]","promises: Promise<void>[]"],"sources":["../src/types.ts","../src/store.ts","../src/sync-manager.ts"],"sourcesContent":["/**\n * Adapter type: local or remote\n */\nexport enum AdapterType {\n Local = 'local',\n Remote = 'remote',\n}\n\n/**\n * Authentication type\n */\nexport enum AuthType {\n Token = 'token',\n Basic = 'basic',\n Bearer = 'bearer',\n}\n\n/**\n * Token authentication configuration\n */\nexport interface TokenAuth {\n access_token: string;\n token_type: string;\n expires_in?: number;\n refresh_token?: string;\n [key: string]: unknown;\n}\n\n/**\n * Authentication configuration\n */\nexport interface Authentication {\n authType: AuthType;\n token?: TokenAuth;\n username?: string;\n password?: string;\n bearer?: string;\n}\n\n/**\n * Service configuration (for remote adapters)\n */\nexport interface ServiceConfig {\n endpoint: string;\n authentication?: Authentication;\n}\n\n/**\n * Query options\n */\nexport interface QueryOptions<T = Record<string, unknown>> {\n source?: 'local' | 'remote';\n page?: number;\n limit?: number;\n where?: Partial<T>;\n}\n\n/**\n * Paginated result\n */\nexport interface PaginatedResult<T> {\n data: T[];\n totalCount: number;\n page: number;\n limit: number;\n}\n\n/**\n * Query function and initial data (for React Query, etc.)\n */\nexport interface QueryResult<T> {\n queryKey: unknown[];\n queryFn: () => Promise<T>;\n getInitialData: () => Promise<T>;\n}\n\n/**\n * Store configuration\n */\nexport interface StoreConfig {\n indexes?: string[];\n idKey?: string;\n maxLocalEntries?: number;\n onChange?: () => void;\n}\n\n/**\n * Base adapter interface\n */\nexport interface BaseAdapter {\n readonly type: AdapterType;\n readonly name: string;\n}\n\n/**\n * Local adapter interface\n */\nexport interface LocalAdapter extends BaseAdapter {\n readonly type: AdapterType.Local;\n \n /**\n * Add data\n */\n add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Update data\n */\n update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Delete data\n */\n delete(storeName: string, id: string, idKey?: string): Promise<void>;\n \n /**\n * Get data by ID\n */\n getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n idKey?: string\n ): Promise<T | null>;\n \n /**\n * Get list data (with pagination support)\n */\n getList<T extends Record<string, unknown>>(\n storeName: string,\n options?: QueryOptions<T>,\n idKey?: string\n ): Promise<T[]>;\n \n /**\n * Clear store\n */\n clear(storeName: string): Promise<void>;\n \n /**\n * Initialize store\n */\n initStore(\n storeName: string,\n indexes?: string[],\n idKey?: string\n ): Promise<void>;\n}\n\n/**\n * Remote adapter interface\n */\nexport interface RemoteAdapter extends BaseAdapter {\n readonly type: AdapterType.Remote;\n \n /**\n * 添加数据\n */\n add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Update data\n */\n update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Delete data\n */\n delete(storeName: string, id: string, idKey?: string): Promise<void>;\n \n /**\n * Get data by ID\n */\n getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n idKey?: string\n ): Promise<T | null>;\n \n /**\n * Get list data (with pagination support)\n */\n getList<T extends Record<string, unknown>>(\n storeName: string,\n options?: QueryOptions<T>,\n idKey?: string\n ): Promise<PaginatedResult<T>>;\n \n /**\n * Clear store\n */\n clear(storeName: string): Promise<void>;\n \n /**\n * Initialize store (create if not exists)\n */\n initStore(\n storeName: string,\n indexes?: string[],\n idKey?: string\n ): Promise<void>;\n \n /**\n * Set service configuration\n */\n setService(service: ServiceConfig): void;\n}\n\n/**\n * Adapter union type\n */\nexport type Adapter = LocalAdapter | RemoteAdapter;\n\n","import {\n type LocalAdapter,\n type RemoteAdapter,\n type QueryOptions,\n type QueryResult,\n} from \"./types.js\";\n\n/**\n * Store configuration\n */\nexport interface StoreOptions<_T extends Record<string, unknown>> {\n localAdapter: LocalAdapter | null;\n remoteAdapter: RemoteAdapter | null;\n idKey: keyof _T;\n indexes?: Array<keyof _T>;\n /**\n * Maximum number of local storage entries\n * When local storage entries exceed this limit, oldest entries will be automatically deleted\n * Can be used with sortByKey parameter to specify sorting field for deletion order\n * If not set, no limit on local storage entries\n */\n maxLocalEntries?: number;\n /**\n * Field name for sorting when maxLocalEntries is in effect\n * If this field is specified, entries will be sorted by this field's value before deleting oldest entries\n * If not specified, entries will be deleted in default array order (usually insertion order)\n * Supports number and string type field values\n */\n sortByKey?: keyof _T;\n onChange?: () => void;\n notThrowLocalError: boolean;\n}\n\n/**\n * Store class\n */\nexport class Store<T extends Record<string, unknown>> {\n private storeName: string;\n private localAdapter: LocalAdapter | null;\n private remoteAdapter: RemoteAdapter | null;\n private idKey: string;\n private indexes?: string[];\n private maxLocalEntries?: number;\n private sortByKey?: string;\n private onChange?: () => void;\n private notThrowLocalError: boolean;\n private initialized = false;\n\n constructor(storeName: string, options: StoreOptions<T>) {\n this.storeName = storeName;\n this.localAdapter = options.localAdapter;\n this.remoteAdapter = options.remoteAdapter;\n this.idKey = options.idKey as string;\n this.indexes = options.indexes as string[];\n this.maxLocalEntries = options.maxLocalEntries;\n this.sortByKey = options.sortByKey as string;\n this.onChange = options.onChange;\n this.notThrowLocalError = options.notThrowLocalError;\n }\n\n /**\n * Initialize Store\n */\n async init(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n const promises: Promise<void | null>[] = [];\n\n if (this.localAdapter) {\n promises.push(\n this.executeLocal(() =>\n this.localAdapter!.initStore(\n this.storeName,\n this.indexes,\n this.idKey,\n ),\n ),\n );\n }\n\n if (this.remoteAdapter) {\n promises.push(\n this.executeRemote(() =>\n this.remoteAdapter!.initStore(\n this.storeName,\n this.indexes,\n this.idKey,\n ),\n ),\n );\n }\n\n await Promise.all(promises);\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.init();\n }\n }\n\n private triggerChange(): void {\n if (this.onChange) {\n this.onChange();\n }\n }\n\n private async executeLocal<TResult>(\n operation: () => Promise<TResult>,\n ): Promise<TResult | null> {\n if (!this.localAdapter) {\n return null;\n }\n\n try {\n return await operation();\n } catch (error) {\n if (this.notThrowLocalError) {\n console.warn(\"Local adapter error:\", error);\n return null;\n }\n throw error;\n }\n }\n\n private async executeRemote<TResult>(\n operation: () => Promise<TResult>,\n ): Promise<TResult> {\n return await operation();\n }\n\n /**\n * Enforce maximum local storage entries limit\n */\n private async enforceMaxLocalEntries(): Promise<void> {\n if (!this.localAdapter || !this.maxLocalEntries) {\n return;\n }\n\n try {\n let currentEntries = await this.localAdapter.getList<T>(\n this.storeName,\n {},\n this.idKey,\n );\n\n if (currentEntries.length > this.maxLocalEntries) {\n // If sorting field is specified, sort by that field\n if (this.sortByKey) {\n currentEntries = this.sortEntries(currentEntries, this.sortByKey);\n }\n\n // Calculate number of entries to delete\n const entriesToDelete = currentEntries.length - this.maxLocalEntries;\n\n // Delete oldest entries (first element after sorting is the oldest)\n for (let i = 0; i < entriesToDelete; i++) {\n const entryToDelete = currentEntries[i];\n if (entryToDelete) {\n const id = String(entryToDelete[this.idKey]);\n await this.executeLocal(() =>\n this.localAdapter!.delete(this.storeName, id, this.idKey),\n );\n }\n }\n }\n } catch (error) {\n if (this.notThrowLocalError) {\n console.warn(\"Failed to enforce max local entries:\", error);\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sort entries by specified field\n * @param entries Array of entries to sort\n * @param key Sorting field name\n * @returns Sorted array of entries\n */\n private sortEntries(entries: T[], key: string): T[] {\n return [...entries].sort((a, b) => {\n const aValue = a[key];\n const bValue = b[key];\n\n // Handle undefined or null values\n if (aValue == null && bValue == null) return 0;\n if (aValue == null) return 1; // null/undefined at the end\n if (bValue == null) return -1; // null/undefined at the end\n\n // Number type sorting\n if (typeof aValue === \"number\" && typeof bValue === \"number\") {\n return aValue - bValue;\n }\n\n // String type sorting\n if (typeof aValue === \"string\" && typeof bValue === \"string\") {\n return aValue.localeCompare(bValue);\n }\n\n // Date type sorting (if string format date)\n if (typeof aValue === \"string\" && typeof bValue === \"string\") {\n const aDate = new Date(aValue);\n const bDate = new Date(bValue);\n if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) {\n return aDate.getTime() - bDate.getTime();\n }\n }\n\n // Convert other types to string for comparison\n return String(aValue).localeCompare(String(bValue));\n });\n }\n\n /**\n * Add data\n */\n async add(data: T): Promise<T> {\n await this.ensureInitialized();\n\n // Write to both local and remote simultaneously\n const promises: Promise<T>[] = [];\n\n if (this.localAdapter) {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.add(this.storeName, data, this.idKey),\n );\n if (localResult) {\n promises.push(Promise.resolve(localResult));\n\n // Check local storage entries limit\n await this.enforceMaxLocalEntries();\n }\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.add(this.storeName, data, this.idKey));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n return data;\n }\n\n /**\n * Update data\n */\n async update(id: string, data: Partial<T>): Promise<T> {\n await this.ensureInitialized();\n\n const promises: Promise<T>[] = [];\n\n if (this.localAdapter) {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.update<T>(this.storeName, id, data, this.idKey),\n );\n if (localResult) {\n promises.push(Promise.resolve(localResult));\n }\n }\n\n if (this.remoteAdapter) {\n promises.push(\n this.remoteAdapter.update<T>(this.storeName, id, data, this.idKey),\n );\n }\n\n const results = await Promise.all(promises);\n this.triggerChange();\n // Return first non-null result\n const firstResult = results.find(\n (result) => result !== null && result !== undefined,\n );\n return firstResult as T;\n }\n\n /**\n * Delete data\n */\n async delete(id: string): Promise<void> {\n await this.ensureInitialized();\n\n const promises: Promise<void | null>[] = [];\n\n if (this.localAdapter) {\n promises.push(\n this.executeLocal(() =>\n this.localAdapter!.delete(this.storeName, id, this.idKey),\n ),\n );\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.delete(this.storeName, id, this.idKey));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n }\n\n /**\n * Get data by ID\n */\n async getData(id: string): Promise<T | null> {\n await this.ensureInitialized();\n\n // Prioritize getting from local\n if (this.localAdapter) {\n try {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.getData(this.storeName, id, this.idKey),\n );\n if (localResult) {\n return localResult as T;\n }\n } catch (error) {\n if (!this.notThrowLocalError) {\n throw error;\n }\n }\n }\n\n // Get from remote\n if (this.remoteAdapter) {\n return await this.remoteAdapter.getData(this.storeName, id, this.idKey);\n }\n\n return null;\n }\n\n /**\n * Get list data\n */\n async getList(options: QueryOptions<T> = {}): Promise<T[]> {\n await this.ensureInitialized();\n\n const source = options.source;\n\n // If source is specified\n if (source === \"local\" && this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n\n if (source === \"remote\" && this.remoteAdapter) {\n const result = await this.remoteAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n return result.data;\n }\n\n // Default to getting from remote\n if (this.remoteAdapter) {\n try {\n const result = await this.remoteAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n\n // Cache to local\n if (this.localAdapter && result.data.length > 0) {\n await Promise.all(\n result.data.map((item) =>\n this.executeLocal(() =>\n this.localAdapter!.add(this.storeName, item, this.idKey),\n ),\n ),\n );\n\n // Check local storage entries limit\n await this.enforceMaxLocalEntries();\n }\n\n return result.data;\n } catch (error) {\n // If remote fails, try to get from local\n if (this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n throw error;\n }\n }\n\n // Only local adapter\n if (this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n\n return [];\n }\n\n /**\n * Get query object for list data\n */\n getListQuery(options: QueryOptions<T> = {}): QueryResult<T[]> {\n const source = options.source;\n\n // Build query key\n const queryKey = [\"store\", this.storeName, source || \"default\", options];\n\n // Build query function\n const queryFn = async (): Promise<T[]> => {\n return this.getList(options);\n };\n\n // Build initial data fetch function\n const getInitialData = async (): Promise<T[]> => {\n await this.ensureInitialized();\n if (this.localAdapter) {\n try {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n } catch (error) {\n // If local fetch fails, return empty array\n return [];\n }\n }\n return [];\n };\n\n return {\n queryKey,\n queryFn,\n getInitialData,\n };\n }\n\n /**\n * Clear store\n */\n async clear(): Promise<void> {\n await this.ensureInitialized();\n\n const promises: Promise<void>[] = [];\n\n if (this.localAdapter) {\n await this.executeLocal(() => this.localAdapter!.clear(this.storeName));\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.clear(this.storeName));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n }\n}\n","import {\n type LocalAdapter,\n type RemoteAdapter,\n type StoreConfig,\n} from './types.js';\nimport { Store } from './store.js';\n\n/**\n * SyncManager configuration options\n */\nexport interface SyncManagerOptions {\n localAdapter?: LocalAdapter;\n remoteAdapter?: RemoteAdapter;\n notThrowLocalError?: boolean;\n}\n\n/**\n * Sync manager\n */\nexport class SyncManager {\n private localAdapter: LocalAdapter | null = null;\n private remoteAdapter: RemoteAdapter | null = null;\n private notThrowLocalError: boolean;\n private stores: Map<string, Store<Record<string, unknown>>> = new Map();\n\n constructor(options: SyncManagerOptions = {}) {\n this.localAdapter = options.localAdapter ?? null;\n this.remoteAdapter = options.remoteAdapter ?? null;\n this.notThrowLocalError = options.notThrowLocalError ?? false;\n }\n\n /**\n * Set local adapter\n */\n setLocalAdapter(adapter: LocalAdapter): void {\n this.localAdapter = adapter;\n }\n\n /**\n * Set remote adapter\n */\n setRemoteAdapter(adapter: RemoteAdapter): void {\n this.remoteAdapter = adapter;\n }\n\n /**\n * Create Store\n */\n createStore<T extends Record<string, unknown>>(\n storeName: string,\n config: StoreConfig = {}\n ): Store<T> {\n // If already exists, return existing store\n const existingStore = this.stores.get(storeName);\n if (existingStore) {\n return existingStore as Store<T>;\n }\n\n const store = new Store<T>(storeName, {\n localAdapter: this.localAdapter,\n remoteAdapter: this.remoteAdapter,\n idKey: config.idKey ?? 'id',\n indexes: config.indexes,\n maxLocalEntries: config.maxLocalEntries,\n onChange: config.onChange,\n notThrowLocalError: this.notThrowLocalError,\n });\n\n this.stores.set(storeName, store as Store<Record<string, unknown>>);\n return store;\n }\n}\n\n/**\n * Create sync manager\n */\nexport function createSyncManager(options: SyncManagerOptions = {}): SyncManager {\n return new SyncManager(options);\n}\n\n"],"mappings":";;;;;AAGA,IAAY,sDAAL;AACL;AACA;;;;;;AAMF,IAAY,gDAAL;AACL;AACA;AACA;;;;;;;;;ACsBF,IAAa,QAAb,MAAsD;CACpD,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ,cAAc;CAEtB,YAAY,WAAmB,SAA0B;AACvD,OAAK,YAAY;AACjB,OAAK,eAAe,QAAQ;AAC5B,OAAK,gBAAgB,QAAQ;AAC7B,OAAK,QAAQ,QAAQ;AACrB,OAAK,UAAU,QAAQ;AACvB,OAAK,kBAAkB,QAAQ;AAC/B,OAAK,YAAY,QAAQ;AACzB,OAAK,WAAW,QAAQ;AACxB,OAAK,qBAAqB,QAAQ;;;;;CAMpC,MAAM,OAAsB;AAC1B,MAAI,KAAK,YACP;EAGF,MAAMA,WAAmC,EAAE;AAE3C,MAAI,KAAK,aACP,UAAS,KACP,KAAK,mBACH,KAAK,aAAc,UACjB,KAAK,WACL,KAAK,SACL,KAAK,MACN,CACF,CACF;AAGH,MAAI,KAAK,cACP,UAAS,KACP,KAAK,oBACH,KAAK,cAAe,UAClB,KAAK,WACL,KAAK,SACL,KAAK,MACN,CACF,CACF;AAGH,QAAM,QAAQ,IAAI,SAAS;AAC3B,OAAK,cAAc;;CAGrB,MAAc,oBAAmC;AAC/C,MAAI,CAAC,KAAK,YACR,OAAM,KAAK,MAAM;;CAIrB,AAAQ,gBAAsB;AAC5B,MAAI,KAAK,SACP,MAAK,UAAU;;CAInB,MAAc,aACZ,WACyB;AACzB,MAAI,CAAC,KAAK,aACR,QAAO;AAGT,MAAI;AACF,UAAO,MAAM,WAAW;WACjB,OAAO;AACd,OAAI,KAAK,oBAAoB;AAC3B,YAAQ,KAAK,wBAAwB,MAAM;AAC3C,WAAO;;AAET,SAAM;;;CAIV,MAAc,cACZ,WACkB;AAClB,SAAO,MAAM,WAAW;;;;;CAM1B,MAAc,yBAAwC;AACpD,MAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAC9B;AAGF,MAAI;GACF,IAAI,iBAAiB,MAAM,KAAK,aAAa,QAC3C,KAAK,WACL,EAAE,EACF,KAAK,MACN;AAED,OAAI,eAAe,SAAS,KAAK,iBAAiB;AAEhD,QAAI,KAAK,UACP,kBAAiB,KAAK,YAAY,gBAAgB,KAAK,UAAU;IAInE,MAAM,kBAAkB,eAAe,SAAS,KAAK;AAGrD,SAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,KAAK;KACxC,MAAM,gBAAgB,eAAe;AACrC,SAAI,eAAe;MACjB,MAAM,KAAK,OAAO,cAAc,KAAK,OAAO;AAC5C,YAAM,KAAK,mBACT,KAAK,aAAc,OAAO,KAAK,WAAW,IAAI,KAAK,MAAM,CAC1D;;;;WAIA,OAAO;AACd,OAAI,KAAK,mBACP,SAAQ,KAAK,wCAAwC,MAAM;OAE3D,OAAM;;;;;;;;;CAWZ,AAAQ,YAAY,SAAc,KAAkB;AAClD,SAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,MAAM;GACjC,MAAM,SAAS,EAAE;GACjB,MAAM,SAAS,EAAE;AAGjB,OAAI,UAAU,QAAQ,UAAU,KAAM,QAAO;AAC7C,OAAI,UAAU,KAAM,QAAO;AAC3B,OAAI,UAAU,KAAM,QAAO;AAG3B,OAAI,OAAO,WAAW,YAAY,OAAO,WAAW,SAClD,QAAO,SAAS;AAIlB,OAAI,OAAO,WAAW,YAAY,OAAO,WAAW,SAClD,QAAO,OAAO,cAAc,OAAO;AAIrC,OAAI,OAAO,WAAW,YAAY,OAAO,WAAW,UAAU;IAC5D,MAAM,QAAQ,IAAI,KAAK,OAAO;IAC9B,MAAM,QAAQ,IAAI,KAAK,OAAO;AAC9B,QAAI,CAAC,MAAM,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,MAAM,SAAS,CAAC,CACpD,QAAO,MAAM,SAAS,GAAG,MAAM,SAAS;;AAK5C,UAAO,OAAO,OAAO,CAAC,cAAc,OAAO,OAAO,CAAC;IACnD;;;;;CAMJ,MAAM,IAAI,MAAqB;AAC7B,QAAM,KAAK,mBAAmB;EAG9B,MAAMC,WAAyB,EAAE;AAEjC,MAAI,KAAK,cAAc;GACrB,MAAM,cAAc,MAAM,KAAK,mBAC7B,KAAK,aAAc,IAAI,KAAK,WAAW,MAAM,KAAK,MAAM,CACzD;AACD,OAAI,aAAa;AACf,aAAS,KAAK,QAAQ,QAAQ,YAAY,CAAC;AAG3C,UAAM,KAAK,wBAAwB;;;AAIvC,MAAI,KAAK,cACP,UAAS,KAAK,KAAK,cAAc,IAAI,KAAK,WAAW,MAAM,KAAK,MAAM,CAAC;AAGzE,QAAM,QAAQ,IAAI,SAAS;AAC3B,OAAK,eAAe;AACpB,SAAO;;;;;CAMT,MAAM,OAAO,IAAY,MAA8B;AACrD,QAAM,KAAK,mBAAmB;EAE9B,MAAMA,WAAyB,EAAE;AAEjC,MAAI,KAAK,cAAc;GACrB,MAAM,cAAc,MAAM,KAAK,mBAC7B,KAAK,aAAc,OAAU,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,CACnE;AACD,OAAI,YACF,UAAS,KAAK,QAAQ,QAAQ,YAAY,CAAC;;AAI/C,MAAI,KAAK,cACP,UAAS,KACP,KAAK,cAAc,OAAU,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,CACnE;EAGH,MAAM,UAAU,MAAM,QAAQ,IAAI,SAAS;AAC3C,OAAK,eAAe;AAKpB,SAHoB,QAAQ,MACzB,WAAW,WAAW,QAAQ,WAAW,OAC3C;;;;;CAOH,MAAM,OAAO,IAA2B;AACtC,QAAM,KAAK,mBAAmB;EAE9B,MAAMD,WAAmC,EAAE;AAE3C,MAAI,KAAK,aACP,UAAS,KACP,KAAK,mBACH,KAAK,aAAc,OAAO,KAAK,WAAW,IAAI,KAAK,MAAM,CAC1D,CACF;AAGH,MAAI,KAAK,cACP,UAAS,KAAK,KAAK,cAAc,OAAO,KAAK,WAAW,IAAI,KAAK,MAAM,CAAC;AAG1E,QAAM,QAAQ,IAAI,SAAS;AAC3B,OAAK,eAAe;;;;;CAMtB,MAAM,QAAQ,IAA+B;AAC3C,QAAM,KAAK,mBAAmB;AAG9B,MAAI,KAAK,aACP,KAAI;GACF,MAAM,cAAc,MAAM,KAAK,mBAC7B,KAAK,aAAc,QAAQ,KAAK,WAAW,IAAI,KAAK,MAAM,CAC3D;AACD,OAAI,YACF,QAAO;WAEF,OAAO;AACd,OAAI,CAAC,KAAK,mBACR,OAAM;;AAMZ,MAAI,KAAK,cACP,QAAO,MAAM,KAAK,cAAc,QAAQ,KAAK,WAAW,IAAI,KAAK,MAAM;AAGzE,SAAO;;;;;CAMT,MAAM,QAAQ,UAA2B,EAAE,EAAgB;AACzD,QAAM,KAAK,mBAAmB;EAE9B,MAAM,SAAS,QAAQ;AAGvB,MAAI,WAAW,WAAW,KAAK,aAC7B,QAAO,MAAM,KAAK,aAAa,QAC7B,KAAK,WACL,SACA,KAAK,MACN;AAGH,MAAI,WAAW,YAAY,KAAK,cAM9B,SALe,MAAM,KAAK,cAAc,QACtC,KAAK,WACL,SACA,KAAK,MACN,EACa;AAIhB,MAAI,KAAK,cACP,KAAI;GACF,MAAM,SAAS,MAAM,KAAK,cAAc,QACtC,KAAK,WACL,SACA,KAAK,MACN;AAGD,OAAI,KAAK,gBAAgB,OAAO,KAAK,SAAS,GAAG;AAC/C,UAAM,QAAQ,IACZ,OAAO,KAAK,KAAK,SACf,KAAK,mBACH,KAAK,aAAc,IAAI,KAAK,WAAW,MAAM,KAAK,MAAM,CACzD,CACF,CACF;AAGD,UAAM,KAAK,wBAAwB;;AAGrC,UAAO,OAAO;WACP,OAAO;AAEd,OAAI,KAAK,aACP,QAAO,MAAM,KAAK,aAAa,QAC7B,KAAK,WACL,SACA,KAAK,MACN;AAEH,SAAM;;AAKV,MAAI,KAAK,aACP,QAAO,MAAM,KAAK,aAAa,QAC7B,KAAK,WACL,SACA,KAAK,MACN;AAGH,SAAO,EAAE;;;;;CAMX,aAAa,UAA2B,EAAE,EAAoB;EAC5D,MAAM,SAAS,QAAQ;EAGvB,MAAM,WAAW;GAAC;GAAS,KAAK;GAAW,UAAU;GAAW;GAAQ;EAGxE,MAAM,UAAU,YAA0B;AACxC,UAAO,KAAK,QAAQ,QAAQ;;EAI9B,MAAM,iBAAiB,YAA0B;AAC/C,SAAM,KAAK,mBAAmB;AAC9B,OAAI,KAAK,aACP,KAAI;AACF,WAAO,MAAM,KAAK,aAAa,QAC7B,KAAK,WACL,SACA,KAAK,MACN;YACM,OAAO;AAEd,WAAO,EAAE;;AAGb,UAAO,EAAE;;AAGX,SAAO;GACL;GACA;GACA;GACD;;;;;CAMH,MAAM,QAAuB;AAC3B,QAAM,KAAK,mBAAmB;EAE9B,MAAME,WAA4B,EAAE;AAEpC,MAAI,KAAK,aACP,OAAM,KAAK,mBAAmB,KAAK,aAAc,MAAM,KAAK,UAAU,CAAC;AAGzE,MAAI,KAAK,cACP,UAAS,KAAK,KAAK,cAAc,MAAM,KAAK,UAAU,CAAC;AAGzD,QAAM,QAAQ,IAAI,SAAS;AAC3B,OAAK,eAAe;;;;;;;;;AC9bxB,IAAa,cAAb,MAAyB;CACvB,AAAQ,eAAoC;CAC5C,AAAQ,gBAAsC;CAC9C,AAAQ;CACR,AAAQ,yBAAsD,IAAI,KAAK;CAEvE,YAAY,UAA8B,EAAE,EAAE;AAC5C,OAAK,eAAe,QAAQ,gBAAgB;AAC5C,OAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,OAAK,qBAAqB,QAAQ,sBAAsB;;;;;CAM1D,gBAAgB,SAA6B;AAC3C,OAAK,eAAe;;;;;CAMtB,iBAAiB,SAA8B;AAC7C,OAAK,gBAAgB;;;;;CAMvB,YACE,WACA,SAAsB,EAAE,EACd;EAEV,MAAM,gBAAgB,KAAK,OAAO,IAAI,UAAU;AAChD,MAAI,cACF,QAAO;EAGT,MAAM,QAAQ,IAAI,MAAS,WAAW;GACpC,cAAc,KAAK;GACnB,eAAe,KAAK;GACpB,OAAO,OAAO,SAAS;GACvB,SAAS,OAAO;GAChB,iBAAiB,OAAO;GACxB,UAAU,OAAO;GACjB,oBAAoB,KAAK;GAC1B,CAAC;AAEF,OAAK,OAAO,IAAI,WAAW,MAAwC;AACnE,SAAO;;;;;;AAOX,SAAgB,kBAAkB,UAA8B,EAAE,EAAe;AAC/E,QAAO,IAAI,YAAY,QAAQ"}
package/dist/index.mjs CHANGED
@@ -205,8 +205,7 @@ var Store = class {
205
205
  /**
206
206
  * Get query object for list data
207
207
  */
208
- async getListQuery(options = {}) {
209
- await this.ensureInitialized();
208
+ getListQuery(options = {}) {
210
209
  const source = options.source;
211
210
  const queryKey = [
212
211
  "store",
@@ -218,6 +217,7 @@ var Store = class {
218
217
  return this.getList(options);
219
218
  };
220
219
  const getInitialData = async () => {
220
+ await this.ensureInitialized();
221
221
  if (this.localAdapter) try {
222
222
  return await this.localAdapter.getList(this.storeName, options, this.idKey);
223
223
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["promises: Promise<void | null>[]","promises: Promise<T>[]","promises: Promise<void>[]"],"sources":["../src/types.ts","../src/store.ts","../src/sync-manager.ts"],"sourcesContent":["/**\n * Adapter type: local or remote\n */\nexport enum AdapterType {\n Local = 'local',\n Remote = 'remote',\n}\n\n/**\n * Authentication type\n */\nexport enum AuthType {\n Token = 'token',\n Basic = 'basic',\n Bearer = 'bearer',\n}\n\n/**\n * Token authentication configuration\n */\nexport interface TokenAuth {\n access_token: string;\n token_type: string;\n expires_in?: number;\n refresh_token?: string;\n [key: string]: unknown;\n}\n\n/**\n * Authentication configuration\n */\nexport interface Authentication {\n authType: AuthType;\n token?: TokenAuth;\n username?: string;\n password?: string;\n bearer?: string;\n}\n\n/**\n * Service configuration (for remote adapters)\n */\nexport interface ServiceConfig {\n endpoint: string;\n authentication?: Authentication;\n}\n\n/**\n * Query options\n */\nexport interface QueryOptions<T = Record<string, unknown>> {\n source?: 'local' | 'remote';\n page?: number;\n limit?: number;\n where?: Partial<T>;\n}\n\n/**\n * Paginated result\n */\nexport interface PaginatedResult<T> {\n data: T[];\n totalCount: number;\n page: number;\n limit: number;\n}\n\n/**\n * Query function and initial data (for React Query, etc.)\n */\nexport interface QueryResult<T> {\n queryKey: unknown[];\n queryFn: () => Promise<T>;\n getInitialData: () => Promise<T>;\n}\n\n/**\n * Store configuration\n */\nexport interface StoreConfig {\n indexes?: string[];\n idKey?: string;\n maxLocalEntries?: number;\n onChange?: () => void;\n}\n\n/**\n * Base adapter interface\n */\nexport interface BaseAdapter {\n readonly type: AdapterType;\n readonly name: string;\n}\n\n/**\n * Local adapter interface\n */\nexport interface LocalAdapter extends BaseAdapter {\n readonly type: AdapterType.Local;\n \n /**\n * Add data\n */\n add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Update data\n */\n update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Delete data\n */\n delete(storeName: string, id: string, idKey?: string): Promise<void>;\n \n /**\n * Get data by ID\n */\n getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n idKey?: string\n ): Promise<T | null>;\n \n /**\n * Get list data (with pagination support)\n */\n getList<T extends Record<string, unknown>>(\n storeName: string,\n options?: QueryOptions<T>,\n idKey?: string\n ): Promise<T[]>;\n \n /**\n * Clear store\n */\n clear(storeName: string): Promise<void>;\n \n /**\n * Initialize store\n */\n initStore(\n storeName: string,\n indexes?: string[],\n idKey?: string\n ): Promise<void>;\n}\n\n/**\n * Remote adapter interface\n */\nexport interface RemoteAdapter extends BaseAdapter {\n readonly type: AdapterType.Remote;\n \n /**\n * 添加数据\n */\n add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Update data\n */\n update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Delete data\n */\n delete(storeName: string, id: string, idKey?: string): Promise<void>;\n \n /**\n * Get data by ID\n */\n getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n idKey?: string\n ): Promise<T | null>;\n \n /**\n * Get list data (with pagination support)\n */\n getList<T extends Record<string, unknown>>(\n storeName: string,\n options?: QueryOptions<T>,\n idKey?: string\n ): Promise<PaginatedResult<T>>;\n \n /**\n * Clear store\n */\n clear(storeName: string): Promise<void>;\n \n /**\n * Initialize store (create if not exists)\n */\n initStore(\n storeName: string,\n indexes?: string[],\n idKey?: string\n ): Promise<void>;\n \n /**\n * Set service configuration\n */\n setService(service: ServiceConfig): void;\n}\n\n/**\n * Adapter union type\n */\nexport type Adapter = LocalAdapter | RemoteAdapter;\n\n","import {\n type LocalAdapter,\n type RemoteAdapter,\n type QueryOptions,\n type QueryResult,\n} from \"./types.js\";\n\n/**\n * Store configuration\n */\nexport interface StoreOptions<_T extends Record<string, unknown>> {\n localAdapter: LocalAdapter | null;\n remoteAdapter: RemoteAdapter | null;\n idKey: string;\n indexes?: string[];\n /**\n * Maximum number of local storage entries\n * When local storage entries exceed this limit, oldest entries will be automatically deleted\n * Can be used with sortByKey parameter to specify sorting field for deletion order\n * If not set, no limit on local storage entries\n */\n maxLocalEntries?: number;\n /**\n * Field name for sorting when maxLocalEntries is in effect\n * If this field is specified, entries will be sorted by this field's value before deleting oldest entries\n * If not specified, entries will be deleted in default array order (usually insertion order)\n * Supports number and string type field values\n */\n sortByKey?: string;\n onChange?: () => void;\n notThrowLocalError: boolean;\n}\n\n/**\n * Store class\n */\nexport class Store<T extends Record<string, unknown>> {\n private storeName: string;\n private localAdapter: LocalAdapter | null;\n private remoteAdapter: RemoteAdapter | null;\n private idKey: string;\n private indexes?: string[];\n private maxLocalEntries?: number;\n private sortByKey?: string;\n private onChange?: () => void;\n private notThrowLocalError: boolean;\n private initialized = false;\n\n constructor(storeName: string, options: StoreOptions<T>) {\n this.storeName = storeName;\n this.localAdapter = options.localAdapter;\n this.remoteAdapter = options.remoteAdapter;\n this.idKey = options.idKey;\n this.indexes = options.indexes;\n this.maxLocalEntries = options.maxLocalEntries;\n this.sortByKey = options.sortByKey;\n this.onChange = options.onChange;\n this.notThrowLocalError = options.notThrowLocalError;\n }\n\n /**\n * Initialize Store\n */\n async init(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n const promises: Promise<void | null>[] = [];\n\n if (this.localAdapter) {\n promises.push(\n this.executeLocal(() =>\n this.localAdapter!.initStore(\n this.storeName,\n this.indexes,\n this.idKey,\n ),\n ),\n );\n }\n\n if (this.remoteAdapter) {\n promises.push(\n this.executeRemote(() =>\n this.remoteAdapter!.initStore(\n this.storeName,\n this.indexes,\n this.idKey,\n ),\n ),\n );\n }\n\n await Promise.all(promises);\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.init();\n }\n }\n\n private triggerChange(): void {\n if (this.onChange) {\n this.onChange();\n }\n }\n\n private async executeLocal<TResult>(\n operation: () => Promise<TResult>,\n ): Promise<TResult | null> {\n if (!this.localAdapter) {\n return null;\n }\n\n try {\n return await operation();\n } catch (error) {\n if (this.notThrowLocalError) {\n console.warn(\"Local adapter error:\", error);\n return null;\n }\n throw error;\n }\n }\n\n private async executeRemote<TResult>(\n operation: () => Promise<TResult>,\n ): Promise<TResult> {\n return await operation();\n }\n\n /**\n * Enforce maximum local storage entries limit\n */\n private async enforceMaxLocalEntries(): Promise<void> {\n if (!this.localAdapter || !this.maxLocalEntries) {\n return;\n }\n\n try {\n let currentEntries = await this.localAdapter.getList<T>(\n this.storeName,\n {},\n this.idKey,\n );\n\n if (currentEntries.length > this.maxLocalEntries) {\n // If sorting field is specified, sort by that field\n if (this.sortByKey) {\n currentEntries = this.sortEntries(currentEntries, this.sortByKey);\n }\n\n // Calculate number of entries to delete\n const entriesToDelete = currentEntries.length - this.maxLocalEntries;\n\n // Delete oldest entries (first element after sorting is the oldest)\n for (let i = 0; i < entriesToDelete; i++) {\n const entryToDelete = currentEntries[i];\n if (entryToDelete) {\n const id = String(entryToDelete[this.idKey]);\n await this.executeLocal(() =>\n this.localAdapter!.delete(this.storeName, id, this.idKey),\n );\n }\n }\n }\n } catch (error) {\n if (this.notThrowLocalError) {\n console.warn(\"Failed to enforce max local entries:\", error);\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sort entries by specified field\n * @param entries Array of entries to sort\n * @param key Sorting field name\n * @returns Sorted array of entries\n */\n private sortEntries(entries: T[], key: string): T[] {\n return [...entries].sort((a, b) => {\n const aValue = a[key];\n const bValue = b[key];\n\n // Handle undefined or null values\n if (aValue == null && bValue == null) return 0;\n if (aValue == null) return 1; // null/undefined at the end\n if (bValue == null) return -1; // null/undefined at the end\n\n // Number type sorting\n if (typeof aValue === \"number\" && typeof bValue === \"number\") {\n return aValue - bValue;\n }\n\n // String type sorting\n if (typeof aValue === \"string\" && typeof bValue === \"string\") {\n return aValue.localeCompare(bValue);\n }\n\n // Date type sorting (if string format date)\n if (typeof aValue === \"string\" && typeof bValue === \"string\") {\n const aDate = new Date(aValue);\n const bDate = new Date(bValue);\n if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) {\n return aDate.getTime() - bDate.getTime();\n }\n }\n\n // Convert other types to string for comparison\n return String(aValue).localeCompare(String(bValue));\n });\n }\n\n /**\n * Add data\n */\n async add(data: T): Promise<T> {\n await this.ensureInitialized();\n\n // Write to both local and remote simultaneously\n const promises: Promise<T>[] = [];\n\n if (this.localAdapter) {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.add(this.storeName, data, this.idKey),\n );\n if (localResult) {\n promises.push(Promise.resolve(localResult));\n\n // Check local storage entries limit\n await this.enforceMaxLocalEntries();\n }\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.add(this.storeName, data, this.idKey));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n return data;\n }\n\n /**\n * Update data\n */\n async update(id: string, data: Partial<T>): Promise<T> {\n await this.ensureInitialized();\n\n const promises: Promise<T>[] = [];\n\n if (this.localAdapter) {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.update<T>(this.storeName, id, data, this.idKey),\n );\n if (localResult) {\n promises.push(Promise.resolve(localResult));\n }\n }\n\n if (this.remoteAdapter) {\n promises.push(\n this.remoteAdapter.update<T>(this.storeName, id, data, this.idKey),\n );\n }\n\n const results = await Promise.all(promises);\n this.triggerChange();\n // Return first non-null result\n const firstResult = results.find(\n (result) => result !== null && result !== undefined,\n );\n return firstResult as T;\n }\n\n /**\n * Delete data\n */\n async delete(id: string): Promise<void> {\n await this.ensureInitialized();\n\n const promises: Promise<void | null>[] = [];\n\n if (this.localAdapter) {\n promises.push(\n this.executeLocal(() =>\n this.localAdapter!.delete(this.storeName, id, this.idKey),\n ),\n );\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.delete(this.storeName, id, this.idKey));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n }\n\n /**\n * Get data by ID\n */\n async getData(id: string): Promise<T | null> {\n await this.ensureInitialized();\n\n // Prioritize getting from local\n if (this.localAdapter) {\n try {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.getData(this.storeName, id, this.idKey),\n );\n if (localResult) {\n return localResult as T;\n }\n } catch (error) {\n if (!this.notThrowLocalError) {\n throw error;\n }\n }\n }\n\n // Get from remote\n if (this.remoteAdapter) {\n return await this.remoteAdapter.getData(this.storeName, id, this.idKey);\n }\n\n return null;\n }\n\n /**\n * Get list data\n */\n async getList(options: QueryOptions<T> = {}): Promise<T[]> {\n await this.ensureInitialized();\n\n const source = options.source;\n\n // If source is specified\n if (source === \"local\" && this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n\n if (source === \"remote\" && this.remoteAdapter) {\n const result = await this.remoteAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n return result.data;\n }\n\n // Default to getting from remote\n if (this.remoteAdapter) {\n try {\n const result = await this.remoteAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n\n // Cache to local\n if (this.localAdapter && result.data.length > 0) {\n await Promise.all(\n result.data.map((item) =>\n this.executeLocal(() =>\n this.localAdapter!.add(this.storeName, item, this.idKey),\n ),\n ),\n );\n\n // Check local storage entries limit\n await this.enforceMaxLocalEntries();\n }\n\n return result.data;\n } catch (error) {\n // If remote fails, try to get from local\n if (this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n throw error;\n }\n }\n\n // Only local adapter\n if (this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n\n return [];\n }\n\n /**\n * Get query object for list data\n */\n async getListQuery(options: QueryOptions<T> = {}): Promise<QueryResult<T[]>> {\n await this.ensureInitialized();\n\n const source = options.source;\n\n // Build query key\n const queryKey = [\"store\", this.storeName, source || \"default\", options];\n\n // Build query function\n const queryFn = async (): Promise<T[]> => {\n return this.getList(options);\n };\n\n // Build initial data fetch function\n const getInitialData = async (): Promise<T[]> => {\n if (this.localAdapter) {\n try {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n } catch (error) {\n // If local fetch fails, return empty array\n return [];\n }\n }\n return [];\n };\n\n return {\n queryKey,\n queryFn,\n getInitialData,\n };\n }\n\n /**\n * Clear store\n */\n async clear(): Promise<void> {\n await this.ensureInitialized();\n\n const promises: Promise<void>[] = [];\n\n if (this.localAdapter) {\n await this.executeLocal(() => this.localAdapter!.clear(this.storeName));\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.clear(this.storeName));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n }\n}\n","import {\n type LocalAdapter,\n type RemoteAdapter,\n type StoreConfig,\n} from './types.js';\nimport { Store } from './store.js';\n\n/**\n * SyncManager configuration options\n */\nexport interface SyncManagerOptions {\n localAdapter?: LocalAdapter;\n remoteAdapter?: RemoteAdapter;\n notThrowLocalError?: boolean;\n}\n\n/**\n * Sync manager\n */\nexport class SyncManager {\n private localAdapter: LocalAdapter | null = null;\n private remoteAdapter: RemoteAdapter | null = null;\n private notThrowLocalError: boolean;\n private stores: Map<string, Store<Record<string, unknown>>> = new Map();\n\n constructor(options: SyncManagerOptions = {}) {\n this.localAdapter = options.localAdapter ?? null;\n this.remoteAdapter = options.remoteAdapter ?? null;\n this.notThrowLocalError = options.notThrowLocalError ?? false;\n }\n\n /**\n * Set local adapter\n */\n setLocalAdapter(adapter: LocalAdapter): void {\n this.localAdapter = adapter;\n }\n\n /**\n * Set remote adapter\n */\n setRemoteAdapter(adapter: RemoteAdapter): void {\n this.remoteAdapter = adapter;\n }\n\n /**\n * Create Store\n */\n createStore<T extends Record<string, unknown>>(\n storeName: string,\n config: StoreConfig = {}\n ): Store<T> {\n // If already exists, return existing store\n const existingStore = this.stores.get(storeName);\n if (existingStore) {\n return existingStore as Store<T>;\n }\n\n const store = new Store<T>(storeName, {\n localAdapter: this.localAdapter,\n remoteAdapter: this.remoteAdapter,\n idKey: config.idKey ?? 'id',\n indexes: config.indexes,\n maxLocalEntries: config.maxLocalEntries,\n onChange: config.onChange,\n notThrowLocalError: this.notThrowLocalError,\n });\n\n this.stores.set(storeName, store as Store<Record<string, unknown>>);\n return store;\n }\n}\n\n/**\n * Create sync manager\n */\nexport function createSyncManager(options: SyncManagerOptions = {}): SyncManager {\n return new SyncManager(options);\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["promises: Promise<void | null>[]","promises: Promise<T>[]","promises: Promise<void>[]"],"sources":["../src/types.ts","../src/store.ts","../src/sync-manager.ts"],"sourcesContent":["/**\n * Adapter type: local or remote\n */\nexport enum AdapterType {\n Local = 'local',\n Remote = 'remote',\n}\n\n/**\n * Authentication type\n */\nexport enum AuthType {\n Token = 'token',\n Basic = 'basic',\n Bearer = 'bearer',\n}\n\n/**\n * Token authentication configuration\n */\nexport interface TokenAuth {\n access_token: string;\n token_type: string;\n expires_in?: number;\n refresh_token?: string;\n [key: string]: unknown;\n}\n\n/**\n * Authentication configuration\n */\nexport interface Authentication {\n authType: AuthType;\n token?: TokenAuth;\n username?: string;\n password?: string;\n bearer?: string;\n}\n\n/**\n * Service configuration (for remote adapters)\n */\nexport interface ServiceConfig {\n endpoint: string;\n authentication?: Authentication;\n}\n\n/**\n * Query options\n */\nexport interface QueryOptions<T = Record<string, unknown>> {\n source?: 'local' | 'remote';\n page?: number;\n limit?: number;\n where?: Partial<T>;\n}\n\n/**\n * Paginated result\n */\nexport interface PaginatedResult<T> {\n data: T[];\n totalCount: number;\n page: number;\n limit: number;\n}\n\n/**\n * Query function and initial data (for React Query, etc.)\n */\nexport interface QueryResult<T> {\n queryKey: unknown[];\n queryFn: () => Promise<T>;\n getInitialData: () => Promise<T>;\n}\n\n/**\n * Store configuration\n */\nexport interface StoreConfig {\n indexes?: string[];\n idKey?: string;\n maxLocalEntries?: number;\n onChange?: () => void;\n}\n\n/**\n * Base adapter interface\n */\nexport interface BaseAdapter {\n readonly type: AdapterType;\n readonly name: string;\n}\n\n/**\n * Local adapter interface\n */\nexport interface LocalAdapter extends BaseAdapter {\n readonly type: AdapterType.Local;\n \n /**\n * Add data\n */\n add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Update data\n */\n update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Delete data\n */\n delete(storeName: string, id: string, idKey?: string): Promise<void>;\n \n /**\n * Get data by ID\n */\n getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n idKey?: string\n ): Promise<T | null>;\n \n /**\n * Get list data (with pagination support)\n */\n getList<T extends Record<string, unknown>>(\n storeName: string,\n options?: QueryOptions<T>,\n idKey?: string\n ): Promise<T[]>;\n \n /**\n * Clear store\n */\n clear(storeName: string): Promise<void>;\n \n /**\n * Initialize store\n */\n initStore(\n storeName: string,\n indexes?: string[],\n idKey?: string\n ): Promise<void>;\n}\n\n/**\n * Remote adapter interface\n */\nexport interface RemoteAdapter extends BaseAdapter {\n readonly type: AdapterType.Remote;\n \n /**\n * 添加数据\n */\n add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Update data\n */\n update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey?: string\n ): Promise<T>;\n \n /**\n * Delete data\n */\n delete(storeName: string, id: string, idKey?: string): Promise<void>;\n \n /**\n * Get data by ID\n */\n getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n idKey?: string\n ): Promise<T | null>;\n \n /**\n * Get list data (with pagination support)\n */\n getList<T extends Record<string, unknown>>(\n storeName: string,\n options?: QueryOptions<T>,\n idKey?: string\n ): Promise<PaginatedResult<T>>;\n \n /**\n * Clear store\n */\n clear(storeName: string): Promise<void>;\n \n /**\n * Initialize store (create if not exists)\n */\n initStore(\n storeName: string,\n indexes?: string[],\n idKey?: string\n ): Promise<void>;\n \n /**\n * Set service configuration\n */\n setService(service: ServiceConfig): void;\n}\n\n/**\n * Adapter union type\n */\nexport type Adapter = LocalAdapter | RemoteAdapter;\n\n","import {\n type LocalAdapter,\n type RemoteAdapter,\n type QueryOptions,\n type QueryResult,\n} from \"./types.js\";\n\n/**\n * Store configuration\n */\nexport interface StoreOptions<_T extends Record<string, unknown>> {\n localAdapter: LocalAdapter | null;\n remoteAdapter: RemoteAdapter | null;\n idKey: keyof _T;\n indexes?: Array<keyof _T>;\n /**\n * Maximum number of local storage entries\n * When local storage entries exceed this limit, oldest entries will be automatically deleted\n * Can be used with sortByKey parameter to specify sorting field for deletion order\n * If not set, no limit on local storage entries\n */\n maxLocalEntries?: number;\n /**\n * Field name for sorting when maxLocalEntries is in effect\n * If this field is specified, entries will be sorted by this field's value before deleting oldest entries\n * If not specified, entries will be deleted in default array order (usually insertion order)\n * Supports number and string type field values\n */\n sortByKey?: keyof _T;\n onChange?: () => void;\n notThrowLocalError: boolean;\n}\n\n/**\n * Store class\n */\nexport class Store<T extends Record<string, unknown>> {\n private storeName: string;\n private localAdapter: LocalAdapter | null;\n private remoteAdapter: RemoteAdapter | null;\n private idKey: string;\n private indexes?: string[];\n private maxLocalEntries?: number;\n private sortByKey?: string;\n private onChange?: () => void;\n private notThrowLocalError: boolean;\n private initialized = false;\n\n constructor(storeName: string, options: StoreOptions<T>) {\n this.storeName = storeName;\n this.localAdapter = options.localAdapter;\n this.remoteAdapter = options.remoteAdapter;\n this.idKey = options.idKey as string;\n this.indexes = options.indexes as string[];\n this.maxLocalEntries = options.maxLocalEntries;\n this.sortByKey = options.sortByKey as string;\n this.onChange = options.onChange;\n this.notThrowLocalError = options.notThrowLocalError;\n }\n\n /**\n * Initialize Store\n */\n async init(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n const promises: Promise<void | null>[] = [];\n\n if (this.localAdapter) {\n promises.push(\n this.executeLocal(() =>\n this.localAdapter!.initStore(\n this.storeName,\n this.indexes,\n this.idKey,\n ),\n ),\n );\n }\n\n if (this.remoteAdapter) {\n promises.push(\n this.executeRemote(() =>\n this.remoteAdapter!.initStore(\n this.storeName,\n this.indexes,\n this.idKey,\n ),\n ),\n );\n }\n\n await Promise.all(promises);\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.init();\n }\n }\n\n private triggerChange(): void {\n if (this.onChange) {\n this.onChange();\n }\n }\n\n private async executeLocal<TResult>(\n operation: () => Promise<TResult>,\n ): Promise<TResult | null> {\n if (!this.localAdapter) {\n return null;\n }\n\n try {\n return await operation();\n } catch (error) {\n if (this.notThrowLocalError) {\n console.warn(\"Local adapter error:\", error);\n return null;\n }\n throw error;\n }\n }\n\n private async executeRemote<TResult>(\n operation: () => Promise<TResult>,\n ): Promise<TResult> {\n return await operation();\n }\n\n /**\n * Enforce maximum local storage entries limit\n */\n private async enforceMaxLocalEntries(): Promise<void> {\n if (!this.localAdapter || !this.maxLocalEntries) {\n return;\n }\n\n try {\n let currentEntries = await this.localAdapter.getList<T>(\n this.storeName,\n {},\n this.idKey,\n );\n\n if (currentEntries.length > this.maxLocalEntries) {\n // If sorting field is specified, sort by that field\n if (this.sortByKey) {\n currentEntries = this.sortEntries(currentEntries, this.sortByKey);\n }\n\n // Calculate number of entries to delete\n const entriesToDelete = currentEntries.length - this.maxLocalEntries;\n\n // Delete oldest entries (first element after sorting is the oldest)\n for (let i = 0; i < entriesToDelete; i++) {\n const entryToDelete = currentEntries[i];\n if (entryToDelete) {\n const id = String(entryToDelete[this.idKey]);\n await this.executeLocal(() =>\n this.localAdapter!.delete(this.storeName, id, this.idKey),\n );\n }\n }\n }\n } catch (error) {\n if (this.notThrowLocalError) {\n console.warn(\"Failed to enforce max local entries:\", error);\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sort entries by specified field\n * @param entries Array of entries to sort\n * @param key Sorting field name\n * @returns Sorted array of entries\n */\n private sortEntries(entries: T[], key: string): T[] {\n return [...entries].sort((a, b) => {\n const aValue = a[key];\n const bValue = b[key];\n\n // Handle undefined or null values\n if (aValue == null && bValue == null) return 0;\n if (aValue == null) return 1; // null/undefined at the end\n if (bValue == null) return -1; // null/undefined at the end\n\n // Number type sorting\n if (typeof aValue === \"number\" && typeof bValue === \"number\") {\n return aValue - bValue;\n }\n\n // String type sorting\n if (typeof aValue === \"string\" && typeof bValue === \"string\") {\n return aValue.localeCompare(bValue);\n }\n\n // Date type sorting (if string format date)\n if (typeof aValue === \"string\" && typeof bValue === \"string\") {\n const aDate = new Date(aValue);\n const bDate = new Date(bValue);\n if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) {\n return aDate.getTime() - bDate.getTime();\n }\n }\n\n // Convert other types to string for comparison\n return String(aValue).localeCompare(String(bValue));\n });\n }\n\n /**\n * Add data\n */\n async add(data: T): Promise<T> {\n await this.ensureInitialized();\n\n // Write to both local and remote simultaneously\n const promises: Promise<T>[] = [];\n\n if (this.localAdapter) {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.add(this.storeName, data, this.idKey),\n );\n if (localResult) {\n promises.push(Promise.resolve(localResult));\n\n // Check local storage entries limit\n await this.enforceMaxLocalEntries();\n }\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.add(this.storeName, data, this.idKey));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n return data;\n }\n\n /**\n * Update data\n */\n async update(id: string, data: Partial<T>): Promise<T> {\n await this.ensureInitialized();\n\n const promises: Promise<T>[] = [];\n\n if (this.localAdapter) {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.update<T>(this.storeName, id, data, this.idKey),\n );\n if (localResult) {\n promises.push(Promise.resolve(localResult));\n }\n }\n\n if (this.remoteAdapter) {\n promises.push(\n this.remoteAdapter.update<T>(this.storeName, id, data, this.idKey),\n );\n }\n\n const results = await Promise.all(promises);\n this.triggerChange();\n // Return first non-null result\n const firstResult = results.find(\n (result) => result !== null && result !== undefined,\n );\n return firstResult as T;\n }\n\n /**\n * Delete data\n */\n async delete(id: string): Promise<void> {\n await this.ensureInitialized();\n\n const promises: Promise<void | null>[] = [];\n\n if (this.localAdapter) {\n promises.push(\n this.executeLocal(() =>\n this.localAdapter!.delete(this.storeName, id, this.idKey),\n ),\n );\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.delete(this.storeName, id, this.idKey));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n }\n\n /**\n * Get data by ID\n */\n async getData(id: string): Promise<T | null> {\n await this.ensureInitialized();\n\n // Prioritize getting from local\n if (this.localAdapter) {\n try {\n const localResult = await this.executeLocal(() =>\n this.localAdapter!.getData(this.storeName, id, this.idKey),\n );\n if (localResult) {\n return localResult as T;\n }\n } catch (error) {\n if (!this.notThrowLocalError) {\n throw error;\n }\n }\n }\n\n // Get from remote\n if (this.remoteAdapter) {\n return await this.remoteAdapter.getData(this.storeName, id, this.idKey);\n }\n\n return null;\n }\n\n /**\n * Get list data\n */\n async getList(options: QueryOptions<T> = {}): Promise<T[]> {\n await this.ensureInitialized();\n\n const source = options.source;\n\n // If source is specified\n if (source === \"local\" && this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n\n if (source === \"remote\" && this.remoteAdapter) {\n const result = await this.remoteAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n return result.data;\n }\n\n // Default to getting from remote\n if (this.remoteAdapter) {\n try {\n const result = await this.remoteAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n\n // Cache to local\n if (this.localAdapter && result.data.length > 0) {\n await Promise.all(\n result.data.map((item) =>\n this.executeLocal(() =>\n this.localAdapter!.add(this.storeName, item, this.idKey),\n ),\n ),\n );\n\n // Check local storage entries limit\n await this.enforceMaxLocalEntries();\n }\n\n return result.data;\n } catch (error) {\n // If remote fails, try to get from local\n if (this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n throw error;\n }\n }\n\n // Only local adapter\n if (this.localAdapter) {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n }\n\n return [];\n }\n\n /**\n * Get query object for list data\n */\n getListQuery(options: QueryOptions<T> = {}): QueryResult<T[]> {\n const source = options.source;\n\n // Build query key\n const queryKey = [\"store\", this.storeName, source || \"default\", options];\n\n // Build query function\n const queryFn = async (): Promise<T[]> => {\n return this.getList(options);\n };\n\n // Build initial data fetch function\n const getInitialData = async (): Promise<T[]> => {\n await this.ensureInitialized();\n if (this.localAdapter) {\n try {\n return await this.localAdapter.getList<T>(\n this.storeName,\n options,\n this.idKey,\n );\n } catch (error) {\n // If local fetch fails, return empty array\n return [];\n }\n }\n return [];\n };\n\n return {\n queryKey,\n queryFn,\n getInitialData,\n };\n }\n\n /**\n * Clear store\n */\n async clear(): Promise<void> {\n await this.ensureInitialized();\n\n const promises: Promise<void>[] = [];\n\n if (this.localAdapter) {\n await this.executeLocal(() => this.localAdapter!.clear(this.storeName));\n }\n\n if (this.remoteAdapter) {\n promises.push(this.remoteAdapter.clear(this.storeName));\n }\n\n await Promise.all(promises);\n this.triggerChange();\n }\n}\n","import {\n type LocalAdapter,\n type RemoteAdapter,\n type StoreConfig,\n} from './types.js';\nimport { Store } from './store.js';\n\n/**\n * SyncManager configuration options\n */\nexport interface SyncManagerOptions {\n localAdapter?: LocalAdapter;\n remoteAdapter?: RemoteAdapter;\n notThrowLocalError?: boolean;\n}\n\n/**\n * Sync manager\n */\nexport class SyncManager {\n private localAdapter: LocalAdapter | null = null;\n private remoteAdapter: RemoteAdapter | null = null;\n private notThrowLocalError: boolean;\n private stores: Map<string, Store<Record<string, unknown>>> = new Map();\n\n constructor(options: SyncManagerOptions = {}) {\n this.localAdapter = options.localAdapter ?? null;\n this.remoteAdapter = options.remoteAdapter ?? null;\n this.notThrowLocalError = options.notThrowLocalError ?? false;\n }\n\n /**\n * Set local adapter\n */\n setLocalAdapter(adapter: LocalAdapter): void {\n this.localAdapter = adapter;\n }\n\n /**\n * Set remote adapter\n */\n setRemoteAdapter(adapter: RemoteAdapter): void {\n this.remoteAdapter = adapter;\n }\n\n /**\n * Create Store\n */\n createStore<T extends Record<string, unknown>>(\n storeName: string,\n config: StoreConfig = {}\n ): Store<T> {\n // If already exists, return existing store\n const existingStore = this.stores.get(storeName);\n if (existingStore) {\n return existingStore as Store<T>;\n }\n\n const store = new Store<T>(storeName, {\n localAdapter: this.localAdapter,\n remoteAdapter: this.remoteAdapter,\n idKey: config.idKey ?? 'id',\n indexes: config.indexes,\n maxLocalEntries: config.maxLocalEntries,\n onChange: config.onChange,\n notThrowLocalError: this.notThrowLocalError,\n });\n\n this.stores.set(storeName, store as Store<Record<string, unknown>>);\n return store;\n }\n}\n\n/**\n * Create sync manager\n */\nexport function createSyncManager(options: SyncManagerOptions = {}): SyncManager {\n return new SyncManager(options);\n}\n\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@omnistreamai/data-core",
3
- "version": "0.1.0",
4
- "type": "module",
5
- "main": "./dist/index.mjs",
6
- "types": "./dist/index.d.mts",
3
+ "version": "0.1.2",
4
+ "main": "./dist/index.js",
5
+ "module": "./dist/index.mjs",
6
+ "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
- "types": "./dist/index.d.mts",
10
- "import": "./dist/index.mjs"
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
11
12
  }
12
13
  },
13
14
  "scripts": {
package/src/store.test.ts CHANGED
@@ -143,11 +143,11 @@ class MockRemoteAdapter implements RemoteAdapter {
143
143
  };
144
144
  }
145
145
 
146
- async getListQuery<T extends Record<string, unknown>>(
146
+ getListQuery<T extends Record<string, unknown>>(
147
147
  storeName: string,
148
148
  options?: QueryOptions<T>,
149
149
  idKey?: string
150
- ): Promise<QueryResult<T[]>> {
150
+ ): QueryResult<T[]> {
151
151
  return {
152
152
  queryKey: ["store", storeName, "remote", options],
153
153
  queryFn: async () => {
@@ -184,7 +184,11 @@ describe("Store", () => {
184
184
  localAdapter = new MockLocalAdapter();
185
185
  remoteAdapter = new MockRemoteAdapter();
186
186
 
187
- store = new Store("user", {
187
+ store = new Store<{
188
+ id: string;
189
+ username: string;
190
+ email?: string;
191
+ }>("user", {
188
192
  localAdapter,
189
193
  remoteAdapter,
190
194
  idKey: "id",
@@ -445,7 +449,7 @@ describe("Store", () => {
445
449
  expect(localData.length).toBe(3);
446
450
 
447
451
  // 应该保留时间戳最大的3个条目(删除了 timestamp: 1000, 2000 的条目)
448
- const timestamps = localData.map(item => item.timestamp).sort((a, b) => a - b);
452
+ const timestamps = localData.map(item => item.timestamp).sort((a:any, b:any) => a - b);
449
453
  expect(timestamps).toEqual([3000, 4000, 5000]);
450
454
  });
451
455
  });
package/src/store.ts CHANGED
@@ -11,8 +11,8 @@ import {
11
11
  export interface StoreOptions<_T extends Record<string, unknown>> {
12
12
  localAdapter: LocalAdapter | null;
13
13
  remoteAdapter: RemoteAdapter | null;
14
- idKey: string;
15
- indexes?: string[];
14
+ idKey: keyof _T;
15
+ indexes?: Array<keyof _T>;
16
16
  /**
17
17
  * Maximum number of local storage entries
18
18
  * When local storage entries exceed this limit, oldest entries will be automatically deleted
@@ -26,7 +26,7 @@ export interface StoreOptions<_T extends Record<string, unknown>> {
26
26
  * If not specified, entries will be deleted in default array order (usually insertion order)
27
27
  * Supports number and string type field values
28
28
  */
29
- sortByKey?: string;
29
+ sortByKey?: keyof _T;
30
30
  onChange?: () => void;
31
31
  notThrowLocalError: boolean;
32
32
  }
@@ -50,10 +50,10 @@ export class Store<T extends Record<string, unknown>> {
50
50
  this.storeName = storeName;
51
51
  this.localAdapter = options.localAdapter;
52
52
  this.remoteAdapter = options.remoteAdapter;
53
- this.idKey = options.idKey;
54
- this.indexes = options.indexes;
53
+ this.idKey = options.idKey as string;
54
+ this.indexes = options.indexes as string[];
55
55
  this.maxLocalEntries = options.maxLocalEntries;
56
- this.sortByKey = options.sortByKey;
56
+ this.sortByKey = options.sortByKey as string;
57
57
  this.onChange = options.onChange;
58
58
  this.notThrowLocalError = options.notThrowLocalError;
59
59
  }
@@ -232,7 +232,7 @@ export class Store<T extends Record<string, unknown>> {
232
232
  if (localResult) {
233
233
  promises.push(Promise.resolve(localResult));
234
234
 
235
- // Check local storage entries limit
235
+ // Check local storage entries limit
236
236
  await this.enforceMaxLocalEntries();
237
237
  }
238
238
  }
@@ -377,7 +377,7 @@ export class Store<T extends Record<string, unknown>> {
377
377
  ),
378
378
  );
379
379
 
380
- // Check local storage entries limit
380
+ // Check local storage entries limit
381
381
  await this.enforceMaxLocalEntries();
382
382
  }
383
383
 
@@ -410,9 +410,7 @@ export class Store<T extends Record<string, unknown>> {
410
410
  /**
411
411
  * Get query object for list data
412
412
  */
413
- async getListQuery(options: QueryOptions<T> = {}): Promise<QueryResult<T[]>> {
414
- await this.ensureInitialized();
415
-
413
+ getListQuery(options: QueryOptions<T> = {}): QueryResult<T[]> {
416
414
  const source = options.source;
417
415
 
418
416
  // Build query key
@@ -425,6 +423,7 @@ export class Store<T extends Record<string, unknown>> {
425
423
 
426
424
  // Build initial data fetch function
427
425
  const getInitialData = async (): Promise<T[]> => {
426
+ await this.ensureInitialized();
428
427
  if (this.localAdapter) {
429
428
  try {
430
429
  return await this.localAdapter.getList<T>(
@@ -96,7 +96,7 @@ class MockRemoteAdapter implements RemoteAdapter {
96
96
  };
97
97
  }
98
98
 
99
- async getListQuery<T extends Record<string, unknown>>(storeName: string, options?: QueryOptions<T>, idKey?: string) {
99
+ getListQuery<T extends Record<string, unknown>>(storeName: string, options?: QueryOptions<T>, idKey?: string) {
100
100
  return {
101
101
  queryKey: ["store", storeName, "remote", options],
102
102
  queryFn: async () => {
package/tsdown.config.ts CHANGED
@@ -2,10 +2,11 @@ import { defineConfig } from 'tsdown';
2
2
 
3
3
  export default defineConfig({
4
4
  entry: ['src/index.ts'],
5
- format: ['esm'],
5
+ format: ['esm', 'cjs'],
6
6
  dts: true,
7
7
  clean: true,
8
8
  sourcemap: true,
9
+ platform: 'neutral',
9
10
  });
10
11
 
11
12