@shuo-li/i18n 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,56 +1,19 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/core/cacheEvents.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunkJOUVTRSAcjs = require('./chunk-JOUVTRSA.cjs');
9
+
10
+ // src/core/cacheEvents.ts
2
11
  var I18N_RESOURCES_UPDATED_EVENT = "golucky:i18n-resources-updated";
3
12
  function emitI18nResourcesUpdated() {
4
13
  if (typeof window === "undefined") return;
5
14
  window.dispatchEvent(new CustomEvent(I18N_RESOURCES_UPDATED_EVENT));
6
15
  }
7
16
 
8
- // src/core/utils.ts
9
- function buildKey(moduleCode, langCode, store) {
10
- return store.cacheGroupKey ? `${moduleCode}_${langCode}_${store.cacheGroupKey}` : `${moduleCode}_${langCode}`;
11
- }
12
- function flatToNested(flat) {
13
- const result = {};
14
- for (const [key, value] of Object.entries(flat)) {
15
- const parts = key.split(".");
16
- let cur = result;
17
- for (let i = 0; i < parts.length - 1; i++) {
18
- const part = parts[i];
19
- if (typeof cur[part] !== "object" || cur[part] === null) {
20
- cur[part] = {};
21
- }
22
- cur = cur[part];
23
- }
24
- cur[parts[parts.length - 1]] = value;
25
- }
26
- return result;
27
- }
28
- function deepMerge(target, source) {
29
- const result = { ...target };
30
- for (const [key, sv] of Object.entries(source)) {
31
- const tv = result[key];
32
- if (sv !== null && typeof sv === "object" && !Array.isArray(sv) && tv !== null && typeof tv === "object" && !Array.isArray(tv)) {
33
- result[key] = deepMerge(tv, sv);
34
- } else {
35
- result[key] = sv;
36
- }
37
- }
38
- return result;
39
- }
40
- function toDefaultParams(p) {
41
- const result = {};
42
- if (_optionalChain([p, 'optionalAccess', _2 => _2.storeName])) result["storeName"] = p.storeName;
43
- if (_optionalChain([p, 'optionalAccess', _3 => _3.langCode])) result["langCode"] = p.langCode;
44
- if (_optionalChain([p, 'optionalAccess', _4 => _4.moduleCode])) result["moduleCode"] = p.moduleCode;
45
- if (_optionalChain([p, 'optionalAccess', _5 => _5.version]) != null) result["version"] = String(p.version);
46
- return result;
47
- }
48
- function toQueryString(params) {
49
- return new URLSearchParams(
50
- Object.entries(params).filter(([, v]) => v != null).map(([k, v]) => [k, String(v)])
51
- ).toString();
52
- }
53
-
54
17
  // src/core/manager.ts
55
18
  var _i18next = require('i18next'); var _i18next2 = _interopRequireDefault(_i18next);
56
19
 
@@ -79,7 +42,7 @@ var SSEClient = class {
79
42
  clearTimeout(this.reconnectTimer);
80
43
  this.reconnectTimer = null;
81
44
  }
82
- _optionalChain([this, 'access', _6 => _6.abortController, 'optionalAccess', _7 => _7.abort, 'call', _8 => _8()]);
45
+ _optionalChain([this, 'access', _2 => _2.abortController, 'optionalAccess', _3 => _3.abort, 'call', _4 => _4()]);
83
46
  this.abortController = null;
84
47
  }
