@shuo-li/i18n 1.0.7 → 1.0.9

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.
@@ -339,7 +339,8 @@ async function _initI18n(options) {
339
339
  resolvedStaticModules = options.staticLocales ? [...new Set(
340
340
  Object.values(options.staticLocales).flatMap((langModules) => Object.keys(langModules))
341
341
  )] : [];
342
- await storage.ensureStores(resolvedStores);
342
+ const schemaVersion = options.version != null ? Math.max(1, Math.trunc(Number(options.version)) || 1) : 1;
343
+ await storage.ensureStores(resolvedStores, schemaVersion);
343
344
  await checkCacheVersion(storage, options);
344
345
  const allKnownModules = sortedModules();
345
346
  for (const lang of resolvedLanguages) {
@@ -339,7 +339,8 @@ async function _initI18n(options) {
339
339
  resolvedStaticModules = options.staticLocales ? [...new Set(
340
340
  Object.values(options.staticLocales).flatMap((langModules) => Object.keys(langModules))
341
341
  )] : [];
342
- await storage.ensureStores(resolvedStores);
342
+ const schemaVersion = options.version != null ? Math.max(1, Math.trunc(Number(options.version)) || 1) : 1;
343
+ await storage.ensureStores(resolvedStores, schemaVersion);
343
344
  await checkCacheVersion(storage, options);
344
345
  const allKnownModules = sortedModules();
345
346
  for (const lang of resolvedLanguages) {
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 }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
2
 
3
3
 
4
4
 
@@ -7,7 +7,7 @@ var _chunkAJJKJPNBcjs = require('./chunk-AJJKJPNB.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunk2EV6FQILcjs = require('./chunk-2EV6FQIL.cjs');
10
+ var _chunkDSK7CM4Gcjs = require('./chunk-DSK7CM4G.cjs');
11
11
 
12
12
  // src/index.ts
13
13
  var _i18next = require('i18next'); var _i18next2 = _interopRequireDefault(_i18next);
@@ -15,16 +15,14 @@ var _reacti18next = require('react-i18next');
15
15
 
16
16
  // src/storage/indexeddb.ts
17
17
  var DB_NAME = "i18n_cache";
18
- var SCHEMA_VERSION = 2;
19
18
  function resourceStoreName(name) {
20
19
  return `i18n_resources_${name}`;
21
20
  }
22
21
  var dbInstance = null;
23
22
  var dbOpenPromise = null;
24
- var dbStoreNames = [];
25
- function openDB(storeNames) {
23
+ function openDB(storeNames, idbVersion) {
26
24
  return new Promise((resolve, reject) => {
27
- const request = indexedDB.open(DB_NAME, SCHEMA_VERSION);
25
+ const request = indexedDB.open(DB_NAME, idbVersion);
28
26
  request.onupgradeneeded = (event) => {
29
27
  const db = event.target.result;
30
28
  for (const name of storeNames) {
@@ -53,18 +51,9 @@ function openDB(storeNames) {
53
51
  request.onblocked = () => reject(new Error("[i18n] IndexedDB open blocked"));
54
52
  });
55
53
  }
56
- function getDB(storeNames) {
54
+ function getDB() {
57
55
  if (dbInstance) return Promise.resolve(dbInstance);
58
- if (!dbOpenPromise) {
59
- dbOpenPromise = openDB(_nullishCoalesce(storeNames, () => ( dbStoreNames))).then((db) => {
60
- dbInstance = db;
61
- dbOpenPromise = null;
62
- return db;
63
- }).catch((err) => {
64
- dbOpenPromise = null;
65
- throw err;
66
- });
67
- }
56
+ if (!dbOpenPromise) throw new Error("[i18n] ensureStores must be called before using the DB");
68
57
  return dbOpenPromise;
69
58
  }
70
59
  function idbRequest(req) {
@@ -82,9 +71,35 @@ async function withRetry(fn) {
82
71
  }
83
72
  }
84
73
  var IndexedDBAdapter = class {
85
- async ensureStores(stores) {
86
- dbStoreNames = stores.map((s) => s.name);
87
- await getDB(dbStoreNames);
74
+ /**
75
+ * schemaVersion 来自外部传入的 options.version。
76
+ * IDB 版本 = schemaVersion * 100 + stores.length,保证:
77
+ * - options.version 变化 → IDB 版本变化 → onupgradeneeded → 触发 checkCacheVersion 的数据清理
78
+ * - store 数量变化(未登录→登录)→ IDB 版本变化 → onupgradeneeded → 新增 store
79
+ */
80
+ async ensureStores(stores, schemaVersion = 1) {
81
+ const storeNames = stores.map((s) => s.name);
82
+ const idbVersion = schemaVersion * 100 + storeNames.length;
83
+ if (dbInstance) {
84
+ const allExist = storeNames.every(
85
+ (n) => dbInstance.objectStoreNames.contains(resourceStoreName(n))
86
+ );
87
+ if (allExist && dbInstance.version === idbVersion) return;
88
+ dbInstance.close();
89
+ dbInstance = null;
90
+ dbOpenPromise = null;
91
+ }
92
+ if (!dbOpenPromise) {
93
+ dbOpenPromise = openDB(storeNames, idbVersion).then((db) => {
94
+ dbInstance = db;
95
+ dbOpenPromise = null;
96
+ return db;
97
+ }).catch((err) => {
98
+ dbOpenPromise = null;
99
+ throw err;
100
+ });
101
+ }
102
+ await dbOpenPromise;
88
103
  }
89
104
  async getRecord(storeName, key) {
90
105
  return withRetry(async () => {
@@ -165,7 +180,7 @@ if (!_i18next2.default.isInitialized) {
165
180
  }
166
181
  });
167
182
  }
168
- var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunk2EV6FQILcjs.createI18nManager.call(void 0, {
183
+ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkDSK7CM4Gcjs.createI18nManager.call(void 0, {
169
184
  storage: new IndexedDBAdapter(),
170
185
  createWorker: () => new (0, _chunkAJJKJPNBcjs.WebWorkerAdapter)(
171
186
  new Worker(new URL("./workers/preload-worker.js", import.meta.url), { type: "module" })
@@ -181,4 +196,4 @@ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } =
181
196
 
182
197
 
183
198
 
184
- exports.I18N_RESOURCES_UPDATED_EVENT = _chunk2EV6FQILcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunk2EV6FQILcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
199
+ exports.I18N_RESOURCES_UPDATED_EVENT = _chunkDSK7CM4Gcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkDSK7CM4Gcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  I18N_RESOURCES_UPDATED_EVENT,
8
8
  createI18nManager,
9
9
  emitI18nResourcesUpdated
10
- } from "./chunk-5VHZCG34.js";
10
+ } from "./chunk-3ALMQ7Q5.js";
11
11
 
12
12
  // src/index.ts
13
13
  import i18n from "i18next";
@@ -15,16 +15,14 @@ import { initReactI18next } from "react-i18next";
15
15
 
16
16
  // src/storage/indexeddb.ts
17
17
  var DB_NAME = "i18n_cache";
18
- var SCHEMA_VERSION = 2;
19
18
  function resourceStoreName(name) {
20
19
  return `i18n_resources_${name}`;
21
20
  }
22
21
  var dbInstance = null;
23
22
  var dbOpenPromise = null;
24
- var dbStoreNames = [];
25
- function openDB(storeNames) {
23
+ function openDB(storeNames, idbVersion) {
26
24
  return new Promise((resolve, reject) => {
27
- const request = indexedDB.open(DB_NAME, SCHEMA_VERSION);
25
+ const request = indexedDB.open(DB_NAME, idbVersion);
28
26
  request.onupgradeneeded = (event) => {
29
27
  const db = event.target.result;
30
28
  for (const name of storeNames) {
@@ -53,18 +51,9 @@ function openDB(storeNames) {
53
51
  request.onblocked = () => reject(new Error("[i18n] IndexedDB open blocked"));
54
52
  });
55
53
  }
56
- function getDB(storeNames) {
54
+ function getDB() {
57
55
  if (dbInstance) return Promise.resolve(dbInstance);
58
- if (!dbOpenPromise) {
59
- dbOpenPromise = openDB(storeNames ?? dbStoreNames).then((db) => {
60
- dbInstance = db;
61
- dbOpenPromise = null;
62
- return db;
63
- }).catch((err) => {
64
- dbOpenPromise = null;
65
- throw err;
66
- });
67
- }
56
+ if (!dbOpenPromise) throw new Error("[i18n] ensureStores must be called before using the DB");
68
57
  return dbOpenPromise;
69
58
  }
70
59
  function idbRequest(req) {
@@ -82,9 +71,35 @@ async function withRetry(fn) {
82
71
  }
83
72
  }
84
73
  var IndexedDBAdapter = class {
85
- async ensureStores(stores) {
86
- dbStoreNames = stores.map((s) => s.name);
87
- await getDB(dbStoreNames);
74
+ /**
75
+ * schemaVersion 来自外部传入的 options.version。
76
+ * IDB 版本 = schemaVersion * 100 + stores.length,保证:
77
+ * - options.version 变化 → IDB 版本变化 → onupgradeneeded → 触发 checkCacheVersion 的数据清理
78
+ * - store 数量变化(未登录→登录)→ IDB 版本变化 → onupgradeneeded → 新增 store
79
+ */
80
+ async ensureStores(stores, schemaVersion = 1) {
81
+ const storeNames = stores.map((s) => s.name);
82
+ const idbVersion = schemaVersion * 100 + storeNames.length;
83
+ if (dbInstance) {
84
+ const allExist = storeNames.every(
85
+ (n) => dbInstance.objectStoreNames.contains(resourceStoreName(n))
86
+ );
87
+ if (allExist && dbInstance.version === idbVersion) return;
88
+ dbInstance.close();
89
+ dbInstance = null;
90
+ dbOpenPromise = null;
91
+ }
92
+ if (!dbOpenPromise) {
93
+ dbOpenPromise = openDB(storeNames, idbVersion).then((db) => {
94
+ dbInstance = db;
95
+ dbOpenPromise = null;
96
+ return db;
97
+ }).catch((err) => {
98
+ dbOpenPromise = null;
99
+ throw err;
100
+ });
101
+ }
102
+ await dbOpenPromise;
88
103
  }
89
104
  async getRecord(storeName, key) {
90
105
  return withRetry(async () => {
package/dist/mp/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- var _chunk2EV6FQILcjs = require('../chunk-2EV6FQIL.cjs');
5
+ var _chunkDSK7CM4Gcjs = require('../chunk-DSK7CM4G.cjs');
6
6
 
7
7
  // src/storage/wx-sqlite.ts
8
8
  var DB_NAME = "i18n_cache";
@@ -39,7 +39,7 @@ function exec(db, sql, args = []) {
39
39
  });
40
40
  }
41
41
  var WxSQLiteAdapter = class {
42
- async ensureStores(stores) {
42
+ async ensureStores(stores, _schemaVersion) {
43
43
  const db = await getDB();
44
44
  for (const store of stores) {
45
45
  const table = resourceTable(store.name);
@@ -181,7 +181,7 @@ function wxFetch(input, init) {
181
181
  }
182
182
 
183
183
  // src/mp/index.ts
184
- var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunk2EV6FQILcjs.createI18nManager.call(void 0, {
184
+ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkDSK7CM4Gcjs.createI18nManager.call(void 0, {
185
185
  storage: new WxSQLiteAdapter(),
186
186
  createWorker: () => new WxWorkerAdapter(wx.createWorker("workers/preload-worker-mp.js")),
187
187
  fetchFn: wxFetch
@@ -194,4 +194,4 @@ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } =
194
194
 
195
195
 
196
196
 
197
- exports.I18N_RESOURCES_UPDATED_EVENT = _chunk2EV6FQILcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunk2EV6FQILcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n;
197
+ exports.I18N_RESOURCES_UPDATED_EVENT = _chunkDSK7CM4Gcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkDSK7CM4Gcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n;
package/dist/mp/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  I18N_RESOURCES_UPDATED_EVENT,
3
3
  createI18nManager,
4
4
  emitI18nResourcesUpdated
5
- } from "../chunk-5VHZCG34.js";
5
+ } from "../chunk-3ALMQ7Q5.js";
6
6
 
7
7
  // src/storage/wx-sqlite.ts
8
8
  var DB_NAME = "i18n_cache";
@@ -39,7 +39,7 @@ function exec(db, sql, args = []) {
39
39
  });
40
40
  }
41
41
  var WxSQLiteAdapter = class {
42
- async ensureStores(stores) {
42
+ async ensureStores(stores, _schemaVersion) {
43
43
  const db = await getDB();
44
44
  for (const store of stores) {
45
45
  const table = resourceTable(store.name);
@@ -7,7 +7,7 @@ var _chunkAJJKJPNBcjs = require('../chunk-AJJKJPNB.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunk2EV6FQILcjs = require('../chunk-2EV6FQIL.cjs');
10
+ var _chunkDSK7CM4Gcjs = require('../chunk-DSK7CM4G.cjs');
11
11
 
12
12
  // src/native/index.ts
13
13
  var _i18next = require('i18next'); var _i18next2 = _interopRequireDefault(_i18next);
@@ -30,7 +30,7 @@ async function execute(sql, params = []) {
30
30
  return db.executeAsync(sql, params);
31
31
  }
32
32
  var SQLiteAdapter = class {
33
- async ensureStores(stores) {
33
+ async ensureStores(stores, _schemaVersion) {
34
34
  for (const store of stores) {
35
35
  const table = resourceTable(store.name);
36
36
  await execute(`
@@ -121,7 +121,7 @@ if (!_i18next2.default.isInitialized) {
121
121
  }
122
122
  });
123
123
  }
124
- var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunk2EV6FQILcjs.createI18nManager.call(void 0, {
124
+ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkDSK7CM4Gcjs.createI18nManager.call(void 0, {
125
125
  storage: new SQLiteAdapter(),
126
126
  // Hermes Worker(RN 0.71+),API 与 Web Worker 一致
127
127
  createWorker: () => new (0, _chunkAJJKJPNBcjs.WebWorkerAdapter)(
@@ -138,4 +138,4 @@ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } =
138
138
 
139
139
 
140
140
 
141
- exports.I18N_RESOURCES_UPDATED_EVENT = _chunk2EV6FQILcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunk2EV6FQILcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
141
+ exports.I18N_RESOURCES_UPDATED_EVENT = _chunkDSK7CM4Gcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkDSK7CM4Gcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
@@ -7,7 +7,7 @@ import {
7
7
  I18N_RESOURCES_UPDATED_EVENT,
8
8
  createI18nManager,
9
9
  emitI18nResourcesUpdated
10
- } from "../chunk-5VHZCG34.js";
10
+ } from "../chunk-3ALMQ7Q5.js";
11
11
 
12
12
  // src/native/index.ts
13
13
  import i18n from "i18next";
@@ -30,7 +30,7 @@ async function execute(sql, params = []) {
30
30
  return db.executeAsync(sql, params);
31
31
  }
32
32
  var SQLiteAdapter = class {
33
- async ensureStores(stores) {
33
+ async ensureStores(stores, _schemaVersion) {
34
34
  for (const store of stores) {
35
35
  const table = resourceTable(store.name);
36
36
  await execute(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuo-li/i18n",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Cross-platform i18n library for Web, React Native and WeChat MiniProgram",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",