@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.
package/dist/index.js CHANGED
@@ -6,10 +6,12 @@ import {
6
6
  import {
7
7
  I18N_RESOURCES_UPDATED_EVENT,
8
8
  createI18nManager,
9
+ emitI18nResourcesUpdated
10
+ } from "./chunk-FFIQQFC4.js";
11
+ import {
9
12
  deepMerge,
10
- emitI18nResourcesUpdated,
11
13
  flatToNested
12
- } from "./chunk-LZQP6OHB.js";
14
+ } from "./chunk-NEXKR7GY.js";
13
15
 
14
16
  // src/index.ts
15
17
  import i18n from "i18next";
@@ -17,6 +19,7 @@ import { initReactI18next } from "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 record?.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
@@ -184,6 +202,7 @@ if (!i18n.isInitialized) {
184
202
  }
185
203
  var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = createI18nManager({
186
204
  storage: new IndexedDBAdapter(),
205
+ workerWritesDB: true,
187
206
  createWorker: () => new WebWorkerAdapter(
188
207
  new Worker(new URL("./workers/preload-worker.js", import.meta.url), { type: "module" })
189
208
  )
package/dist/mp/index.cjs CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkT7476FJ4cjs = require('../chunk-T7476FJ4.cjs');
5
+ var _chunkUMU62XLBcjs = require('../chunk-UMU62XLB.cjs');
6
+ require('../chunk-JOUVTRSA.cjs');
6
7
 
7
8
  // src/storage/wx-sqlite.ts
8
9
  var DB_NAME = "i18n_cache";
10
+ var META_TABLE = "i18n_meta";
9
11
  function resourceTable(name) {
10
12
  return `i18n_resources_${name}`;
11
13
  }
@@ -41,6 +43,12 @@ function exec(db, sql, args = []) {
41
43
  var WxSQLiteAdapter = class {
42
44
  async ensureStores(stores, _schemaVersion) {
43
45
  const db = await getDB();
46
+ await exec(db, `
47
+ CREATE TABLE IF NOT EXISTS ${META_TABLE} (
48
+ key TEXT PRIMARY KEY,
49
+ value TEXT NOT NULL
50
+ )
51
+ `);
44
52
  for (const store of stores) {
45
53
  const table = resourceTable(store.name);
46
54
  await exec(db, `
@@ -64,11 +72,7 @@ var WxSQLiteAdapter = class {
64
72
  }
65
73
  async getRecord(storeName, key) {
66
74
  const db = await getDB();
67
- const result = await exec(
68
- db,
69
- `SELECT * FROM ${resourceTable(storeName)} WHERE key = ?`,
70
- [key]
71
- );
75
+ const result = await exec(db, `SELECT * FROM ${resourceTable(storeName)} WHERE key = ?`, [key]);
72
76
  if (result.rows.length === 0) return void 0;
73
77
  return rowToRecord(result.rows.item(0));
74
78
  }
@@ -111,12 +115,30 @@ var WxSQLiteAdapter = class {
111
115
  const result = await exec(
112
116
  db,
113
117
  `SELECT key FROM ${resourceTable(store.name)}
114
- WHERE key NOT LIKE 'UNLOGIN_%' AND key NOT LIKE '__meta__:%' LIMIT 1`
118
+ WHERE key NOT LIKE 'UNLOGIN_%' LIMIT 1`
115
119
  );
116
120
  if (result.rows.length === 0) return false;
117
121
  }
118
122
  return true;
119
123
  }
124
+ async getMeta(key) {
125
+ const db = await getDB();
126
+ const result = await exec(
127
+ db,
128
+ `SELECT value FROM ${META_TABLE} WHERE key = ?`,
129
+ [key]
130
+ );
131
+ if (result.rows.length === 0) return null;
132
+ return result.rows.item(0).value;
133
+ }
134
+ async setMeta(key, value) {
135
+ const db = await getDB();
136
+ await exec(
137
+ db,
138
+ `INSERT OR REPLACE INTO ${META_TABLE} (key, value) VALUES (?, ?)`,
139
+ [key, value]
140
+ );
141
+ }
120
142
  };
121
143
  function rowToRecord(row) {
122
144
  return {
@@ -181,7 +203,7 @@ function wxFetch(input, init) {
181
203
  }
182
204
 
183
205
  // src/mp/index.ts
184
- var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkT7476FJ4cjs.createI18nManager.call(void 0, {
206
+ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkUMU62XLBcjs.createI18nManager.call(void 0, {
185
207
  storage: new WxSQLiteAdapter(),
186
208
  createWorker: () => new WxWorkerAdapter(wx.createWorker("workers/preload-worker-mp.js")),
187
209
  fetchFn: wxFetch
@@ -194,4 +216,4 @@ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } =
194
216
 
195
217
 
196
218
 
197
- exports.I18N_RESOURCES_UPDATED_EVENT = _chunkT7476FJ4cjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkT7476FJ4cjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n;
219
+ exports.I18N_RESOURCES_UPDATED_EVENT = _chunkUMU62XLBcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkUMU62XLBcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n;
@@ -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, 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, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, h as emitI18nResourcesUpdated } from '../cacheEvents-BwXBBuex.cjs';
3
3
 
4
4
  declare const initI18n: typeof initI18n$1;
5
5
  declare const closeSSE: typeof closeSSE$1;
@@ -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, 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, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, h as emitI18nResourcesUpdated } from '../cacheEvents-BwXBBuex.js';
3
3
 
4
4
  declare const initI18n: typeof initI18n$1;
5
5
  declare const closeSSE: typeof closeSSE$1;
package/dist/mp/index.js CHANGED
@@ -2,10 +2,12 @@ import {
2
2
  I18N_RESOURCES_UPDATED_EVENT,
3
3
  createI18nManager,
4
4
  emitI18nResourcesUpdated
5
- } from "../chunk-LZQP6OHB.js";
5
+ } from "../chunk-FFIQQFC4.js";
6
+ import "../chunk-NEXKR7GY.js";
6
7
 
7
8
  // src/storage/wx-sqlite.ts
8
9
  var DB_NAME = "i18n_cache";
10
+ var META_TABLE = "i18n_meta";
9
11
  function resourceTable(name) {
10
12
  return `i18n_resources_${name}`;
11
13
  }
@@ -41,6 +43,12 @@ function exec(db, sql, args = []) {
41
43
  var WxSQLiteAdapter = class {
42
44
  async ensureStores(stores, _schemaVersion) {
43
45
  const db = await getDB();
46
+ await exec(db, `
47
+ CREATE TABLE IF NOT EXISTS ${META_TABLE} (
48
+ key TEXT PRIMARY KEY,
49
+ value TEXT NOT NULL
50
+ )
51
+ `);
44
52
  for (const store of stores) {
45
53
  const table = resourceTable(store.name);
46
54
  await exec(db, `
@@ -64,11 +72,7 @@ var WxSQLiteAdapter = class {
64
72
  }
65
73
  async getRecord(storeName, key) {
66
74
  const db = await getDB();
67
- const result = await exec(
68
- db,
69
- `SELECT * FROM ${resourceTable(storeName)} WHERE key = ?`,
70
- [key]
71
- );
75
+ const result = await exec(db, `SELECT * FROM ${resourceTable(storeName)} WHERE key = ?`, [key]);
72
76
  if (result.rows.length === 0) return void 0;
73
77
  return rowToRecord(result.rows.item(0));
74
78
  }
@@ -111,12 +115,30 @@ var WxSQLiteAdapter = class {
111
115
  const result = await exec(
112
116
  db,
113
117
  `SELECT key FROM ${resourceTable(store.name)}
114
- WHERE key NOT LIKE 'UNLOGIN_%' AND key NOT LIKE '__meta__:%' LIMIT 1`
118
+ WHERE key NOT LIKE 'UNLOGIN_%' LIMIT 1`
115
119
  );
116
120
  if (result.rows.length === 0) return false;
117
121
  }
118
122
  return true;
119
123
  }
124
+ async getMeta(key) {
125
+ const db = await getDB();
126
+ const result = await exec(
127
+ db,
128
+ `SELECT value FROM ${META_TABLE} WHERE key = ?`,
129
+ [key]
130
+ );
131
+ if (result.rows.length === 0) return null;
132
+ return result.rows.item(0).value;
133
+ }
134
+ async setMeta(key, value) {
135
+ const db = await getDB();
136
+ await exec(
137
+ db,
138
+ `INSERT OR REPLACE INTO ${META_TABLE} (key, value) VALUES (?, ?)`,
139
+ [key, value]
140
+ );
141
+ }
120
142
  };
121
143
  function rowToRecord(row) {
122
144
  return {
@@ -7,7 +7,8 @@ var _chunkAJJKJPNBcjs = require('../chunk-AJJKJPNB.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunkT7476FJ4cjs = require('../chunk-T7476FJ4.cjs');
10
+ var _chunkUMU62XLBcjs = require('../chunk-UMU62XLB.cjs');
11
+ require('../chunk-JOUVTRSA.cjs');
11
12
 
12
13
  // src/native/index.ts
13
14
  var _i18next = require('i18next'); var _i18next2 = _interopRequireDefault(_i18next);
@@ -15,6 +16,7 @@ var _reacti18next = require('react-i18next');
15
16
 
16
17
  // src/storage/sqlite.ts
17
18
  var DB_NAME = "i18n_cache";
19
+ var META_TABLE = "i18n_meta";
18
20
  function resourceTable(name) {
19
21
  return `i18n_resources_${name}`;
20
22
  }
@@ -31,6 +33,12 @@ async function execute(sql, params = []) {
31
33
  }
32
34
  var SQLiteAdapter = class {
33
35
  async ensureStores(stores, _schemaVersion) {
36
+ await execute(`
37
+ CREATE TABLE IF NOT EXISTS ${META_TABLE} (
38
+ key TEXT PRIMARY KEY,
39
+ value TEXT NOT NULL
40
+ )
41
+ `);
34
42
  for (const store of stores) {
35
43
  const table = resourceTable(store.name);
36
44
  await execute(`
@@ -86,12 +94,26 @@ var SQLiteAdapter = class {
86
94
  for (const store of stores) {
87
95
  const { rows } = await execute(
88
96
  `SELECT key FROM ${resourceTable(store.name)}
89
- WHERE key NOT LIKE 'UNLOGIN_%' AND key NOT LIKE '__meta__:%' LIMIT 1`
97
+ WHERE key NOT LIKE 'UNLOGIN_%' LIMIT 1`
90
98
  );
91
99
  if (rows.length === 0) return false;
92
100
  }
93
101
  return true;
94
102
  }
103
+ async getMeta(key) {
104
+ const { rows } = await execute(
105
+ `SELECT value FROM ${META_TABLE} WHERE key = ?`,
106
+ [key]
107
+ );
108
+ if (!rows.length) return null;
109
+ return rows[0].value;
110
+ }
111
+ async setMeta(key, value) {
112
+ await execute(
113
+ `INSERT OR REPLACE INTO ${META_TABLE} (key, value) VALUES (?, ?)`,
114
+ [key, value]
115
+ );
116
+ }
95
117
  };
96
118
  function rowToRecord(row) {
97
119
  return {
@@ -121,7 +143,7 @@ if (!_i18next2.default.isInitialized) {
121
143
  }
122
144
  });
123
145
  }
124
- var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkT7476FJ4cjs.createI18nManager.call(void 0, {
146
+ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } = _chunkUMU62XLBcjs.createI18nManager.call(void 0, {
125
147
  storage: new SQLiteAdapter(),
126
148
  // Hermes Worker(RN 0.71+),API 与 Web Worker 一致
127
149
  createWorker: () => new (0, _chunkAJJKJPNBcjs.WebWorkerAdapter)(
@@ -138,4 +160,4 @@ var { initI18n, closeSSE, ensureModules, getResource, getAllRecordsByModule } =
138
160
 
139
161
 
140
162
 
141
- exports.I18N_RESOURCES_UPDATED_EVENT = _chunkT7476FJ4cjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkT7476FJ4cjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
163
+ exports.I18N_RESOURCES_UPDATED_EVENT = _chunkUMU62XLBcjs.I18N_RESOURCES_UPDATED_EVENT; exports.closeSSE = closeSSE; exports.emitI18nResourcesUpdated = _chunkUMU62XLBcjs.emitI18nResourcesUpdated; exports.ensureModules = ensureModules; exports.getAllRecordsByModule = getAllRecordsByModule; exports.getResource = getResource; exports.initI18n = initI18n; exports.useDict = _chunkAJJKJPNBcjs.useDict; exports.useTranslation = _chunkAJJKJPNBcjs.useTranslation;
@@ -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, 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, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, 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
 
@@ -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, 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, P as PullLangBlock, R as ResourceRecord, S as SSEMessage, d as StandardPullParams, f as StoreConfig, 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
 
@@ -7,7 +7,8 @@ import {
7
7
  I18N_RESOURCES_UPDATED_EVENT,
8
8
  createI18nManager,
9
9
  emitI18nResourcesUpdated
10
- } from "../chunk-LZQP6OHB.js";
10
+ } from "../chunk-FFIQQFC4.js";
11
+ import "../chunk-NEXKR7GY.js";
11
12
 
12
13
  // src/native/index.ts
13
14
  import i18n from "i18next";
@@ -15,6 +16,7 @@ import { initReactI18next } from "react-i18next";
15
16
 
16
17
  // src/storage/sqlite.ts
17
18
  var DB_NAME = "i18n_cache";
19
+ var META_TABLE = "i18n_meta";
18
20
  function resourceTable(name) {
19
21
  return `i18n_resources_${name}`;
20
22
  }
@@ -31,6 +33,12 @@ async function execute(sql, params = []) {
31
33
  }
32
34
  var SQLiteAdapter = class {
33
35
  async ensureStores(stores, _schemaVersion) {
36
+ await execute(`
37
+ CREATE TABLE IF NOT EXISTS ${META_TABLE} (
38
+ key TEXT PRIMARY KEY,
39
+ value TEXT NOT NULL
40
+ )
41
+ `);
34
42
  for (const store of stores) {
35
43
  const table = resourceTable(store.name);
36
44
  await execute(`
@@ -86,12 +94,26 @@ var SQLiteAdapter = class {
86
94
  for (const store of stores) {
87
95
  const { rows } = await execute(
88
96
  `SELECT key FROM ${resourceTable(store.name)}
89
- WHERE key NOT LIKE 'UNLOGIN_%' AND key NOT LIKE '__meta__:%' LIMIT 1`
97
+ WHERE key NOT LIKE 'UNLOGIN_%' LIMIT 1`
90
98
  );
91
99
  if (rows.length === 0) return false;
92
100
  }
93
101
  return true;
94
102
  }
103
+ async getMeta(key) {
104
+ const { rows } = await execute(
105
+ `SELECT value FROM ${META_TABLE} WHERE key = ?`,
106
+ [key]
107
+ );
108
+ if (!rows.length) return null;
109
+ return rows[0].value;
110
+ }
111
+ async setMeta(key, value) {
112
+ await execute(
113
+ `INSERT OR REPLACE INTO ${META_TABLE} (key, value) VALUES (?, ?)`,
114
+ [key, value]
115
+ );
116
+ }
95
117
  };
96
118
  function rowToRecord(row) {
97
119
  return {
@@ -1,10 +1,47 @@
1
- "use strict"; function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/workers/preload-worker.ts
1
+ "use strict"; 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
+ var _chunkJOUVTRSAcjs = require('../chunk-JOUVTRSA.cjs');
7
+
8
+ // src/workers/preload-worker.ts
9
+ var DB_NAME = "i18n_cache";
10
+ var pendingParsedData = /* @__PURE__ */ new Map();
11
+ var dbInstance = null;
12
+ function openDB() {
13
+ if (dbInstance) return Promise.resolve(dbInstance);
14
+ return new Promise((resolve, reject) => {
15
+ const req = indexedDB.open(DB_NAME);
16
+ req.onsuccess = () => {
17
+ dbInstance = req.result;
18
+ resolve(req.result);
19
+ };
20
+ req.onerror = () => reject(req.error);
21
+ });
22
+ }
23
+ function idbGet(db, storeName, key) {
24
+ return new Promise((resolve, reject) => {
25
+ const tx = db.transaction(`i18n_resources_${storeName}`, "readonly");
26
+ const req = tx.objectStore(`i18n_resources_${storeName}`).get(key);
27
+ req.onsuccess = () => resolve(req.result);
28
+ req.onerror = () => reject(req.error);
29
+ });
30
+ }
31
+ function idbPut(db, storeName, record) {
32
+ return new Promise((resolve, reject) => {
33
+ const tx = db.transaction(`i18n_resources_${storeName}`, "readwrite");
34
+ const req = tx.objectStore(`i18n_resources_${storeName}`).put(record);
35
+ req.onsuccess = () => resolve();
36
+ req.onerror = () => reject(req.error);
37
+ });
38
+ }
2
39
  function toQueryString(params) {
3
40
  return new URLSearchParams(
4
41
  Object.entries(params).filter(([, v]) => v != null).map(([k, v]) => [k, String(v)])
5
42
  ).toString();
6
43
  }
7
- async function processTask(task, payload) {
44
+ async function fetchRaw(task, payload) {
8
45
  const { baseURL, headers, pullPath, pullMethod } = payload;
9
46
  const params = _nullishCoalesce(task.params, () => ( {}));
10
47
  if (!task.params) {
@@ -26,12 +63,60 @@ async function processTask(task, payload) {
26
63
  res = await fetch(qs ? `${url}?${qs}` : url, { headers });
27
64
  }
28
65
  if (!res.ok) throw new Error(`[i18n worker] fetch failed: ${res.status}`);
29
- const raw = await res.json();
66
+ return res.json();
67
+ }
68
+ async function writeBlocksToIDB(blocks, storeConfig, storeIndex) {
69
+ const db = await openDB();
70
+ for (const block of blocks) {
71
+ for (const mod of _nullishCoalesce(block.modules, () => ( []))) {
72
+ const key = _chunkJOUVTRSAcjs.buildKey.call(void 0, mod.moduleCode, block.langCode, storeConfig);
73
+ const existing = await idbGet(db, storeConfig.name, key);
74
+ if (existing && mod.version <= (_nullishCoalesce(existing.version, () => ( 0)))) continue;
75
+ const flat = _chunkJOUVTRSAcjs.parseI18nValues.call(void 0, mod.i18nValues);
76
+ const resources = storeIndex === 0 ? _chunkJOUVTRSAcjs.deepMerge.call(void 0, _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _ => _.resources]), () => ( {})), _chunkJOUVTRSAcjs.flatToNested.call(void 0, flat)) : { ..._nullishCoalesce(_optionalChain([existing, 'optionalAccess', _2 => _2.resources]), () => ( {})), ...flat };
77
+ await idbPut(db, storeConfig.name, {
78
+ key,
79
+ moduleCode: mod.moduleCode,
80
+ langCode: block.langCode,
81
+ version: mod.version,
82
+ resources
83
+ });
84
+ self.postMessage({
85
+ type: "moduleLoaded",
86
+ storeName: storeConfig.name,
87
+ moduleCode: mod.moduleCode,
88
+ langCode: block.langCode,
89
+ version: mod.version
90
+ });
91
+ }
92
+ }
93
+ }
94
+ async function processTask(task, payload) {
95
+ const raw = await fetchRaw(task, payload);
30
96
  self.postMessage({ type: "rawData", task, raw });
97
+ const blocks = await new Promise((resolve) => {
98
+ pendingParsedData.set(task.taskId, resolve);
99
+ });
100
+ if (blocks.length === 0) return;
101
+ const storeConfigs = _nullishCoalesce(payload.storeConfigs, () => ( []));
102
+ const storeConfig = storeConfigs.find((s) => s.name === task.storeName);
103
+ if (!storeConfig) return;
104
+ const storeIndex = storeConfigs.indexOf(storeConfig);
105
+ await writeBlocksToIDB(blocks, storeConfig, storeIndex);
31
106
  }
32
107
  self.onmessage = async (event) => {
33
- if (event.data.type !== "start") return;
34
- const { payload } = event.data;
108
+ const data = event.data;
109
+ if (data.type === "parsedData") {
110
+ const { taskId, blocks } = data;
111
+ const resolve = pendingParsedData.get(taskId);
112
+ if (resolve) {
113
+ pendingParsedData.delete(taskId);
114
+ resolve(blocks);
115
+ }
116
+ return;
117
+ }
118
+ if (data.type !== "start") return;
119
+ const payload = data.payload;
35
120
  for (const task of payload.tasks) {
36
121
  try {
37
122
  await processTask(task, payload);