85
48
  async connect() {
@@ -149,7 +112,7 @@ var SSEClient = class {
149
112
  if (!data) return;
150
113
  try {
151
114
  const parsed = JSON.parse(data);
152
- _optionalChain([this, 'access', _9 => _9.onMessage, 'optionalCall', _10 => _10(parsed)]);
115
+ _optionalChain([this, 'access', _5 => _5.onMessage, 'optionalCall', _6 => _6(parsed)]);
153
116
  } catch (e2) {
154
117
  }
155
118
  }
@@ -182,23 +145,42 @@ var WorkerManager = class {
182
145
  }
183
146
  const worker = createWorker();
184
147
  this.worker = worker;
148
+ const workerWritesDB = typeof callbacks.transformRaw === "function";
185
149
  worker.onMessage((msg) => {
186
150
  if (msg.type === "rawData") {
187
- const p = callbacks.onRawData(msg.task, msg.raw).catch(() => {
188
- });
189
- this.pendingCallbacks.add(p);
190
- p.finally(() => this.pendingCallbacks.delete(p));
151
+ if (workerWritesDB && callbacks.transformRaw) {
152
+ let blocks;
153
+ try {
154
+ blocks = callbacks.transformRaw(msg.task, msg.raw);
155
+ } catch (err) {
156
+ console.error("[i18n] transform failed", msg.task, err);
157
+ blocks = [];
158
+ }
159
+ worker.postMessage({ type: "parsedData", taskId: msg.task.taskId, blocks });
160
+ } else if (callbacks.onRawData) {
161
+ const p = callbacks.onRawData(msg.task, msg.raw).catch(() => {
162
+ });
163
+ this.pendingCallbacks.add(p);
164
+ p.finally(() => this.pendingCallbacks.delete(p));
165
+ }
166
+ } else if (msg.type === "moduleLoaded") {
167
+ if (callbacks.onModuleLoaded) {
168
+ const p = callbacks.onModuleLoaded(msg).catch(() => {
169
+ });
170
+ this.pendingCallbacks.add(p);
171
+ p.finally(() => this.pendingCallbacks.delete(p));
172
+ }
191
173
  } else if (msg.type === "moduleError") {
192
- _optionalChain([callbacks, 'access', _11 => _11.onModuleError, 'optionalCall', _12 => _12(msg)]);
174
+ _optionalChain([callbacks, 'access', _7 => _7.onModuleError, 'optionalCall', _8 => _8(msg)]);
193
175
  } else if (msg.type === "done" || msg.type === "error") {
194
- if (msg.type === "error") _optionalChain([callbacks, 'access', _13 => _13.onError, 'optionalCall', _14 => _14()]);
176
+ if (msg.type === "error") _optionalChain([callbacks, 'access', _9 => _9.onError, 'optionalCall', _10 => _10()]);
195
177
  this.finalize(callbacks);
196
178
  }
197
179
  });
198
180
  worker.postMessage({ type: "start", payload });
199
181
  }
200
182
  terminate() {
201
- _optionalChain([this, 'access', _15 => _15.worker, 'optionalAccess', _16 => _16.terminate, 'call', _17 => _17()]);
183
+ _optionalChain([this, 'access', _11 => _11.worker, 'optionalAccess', _12 => _12.terminate, 'call', _13 => _13()]);
202
184
  this.worker = null;
203
185
  }
204
186
  isRunning() {
@@ -227,6 +209,7 @@ var resolvedLanguages = [];
227
209
  var unloginPullStarted = false;
228
210
  var managerOptions = null;
229
211
  var initOptions = null;
212
+ var taskIdCounter = 0;
230
213
  var loadedModules = /* @__PURE__ */ new Set();
231
214
  var loadingModules = /* @__PURE__ */ new Set();
232
215
  var sseClient = new SSEClient();
@@ -299,15 +282,15 @@ async function getResource(moduleCode, langCode) {
299
282
  let merged = { ...getStaticLocale(moduleCode, langCode) };
300
283
  const results = await Promise.allSettled(
301
284
  resolvedStores.map(
302
- (store) => storage.getRecord(store.name, buildKey(moduleCode, langCode, store))
285
+ (store) => storage.getRecord(store.name, _chunkJOUVTRSAcjs.buildKey.call(void 0, moduleCode, langCode, store))
303
286
  )
304
287
  );
305
288
  for (let i = 0; i < resolvedStores.length; i++) {
306
289
  const result = results[i];
307
290
  if (result.status === "rejected") continue;
308
291
  const record = result.value;
309
- if (!_optionalChain([record, 'optionalAccess', _18 => _18.resources])) continue;
310
- merged = deepMerge(merged, record.resources);
292
+ if (!_optionalChain([record, 'optionalAccess', _14 => _14.resources])) continue;
293
+ merged = _chunkJOUVTRSAcjs.deepMerge.call(void 0, merged, record.resources);
311
294
  }
312
295
  return merged;
313
296
  }
@@ -363,24 +346,15 @@ async function _initI18n(options) {
363
346
  startSSE(options);
364
347
  }
365
348
  }
366
- var CACHE_VERSION_KEY = "__meta__:cache_version";
367
349
  async function checkCacheVersion(storage, options) {
368
350
  if (options.version == null) return;
369
- const baseStoreName = resolvedStores[0].name;
370
351
  const current = String(options.version);
371
- const record = await storage.getRecord(baseStoreName, CACHE_VERSION_KEY).catch(() => void 0);
372
- const stored = _optionalChain([record, 'optionalAccess', _19 => _19.resources, 'optionalAccess', _20 => _20["value"]]);
352
+ const stored = await storage.getMeta("cache_version").catch(() => null);
373
353
  if (stored === current) return;
374
354
  for (const store of options.stores) {
375
355
  await storage.clearStore(store.name);
376
356
  }
377
- await storage.putRecord(baseStoreName, {
378
- key: CACHE_VERSION_KEY,
379
- moduleCode: "__meta__",
380
- langCode: "__meta__",
381
- version: 0,
382
- resources: { value: current }
383
- });
357
+ await storage.setMeta("cache_version", current);
384
358
  }
385
359
  async function doUnloginPull(storage, options) {
386
360
  const { apiContext } = options;
@@ -396,11 +370,12 @@ async function doUnloginPull(storage, options) {
396
370
  }
397
371
  for (const block of blocks) {
398
372
  for (const mod of _nullishCoalesce(block.modules, () => ( []))) {
399
- const key = buildKey(mod.moduleCode, block.langCode, baseStore);
373
+ const key = _chunkJOUVTRSAcjs.buildKey.call(void 0, mod.moduleCode, block.langCode, baseStore);
400
374
  const existing = await storage.getRecord(baseStore.name, key);
401
- const resources = deepMerge(
402
- _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _21 => _21.resources]), () => ( {})),
403
- mod.resources
375
+ const flat = _chunkJOUVTRSAcjs.parseI18nValues.call(void 0, mod.i18nValues);
376
+ const resources = _chunkJOUVTRSAcjs.deepMerge.call(void 0,
377
+ _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _15 => _15.resources]), () => ( {})),
378
+ _chunkJOUVTRSAcjs.flatToNested.call(void 0, flat)
404
379
  );
405
380
  await storage.putRecord(baseStore.name, {
406
381
  key,
@@ -420,16 +395,13 @@ async function startWorkerFull(options) {
420
395
  const pull = apiContext.pull;
421
396
  const tasks = [];
422
397
  for (const store of resolvedStores) {
423
- for (const lang of resolvedLanguages) {
424
- for (const module of sortedModules()) {
425
- const internal = { storeName: store.name, langCode: lang, moduleCode: module, version: 0 };
426
- tasks.push({
427
- ...internal,
428
- trigger: "init-full",
429
- params: pull.buildParams ? pull.buildParams(internal) : void 0
430
- });
431
- }
432
- }
398
+ const internal = { storeName: store.name };
399
+ tasks.push({
400
+ storeName: store.name,
401
+ taskId: ++taskIdCounter,
402
+ trigger: "init-full",
403
+ params: pull.buildParams ? pull.buildParams(internal) : void 0
404
+ });
433
405
  }
434
406
  await runWorker(options, tasks, pull);
435
407
  }
@@ -437,16 +409,35 @@ function runWorker(options, tasks, pull) {
437
409
  return new Promise((resolve, reject) => {
438
410
  const { apiContext } = options;
439
411
  const storage = managerOptions.storage;
440
- workerManager.start(
441
- managerOptions.createWorker,
442
- {
443
- baseURL: apiContext.baseURL,
444
- headers: apiContext.getHeaders(),
445
- pullPath: pull.path,
446
- pullMethod: _nullishCoalesce(pull.method, () => ( "GET")),
447
- tasks
448
- },
449
- {
412
+ const workerWritesDB = _nullishCoalesce(managerOptions.workerWritesDB, () => ( false));
413
+ const payload = {
414
+ baseURL: apiContext.baseURL,
415
+ headers: apiContext.getHeaders(),
416
+ pullPath: pull.path,
417
+ pullMethod: _nullishCoalesce(pull.method, () => ( "GET")),
418
+ tasks,
419
+ ...workerWritesDB ? { storeConfigs: resolvedStores } : {}
420
+ };
421
+ if (workerWritesDB) {
422
+ workerManager.start(managerOptions.createWorker, payload, {
423
+ transformRaw: (task, raw) => {
424
+ try {
425
+ return pull.transform ? pull.transform(raw) : raw;
426
+ } catch (err) {
427
+ console.error("[i18n] pull transform \u5931\u8D25", task, err);
428
+ return [];
429
+ }
430
+ },
431
+ onModuleLoaded: async (info) => {
432
+ await onModuleLoaded(info);
433
+ },
434
+ onModuleError: () => {
435
+ },
436
+ onDone: resolve,
437
+ onError: () => reject(new Error("[i18n] Worker fatal error"))
438
+ });
439
+ } else {
440
+ workerManager.start(managerOptions.createWorker, payload, {
450
441
  onRawData: async (task, raw) => {
451
442
  let blocks;
452
443
  try {
@@ -460,10 +451,11 @@ function runWorker(options, tasks, pull) {
460
451
  const storeIndex = resolvedStores.indexOf(store);
461
452
  for (const block of blocks) {
462
453
  for (const mod of _nullishCoalesce(block.modules, () => ( []))) {
463
- const key = buildKey(mod.moduleCode, block.langCode, store);
454
+ const key = _chunkJOUVTRSAcjs.buildKey.call(void 0, mod.moduleCode, block.langCode, store);
464
455
  const existing = await storage.getRecord(store.name, key);
465
456
  if (existing && mod.version <= existing.version) continue;
466
- const resources = storeIndex === 0 ? deepMerge(_nullishCoalesce(_optionalChain([existing, 'optionalAccess', _22 => _22.resources]), () => ( {})), mod.resources) : { ..._nullishCoalesce(_optionalChain([existing, 'optionalAccess', _23 => _23.resources]), () => ( {})), ...mod.resources };
457
+ const flat = _chunkJOUVTRSAcjs.parseI18nValues.call(void 0, mod.i18nValues);
458
+ const resources = storeIndex === 0 ? _chunkJOUVTRSAcjs.deepMerge.call(void 0, _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _16 => _16.resources]), () => ( {})), _chunkJOUVTRSAcjs.flatToNested.call(void 0, flat)) : { ..._nullishCoalesce(_optionalChain([existing, 'optionalAccess', _17 => _17.resources]), () => ( {})), ...flat };
467
459
  await storage.putRecord(store.name, {
468
460
  key,
469
461
  moduleCode: mod.moduleCode,
@@ -473,19 +465,19 @@ function runWorker(options, tasks, pull) {
473
465
  });
474
466
  await onModuleLoaded({
475
467
  storeName: task.storeName,
476
- langCode: block.langCode,
477
468
  moduleCode: mod.moduleCode,
469
+ langCode: block.langCode,
478
470
  version: mod.version
479
471
  });
480
472
  }
481
473
  }
482
474
  },
483
- onModuleError: (_data) => {
475
+ onModuleError: () => {
484
476
  },
485
477
  onDone: resolve,
486
478
  onError: () => reject(new Error("[i18n] Worker fatal error"))
487
- }
488
- );
479
+ });
480
+ }
489
481
  });
490
482
  }
491
483
  async function onModuleLoaded(data) {
@@ -499,9 +491,9 @@ async function injectFromDB(moduleCode, langCode) {
499
491
  const storage = managerOptions.storage;
500
492
  for (let i = 0; i < resolvedStores.length; i++) {
501
493
  const store = resolvedStores[i];
502
- const key = buildKey(moduleCode, langCode, store);
494
+ const key = _chunkJOUVTRSAcjs.buildKey.call(void 0, moduleCode, langCode, store);
503
495
  const record = await storage.getRecord(store.name, key);
504
- if (!_optionalChain([record, 'optionalAccess', _24 => _24.resources])) continue;
496
+ if (!_optionalChain([record, 'optionalAccess', _18 => _18.resources])) continue;
505
497
  if (i === 0) {
506
498
  _i18next2.default.addResourceBundle(langCode, moduleCode, record.resources, true, true);
507
499
  } else {
@@ -523,7 +515,7 @@ function startSSE(options) {
523
515
  if (!apiContext.sse) return;
524
516
  sseClient.start(
525
517
  (raw) => {
526
- const msg = _optionalChain([apiContext, 'access', _25 => _25.sse, 'optionalAccess', _26 => _26.transformMessage]) ? apiContext.sse.transformMessage(raw) : raw;
518
+ const msg = _optionalChain([apiContext, 'access', _19 => _19.sse, 'optionalAccess', _20 => _20.transformMessage]) ? apiContext.sse.transformMessage(raw) : raw;
527
519
  void handleSSEMessage(msg, options);
528
520
  },
529
521
  {
@@ -606,10 +598,11 @@ async function pullAndStore(task, fromVersion, options) {
606
598
  const store = resolvedStores.find((s) => s.name === task.storeName);
607
599
  if (!store) continue;
608
600
  const storeIndex = resolvedStores.indexOf(store);
609
- const key = buildKey(mod.moduleCode, block.langCode, store);
601
+ const key = _chunkJOUVTRSAcjs.buildKey.call(void 0, mod.moduleCode, block.langCode, store);
610
602
  const existing = await storage.getRecord(store.name, key);
611
- if (mod.version <= (_nullishCoalesce(_optionalChain([existing, 'optionalAccess', _27 => _27.version]), () => ( 0)))) continue;
612
- const resources = storeIndex === 0 ? deepMerge(_nullishCoalesce(_optionalChain([existing, 'optionalAccess', _28 => _28.resources]), () => ( {})), mod.resources) : { ..._nullishCoalesce(_optionalChain([existing, 'optionalAccess', _29 => _29.resources]), () => ( {})), ...mod.resources };
603
+ if (mod.version <= (_nullishCoalesce(_optionalChain([existing, 'optionalAccess', _21 => _21.version]), () => ( 0)))) continue;
604
+ const flat = _chunkJOUVTRSAcjs.parseI18nValues.call(void 0, mod.i18nValues);
605
+ const resources = storeIndex === 0 ? _chunkJOUVTRSAcjs.deepMerge.call(void 0, _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _22 => _22.resources]), () => ( {})), _chunkJOUVTRSAcjs.flatToNested.call(void 0, flat)) : { ..._nullishCoalesce(_optionalChain([existing, 'optionalAccess', _23 => _23.resources]), () => ( {})), ...flat };
613
606
  const version = Math.max(mod.version, task.targetVersion);
614
607
  await storage.putRecord(store.name, {
615
608
  key,
@@ -625,7 +618,7 @@ async function doFetch(config, options, internalParams) {
625
618
  const fetchFn = _nullishCoalesce(managerOptions.fetchFn, () => ( globalThis.fetch.bind(globalThis)));
626
619
  const headers = options.apiContext.getHeaders();
627
620
  const url = options.apiContext.baseURL + config.path;
628
- const params = "buildParams" in config && config.buildParams ? config.buildParams(internalParams) : toDefaultParams(internalParams);
621
+ const params = "buildParams" in config && config.buildParams ? config.buildParams(internalParams) : _chunkJOUVTRSAcjs.toDefaultParams.call(void 0, internalParams);
629
622
  const method = "method" in config ? config.method : void 0;
630
623
  let res;
631
624
  if (method === "POST") {
@@ -635,7 +628,7 @@ async function doFetch(config, options, internalParams) {
635
628
  body: JSON.stringify(params)
636
629
  });
637
630
  } else {
638
- const qs = toQueryString(params);
631
+ const qs = _chunkJOUVTRSAcjs.toQueryString.call(void 0, params);
639
632
  res = await fetchFn(qs ? `${url}?${qs}` : url, { headers });
640
633
  }
641
634
  if (!res.ok) throw new Error(`[i18n] fetch failed: ${res.status} ${url}`);
@@ -653,19 +646,17 @@ function sortedModules() {
653
646
  return [...priority, ...rest];
654
647
  }
655
648
  function getStaticLocale(moduleCode, langCode) {
656
- return _nullishCoalesce(_optionalChain([initOptions, 'optionalAccess', _30 => _30.staticLocales, 'optionalAccess', _31 => _31[langCode], 'optionalAccess', _32 => _32[moduleCode]]), () => ( {}));
649
+ return _nullishCoalesce(_optionalChain([initOptions, 'optionalAccess', _24 => _24.staticLocales, 'optionalAccess', _25 => _25[langCode], 'optionalAccess', _26 => _26[moduleCode]]), () => ( {}));
657
650
  }
658
651
  async function getStoredVersion(store, moduleCode, langCode) {
659
652
  const storage = managerOptions.storage;
660
- const key = buildKey(moduleCode, langCode, store);
653
+ const key = _chunkJOUVTRSAcjs.buildKey.call(void 0, moduleCode, langCode, store);
661
654
  const record = await storage.getRecord(store.name, key);
662
- return _nullishCoalesce(_optionalChain([record, 'optionalAccess', _33 => _33.version]), () => ( 0));
655
+ return _nullishCoalesce(_optionalChain([record, 'optionalAccess', _27 => _27.version]), () => ( 0));
663
656
  }
664
657
 
665
658
 
666
659
 
667
660
 
668
661
 
669
-
670
-
671
- exports.I18N_RESOURCES_UPDATED_EVENT = I18N_RESOURCES_UPDATED_EVENT; exports.emitI18nResourcesUpdated = emitI18nResourcesUpdated; exports.flatToNested = flatToNested; exports.deepMerge = deepMerge; exports.createI18nManager = createI18nManager;
662
+ exports.I18N_RESOURCES_UPDATED_EVENT = I18N_RESOURCES_UPDATED_EVENT; exports.emitI18nResourcesUpdated = emitI18nResourcesUpdated; exports.createI18nManager = createI18nManager;
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
3
 
4
4
 
@@ -7,9 +7,11 @@ var _chunkAJJKJPNBcjs = require('./chunk-AJJKJPNB.cjs');
7
7
 
8
8
 
9
9
 
10
+ var _chunkUMU62XLBcjs = require('./chunk-UMU62XLB.cjs');
10
11
 
11
12
 
12
- var _chunkT7476FJ4cjs = require('./chunk-T7476FJ4.cjs');
13
+
14
+ var _chunkJOUVTRSAcjs = require('./chunk-JOUVTRSA.cjs');
13
15
 
14
16
  // src/index.ts
15
17
  var _i18next = require('i18next'); var _i18next2 = _interopRequireDefault(_i18next);
@@ -17,6 +19,7 @@ var _reacti18next = require('react-i18next');
17
19
 
18
20
  // src/storage/indexeddb.ts
19
21
  var DB_NAME = "i18n_cache";
22
+ var META_STORE = "i18n_meta";
20
23
  function resourceStoreName(name) {
21
24
  return `i18n_resources_${name}`;
22
25
  }
@@ -27,10 +30,13 @@ function openDB(storeNames, idbVersion) {
27
30
  const request = indexedDB.open(DB_NAME, idbVersion);
28
31
  request.onupgradeneeded = (event) => {
29
32
  const db = event.target.result;
33
+ if (!db.objectStoreNames.contains(META_STORE)) {
34
+ db.createObjectStore(META_STORE, { keyPath: "key" });
35
+ }
30
36
  for (const name of storeNames) {
31
- const storeName = resourceStoreName(name);
32
- if (!db.objectStoreNames.contains(storeName)) {
33
- const s = db.createObjectStore(storeName, { keyPath: "key" });
37
+ const sName = resourceStoreName(name);
38
+ if (!db.objectStoreNames.contains(sName)) {
39
+ const s = db.createObjectStore(sName, { keyPath: "key" });
34
40
  s.createIndex("by_module", "moduleCode");
35
41
  s.createIndex("by_language", "langCode");
36
42
  }
@@ -74,18 +80,16 @@ async function withRetry(fn) {
74
80
  }
75
81
  var IndexedDBAdapter = class {
76
82
  /**
77
- * schemaVersion 来自外部传入的 options.version。
78
- * IDB 版本 = schemaVersion * 100 + stores.length,保证:
79
- * - options.version 变化 → IDB 版本变化 → onupgradeneeded → 触发 checkCacheVersion 的数据清理
80
- * - store 数量变化(未登录→登录)→ IDB 版本变化 → onupgradeneeded → 新增 store
83
+ * idbVersion = schemaVersion * 100 + stores.length + 1
84
+ * +1 确保升级时创建 i18n_meta objectStore(新用户自动建,老用户触发 onupgradeneeded)
81
85
  */
82
86
  async ensureStores(stores, schemaVersion = 1) {
83
87
  const storeNames = stores.map((s) => s.name);
84
- const idbVersion = schemaVersion * 100 + storeNames.length;
88
+ const idbVersion = schemaVersion * 100 + storeNames.length + 1;
85
89
  if (dbInstance) {
86
90
  const allExist = storeNames.every(
87
91
  (n) => dbInstance.objectStoreNames.contains(resourceStoreName(n))
88
- );
92
+ ) && dbInstance.objectStoreNames.contains(META_STORE);
89
93
  if (allExist && dbInstance.version === idbVersion) return;
90
94
  dbInstance.close();
91
95
  dbInstance = null;
@@ -107,16 +111,14 @@ var IndexedDBAdapter = class {
107
111
  return withRetry(async () => {
108
112
  const db = await getDB();
109
113
  const tx = db.transaction(resourceStoreName(storeName), "readonly");
110
- const store = tx.objectStore(resourceStoreName(storeName));
111
- return idbRequest(store.get(key));
114
+ return idbRequest(tx.objectStore(resourceStoreName(storeName)).get(key));
112
115
  });
113
116
  }
114
117
  async putRecord(storeName, record) {
115
118
  await withRetry(async () => {
116
119
  const db = await getDB();
117
120
  const tx = db.transaction(resourceStoreName(storeName), "readwrite");
118
- const store = tx.objectStore(resourceStoreName(storeName));
119
- await idbRequest(store.put(record));
121
+ await idbRequest(tx.objectStore(resourceStoreName(storeName)).put(record));
120
122
  });
121
123
  }
122
124
  async getAllByModule(storeName, moduleCode) {
@@ -138,10 +140,10 @@ var IndexedDBAdapter = class {
138
140
  return withRetry(async () => {
139
141
  const db = await getDB();
140
142
  for (const store of stores) {
141
- const tx = db.transaction(resourceStoreName(store.name), "readonly");
142
- const objStore = tx.objectStore(resourceStoreName(store.name));
143
+ const sName = resourceStoreName(store.name);
144
+ const tx = db.transaction(sName, "readonly");
143
145
  const found = await new Promise((resolve, reject) => {
144
- const req = objStore.openCursor();
146
+ const req = tx.objectStore(sName).openCursor();
145
147
  req.onerror = () => reject(req.error);
146
148
  req.onsuccess = () => {
147
149
  const cursor = req.result;
@@ -149,8 +151,7 @@ var IndexedDBAdapter = class {
149
151
  resolve(false);
150
152
  return;
151
153
  }
152
- const record = cursor.value;
153
- if (!record.key.startsWith("UNLOGIN_") && !record.key.startsWith("__meta__:")) {
154
+ if (!cursor.value.key.startsWith("UNLOGIN_")) {
154
155
  resolve(true);
155
156
  return;
156
157
  }
@@ -162,6 +163,23 @@ var IndexedDBAdapter = class {
162
163
  return true;
163
164
  });
164
165
  }
166
+ async getMeta(key) {
167
+ return withRetry(async () => {
168
+ const db = await getDB();
169
+ const tx = db.transaction(META_STORE, "readonly");
170
+ const record = await idbRequest(
171
+ tx.objectStore(META_STORE).get(key)
172
+ );
173
+ return _nullishCoalesce(_optionalChain([record, 'optionalAccess', _ => _.value]), () => ( null));
174
+ });
175
+ }
176
+ async setMeta(key, value) {
177
+ await withRetry(async () => {
178
+ const db = await getDB();
179
+ const tx = db.transaction(META_STORE, "readwrite");
180
+ await idbRequest(tx.objectStore(META_STORE).put({ key, value }));
181
+ });
182
+ }
165
183
  };
166
184
 
167
185
  // src/index.ts
@@ -182,8 +200,9 @@ if (!_i18next2.default.isInitialized) {
182
200
  }
183
201
  });
184
202
  }
185
- var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkT7476FJ4cjs.createI18nManager.call(void 0, {
203
+ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkUMU62XLBcjs.createI18nManager.call(void 0, {
186
204
  storage: new IndexedDBAdapter(),
205
+ workerWritesDB: true,
187
206
  createWorker: () => new (0, _chunkAJJKJPNBcjs.WebWorkerAdapter)(
188
207
  new Worker(new URL("./workers/preload-worker.js", import.meta.url), { type: "module" })
189
208
  )
@@ -200,4 +219,4 @@ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } =
200
219
 
201
220
 
202
221
 
203
- exports.I18N_RESOURCES_UPDATED_EVENT = _chunkT7476FJ4cjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.deepMerge = _chunkT7476FJ4cjs.deepMerge; exports.emitI18nResourcesUpdated = _chunkT7476FJ4cjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.flatToNested = _chunkT7476FJ4cjs.flatToNested; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
222
+ exports.I18N_RESOURCES_UPDATED_EVENT = _chunkUMU62XLBcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.deepMerge = _chunkJOUVTRSAcjs.deepMerge; exports.emitI18nResourcesUpdated = _chunkUMU62XLBcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.flatToNested = _chunkJOUVTRSAcjs.flatToNested; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as closeSSE$1, e as ensureModules$1, g as getAllRecordsByModule$1, a as getResource$1, i as initI18n$1 } from './cacheEvents-DAFvp5or.cjs';
2
- export { I as I18N_RESOURCES_UPDATED_EVENT, b as I18nInitOptions, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, W as WorkerLike, h as emitI18nResourcesUpdated } from './cacheEvents-DAFvp5or.cjs';
1
+ import { c as closeSSE$1, e as ensureModules$1, g as getAllRecordsByModule$1, a as getResource$1, i as initI18n$1 } from './cacheEvents-BwXBBuex.cjs';
2
+ export { I as I18N_RESOURCES_UPDATED_EVENT, b as I18nInitOptions, j as I18nValue, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, W as WorkerLike, h as emitI18nResourcesUpdated } from './cacheEvents-BwXBBuex.cjs';
3
3
  export { u as useDict } from './hooks-ClO29Chr.cjs';
4
4
  export { useTranslation } from 'react-i18next';
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as closeSSE$1, e as ensureModules$1, g as getAllRecordsByModule$1, a as getResource$1, i as initI18n$1 } from './cacheEvents-DAFvp5or.js';
2
- export { I as I18N_RESOURCES_UPDATED_EVENT, b as I18nInitOptions, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, W as WorkerLike, h as emitI18nResourcesUpdated } from './cacheEvents-DAFvp5or.js';
1
+ import { c as closeSSE$1, e as ensureModules$1, g as getAllRecordsByModule$1, a as getResource$1, i as initI18n$1 } from './cacheEvents-BwXBBuex.js';
2
+ export { I as I18N_RESOURCES_UPDATED_EVENT, b as I18nInitOptions, j as I18nValue, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, W as WorkerLike, h as emitI18nResourcesUpdated } from './cacheEvents-BwXBBuex.js';
3
3
  export { u as useDict } from './hooks-ClO29Chr.js';
4
4
  export { useTranslation } from 'react-i18next';
5
5