wuchale 0.23.4 → 0.24.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/adapter-utils/mixed-visitor.d.ts +21 -14
- package/dist/adapter-utils/mixed-visitor.js +110 -101
- package/dist/adapter-vanilla/index.js +8 -6
- package/dist/adapter-vanilla/inertvisitors.d.ts +31 -0
- package/dist/adapter-vanilla/inertvisitors.js +86 -0
- package/dist/adapter-vanilla/transformer.d.ts +67 -95
- package/dist/adapter-vanilla/transformer.js +288 -241
- package/dist/adapters.d.ts +16 -12
- package/dist/adapters.js +33 -13
- package/dist/ai/gemini.js +1 -1
- package/dist/ai/index.js +3 -1
- package/dist/bundlers/vite.d.ts +1 -1
- package/dist/bundlers/vite.js +3 -3
- package/dist/cli/check.js +1 -1
- package/dist/cli/index.js +12 -5
- package/dist/cli/status.js +1 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.js +2 -2
- package/dist/handler/files.d.ts +11 -13
- package/dist/handler/files.js +37 -44
- package/dist/handler/index.d.ts +7 -4
- package/dist/handler/index.js +85 -62
- package/dist/handler/state.d.ts +10 -11
- package/dist/handler/state.js +40 -28
- package/dist/handler/url.d.ts +10 -13
- package/dist/handler/url.js +51 -80
- package/dist/hub.d.ts +1 -1
- package/dist/hub.js +16 -14
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/load-utils/index.d.ts +6 -8
- package/dist/load-utils/index.js +11 -11
- package/dist/load-utils/pure.d.ts +2 -2
- package/dist/load-utils/server.d.ts +3 -3
- package/dist/load-utils/server.js +4 -7
- package/dist/pofile.d.ts +5 -5
- package/dist/pofile.js +23 -35
- package/dist/storage.d.ts +6 -3
- package/dist/storage.js +98 -0
- package/dist/url.d.ts +12 -10
- package/dist/url.js +206 -31
- package/package.json +4 -5
- package/src/adapter-vanilla/loaders/bundle.js +1 -1
- package/src/adapter-vanilla/loaders/server.js +3 -3
- package/src/adapter-vanilla/loaders/vite.js +2 -2
- package/src/adapter-vanilla/loaders/vite.ssr.js +3 -3
package/dist/handler/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
1
2
|
import { resolve } from 'node:path';
|
|
2
3
|
import { isDeepStrictEqual } from 'node:util';
|
|
3
4
|
import pm, {} from 'picomatch';
|
|
@@ -6,7 +7,7 @@ import { getKey } from '../adapters.js';
|
|
|
6
7
|
import AIQueue from '../ai/index.js';
|
|
7
8
|
import { compileTranslation } from '../compile.js';
|
|
8
9
|
import { itemIsUrl, newItem } from '../storage.js';
|
|
9
|
-
import { Files, globConfToArgs, normalizeSep, objKeyLocale, } from './files.js';
|
|
10
|
+
import { defaultLoadID, Files, globConfToArgs, normalizeSep, objKeyLocale, } from './files.js';
|
|
10
11
|
import { State } from './state.js';
|
|
11
12
|
import { URLHandler } from './url.js';
|
|
12
13
|
const loaderImportGetRuntime = 'getRuntime';
|
|
@@ -15,19 +16,45 @@ const getFuncPlainDefault = '_w_load_';
|
|
|
15
16
|
const urlLocalizeUdfName = 'localize';
|
|
16
17
|
const getFuncReactiveDefault = `${getFuncPlainDefault}rx_`;
|
|
17
18
|
const bundleCatalogsVarName = '_w_catalogs_';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!adapter.granularLoad) {
|
|
22
|
-
return [[key], [ownerKey]];
|
|
19
|
+
export function getLoadIDs(adapter, granularStates, sourceLocale) {
|
|
20
|
+
if (!adapter.loading.granular) {
|
|
21
|
+
return [defaultLoadID];
|
|
23
22
|
}
|
|
23
|
+
const loadIDs = [];
|
|
24
24
|
for (const state of granularStates) {
|
|
25
25
|
// only the ones with ready messages
|
|
26
26
|
if (state.compiled.get(sourceLocale).items.length) {
|
|
27
27
|
loadIDs.push(state.id);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
return
|
|
30
|
+
return loadIDs;
|
|
31
|
+
}
|
|
32
|
+
export const newItemsAllowed = (mode, devMode) => mode !== 'dev' || devMode === 'add' || devMode === 'refs' || devMode === 'clean';
|
|
33
|
+
function getFallback(fbConf, loc, sourceLocale, locales, chain) {
|
|
34
|
+
let fallback = fbConf[loc];
|
|
35
|
+
if (!fallback) {
|
|
36
|
+
if (loc.includes('-')) {
|
|
37
|
+
fallback = new Intl.Locale(loc).language;
|
|
38
|
+
}
|
|
39
|
+
if (!fallback || !locales.includes(fallback)) {
|
|
40
|
+
chain.push(sourceLocale);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
chain.push(fallback);
|
|
45
|
+
getFallback(fbConf, fallback, sourceLocale, locales, chain);
|
|
46
|
+
}
|
|
47
|
+
export function getFallbackChains(fallbackConf, locales, sourceLocale) {
|
|
48
|
+
const chains = new Map([[sourceLocale, [sourceLocale]]]);
|
|
49
|
+
for (const loc of locales) {
|
|
50
|
+
if (loc === sourceLocale) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const chain = [loc];
|
|
54
|
+
chains.set(loc, chain);
|
|
55
|
+
getFallback(fallbackConf, loc, sourceLocale, locales, chain);
|
|
56
|
+
}
|
|
57
|
+
return chains;
|
|
31
58
|
}
|
|
32
59
|
export class AdapterHandler {
|
|
33
60
|
key;
|
|
@@ -41,15 +68,19 @@ export class AdapterHandler {
|
|
|
41
68
|
url;
|
|
42
69
|
aiQueue;
|
|
43
70
|
onBeforeSave;
|
|
71
|
+
#fallbackChains;
|
|
72
|
+
#newKeys = new Set(); // keys added during dev
|
|
44
73
|
constructor(opts) {
|
|
45
74
|
this.#opts = opts;
|
|
46
75
|
this.key = opts.key;
|
|
47
76
|
this.adapter = opts.adapter;
|
|
48
77
|
this.granularState = opts.granularState;
|
|
49
78
|
this.sharedState = opts.sharedState;
|
|
50
|
-
|
|
79
|
+
const [patterns, ignore] = globConfToArgs(opts.adapter.files, opts.config.localesDir);
|
|
80
|
+
this.fileMatches = pm(patterns, { ignore });
|
|
51
81
|
this.sourceLocale = opts.sourceLocale;
|
|
52
82
|
this.url = new URLHandler(opts.config.locales, this.sourceLocale, opts.adapter.url);
|
|
83
|
+
this.#fallbackChains = getFallbackChains(opts.config.fallback, opts.config.locales, this.sourceLocale);
|
|
53
84
|
this.files = opts.files;
|
|
54
85
|
if (opts.config.ai) {
|
|
55
86
|
this.aiQueue = new AIQueue(opts.sourceLocale, opts.config.ai, opts.mode === 'cli' ? this.saveStorage : this.saveStorageCompile, opts.log);
|
|
@@ -65,16 +96,16 @@ export class AdapterHandler {
|
|
|
65
96
|
fs,
|
|
66
97
|
root,
|
|
67
98
|
});
|
|
68
|
-
const writeProxies =
|
|
69
|
-
const granularState = new State(writeProxies, adapter.
|
|
99
|
+
const writeProxies = groupPatts => files.writeProxies(config.locales, groupPatts);
|
|
100
|
+
const granularState = new State(writeProxies, adapter.loading.group);
|
|
70
101
|
const handler = new AdapterHandler({ ...opts, granularState, files });
|
|
71
102
|
await handler.loadStorage();
|
|
72
|
-
if (await handler.url.initPatterns(key, sharedState.catalog, handler.aiQueue)) {
|
|
103
|
+
if (await handler.url.initPatterns(key, sharedState.catalog, handler.#fallbackChains, handler.aiQueue)) {
|
|
73
104
|
await handler.saveStorage();
|
|
74
105
|
}
|
|
75
106
|
await handler.compile();
|
|
76
|
-
await writeProxies(granularState.
|
|
77
|
-
await files.writeUrlFiles(handler.url.buildManifest(
|
|
107
|
+
await writeProxies(granularState.groupPatterns);
|
|
108
|
+
await files.writeUrlFiles(handler.url.buildManifest(), config.locales[0]);
|
|
78
109
|
return handler;
|
|
79
110
|
};
|
|
80
111
|
loadStorage = async () => {
|
|
@@ -84,7 +115,7 @@ export class AdapterHandler {
|
|
|
84
115
|
};
|
|
85
116
|
saveStorage = async () => {
|
|
86
117
|
this.onBeforeSave?.();
|
|
87
|
-
await this.sharedState.save();
|
|
118
|
+
await this.sharedState.save(this.#opts.mode === 'dev' && this.#opts.devMode === 'clean');
|
|
88
119
|
};
|
|
89
120
|
compile = async (hmrVersion = -1) => {
|
|
90
121
|
// for proper fallback
|
|
@@ -116,10 +147,10 @@ export class AdapterHandler {
|
|
|
116
147
|
return manifest;
|
|
117
148
|
};
|
|
118
149
|
#writeManifests = async () => {
|
|
119
|
-
const promises = [this.files.writeManifest(this.#buildManifest(this.sharedState.indexTracker.
|
|
120
|
-
if (this.adapter.
|
|
150
|
+
const promises = [this.files.writeManifest(this.#buildManifest(this.sharedState.indexTracker.getAll()), null)];
|
|
151
|
+
if (this.adapter.loading.granular) {
|
|
121
152
|
for (const state of this.granularState.byID.values()) {
|
|
122
|
-
promises.push(this.files.writeManifest(this.#buildManifest(state.indexTracker.
|
|
153
|
+
promises.push(this.files.writeManifest(this.#buildManifest(state.indexTracker.getAll()), state.id));
|
|
123
154
|
}
|
|
124
155
|
}
|
|
125
156
|
await Promise.all(promises);
|
|
@@ -135,7 +166,7 @@ export class AdapterHandler {
|
|
|
135
166
|
const promises = [
|
|
136
167
|
this.files.writeCatalogModule(compiledData.items, compiledData.hasPlurals ? pluralRule : null, loc, hmrVersionMode, null),
|
|
137
168
|
];
|
|
138
|
-
if (this.adapter.
|
|
169
|
+
if (this.adapter.loading.granular) {
|
|
139
170
|
for (const state of this.granularState.byID.values()) {
|
|
140
171
|
compiledData = state.compiled?.get(loc) || {
|
|
141
172
|
hasPlurals: false,
|
|
@@ -146,25 +177,12 @@ export class AdapterHandler {
|
|
|
146
177
|
}
|
|
147
178
|
await Promise.all(promises);
|
|
148
179
|
};
|
|
149
|
-
getCompiledFallback(index,
|
|
150
|
-
for (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (fallbackLoc == null) {
|
|
154
|
-
if (loc.includes('-')) {
|
|
155
|
-
fallbackLoc = new Intl.Locale(loc).language;
|
|
156
|
-
}
|
|
157
|
-
if (fallbackLoc == null || !this.#opts.config.locales.includes(fallbackLoc)) {
|
|
158
|
-
fallbackLoc = this.sourceLocale;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
const catalog = this.sharedState.compiled.get(fallbackLoc).items;
|
|
162
|
-
const compiled = catalog[index];
|
|
163
|
-
if (compiled || fallbackLoc === this.sourceLocale) {
|
|
164
|
-
// last try
|
|
180
|
+
getCompiledFallback(index, locale) {
|
|
181
|
+
for (const loc of this.#fallbackChains.get(locale) ?? [locale, this.sourceLocale]) {
|
|
182
|
+
const compiled = this.sharedState.compiled.get(loc).items[index];
|
|
183
|
+
if (compiled || loc === this.sourceLocale) {
|
|
165
184
|
return compiled || '';
|
|
166
185
|
}
|
|
167
|
-
loc = fallbackLoc;
|
|
168
186
|
}
|
|
169
187
|
return '';
|
|
170
188
|
}
|
|
@@ -207,16 +225,16 @@ export class AdapterHandler {
|
|
|
207
225
|
else {
|
|
208
226
|
let toCompile = transl[0];
|
|
209
227
|
if (itemIsUrl(item)) {
|
|
210
|
-
toCompile = this.url.matchToCompile(key,
|
|
228
|
+
toCompile = this.url.matchToCompile(key, loc);
|
|
211
229
|
}
|
|
212
230
|
compiled = compileTranslation(toCompile, fallback);
|
|
213
231
|
}
|
|
214
232
|
sharedCompiledLoc.items[index] = compiled;
|
|
215
|
-
if (!this.adapter.
|
|
233
|
+
if (!this.adapter.loading.granular) {
|
|
216
234
|
continue;
|
|
217
235
|
}
|
|
218
236
|
for (const ref of item.references) {
|
|
219
|
-
const state = await this.granularState.byFileCreate(ref.file, this.#opts.config.locales);
|
|
237
|
+
const state = await this.granularState.byFileCreate(ref.file, this.#opts.config.locales, newItemsAllowed(this.#opts.mode, this.#opts.devMode));
|
|
220
238
|
const compiledLoc = state.compiled.get(loc);
|
|
221
239
|
compiledLoc.hasPlurals = sharedCompiledLoc.hasPlurals;
|
|
222
240
|
compiledLoc.items[state.indexTracker.get(key)] = compiled;
|
|
@@ -261,24 +279,20 @@ export class AdapterHandler {
|
|
|
261
279
|
getRuntimeReactive += 'hmr_';
|
|
262
280
|
head.push(this.#hmrUpdateFunc(getRuntimeVars.plain, getRuntimePlain), this.#hmrUpdateFunc(getRuntimeVars.reactive, getRuntimeReactive));
|
|
263
281
|
}
|
|
264
|
-
|
|
265
|
-
if (this.adapter.outDir) {
|
|
266
|
-
loaderRelTo = resolve(`${this.adapter.outDir}/${filename}`);
|
|
267
|
-
}
|
|
268
|
-
const loaderPath = this.files.getImportLoaderPath(forServer, loaderRelTo);
|
|
282
|
+
const loaderPath = this.files.getImportLoaderPath(forServer, filename);
|
|
269
283
|
const importsFuncs = [
|
|
270
284
|
`${loaderImportGetRuntime} as ${getRuntimePlain}`,
|
|
271
285
|
`${loaderImportGetRuntimeRx} as ${getRuntimeReactive}`,
|
|
272
286
|
];
|
|
273
287
|
head = [`import {${importsFuncs.join(', ')}} from "${loaderPath}"`, ...head];
|
|
274
|
-
if (!this.adapter.
|
|
288
|
+
if (!this.adapter.loading.direct) {
|
|
275
289
|
return head.join('\n');
|
|
276
290
|
}
|
|
277
291
|
const imports = [];
|
|
278
292
|
const objElms = [];
|
|
279
293
|
for (const [i, loc] of this.#opts.config.locales.entries()) {
|
|
280
294
|
const locKW = `_w_c_${i}_`;
|
|
281
|
-
const importFrom = this.files.getImportPath(this.files.getCompiledFilePath(loc, loadID),
|
|
295
|
+
const importFrom = this.files.getImportPath(this.files.getCompiledFilePath(loc, loadID), filename);
|
|
282
296
|
imports.push(`import * as ${locKW} from '${importFrom}'`);
|
|
283
297
|
objElms.push(`${objKeyLocale(loc)}: ${locKW}`);
|
|
284
298
|
}
|
|
@@ -286,15 +300,17 @@ export class AdapterHandler {
|
|
|
286
300
|
};
|
|
287
301
|
#prepareRuntimeExpr = (loadID) => {
|
|
288
302
|
const importLoaderVars = this.#getRuntimeVars();
|
|
289
|
-
if (this.adapter.
|
|
303
|
+
if (this.adapter.loading.direct) {
|
|
290
304
|
return {
|
|
291
305
|
plain: `${importLoaderVars.plain}(${bundleCatalogsVarName})`,
|
|
292
306
|
reactive: `${importLoaderVars.reactive}(${bundleCatalogsVarName})`,
|
|
293
307
|
};
|
|
294
308
|
}
|
|
309
|
+
// default is always 0 unless loading.granular is true
|
|
310
|
+
const loadIDParam = loadID === 0 ? '' : loadID;
|
|
295
311
|
return {
|
|
296
|
-
plain: `${importLoaderVars.plain}(
|
|
297
|
-
reactive: `${importLoaderVars.reactive}(
|
|
312
|
+
plain: `${importLoaderVars.plain}(${loadIDParam})`,
|
|
313
|
+
reactive: `${importLoaderVars.reactive}(${loadIDParam})`,
|
|
298
314
|
};
|
|
299
315
|
};
|
|
300
316
|
popTrackedRefs = (filename) => {
|
|
@@ -367,6 +383,7 @@ export class AdapterHandler {
|
|
|
367
383
|
let compileUpdated = false;
|
|
368
384
|
const hmrKeys = [];
|
|
369
385
|
const toTranslate = [];
|
|
386
|
+
const modifyExistingRefs = this.#opts.mode !== 'dev' || this.#opts.devMode === 'refs' || this.#opts.devMode === 'clean';
|
|
370
387
|
for (const msgInfo of msgs) {
|
|
371
388
|
let key = getKey(msgInfo.msgStr, msgInfo.context);
|
|
372
389
|
hmrKeys.push(key);
|
|
@@ -377,16 +394,18 @@ export class AdapterHandler {
|
|
|
377
394
|
err.id = filename;
|
|
378
395
|
throw err;
|
|
379
396
|
}
|
|
380
|
-
key = this.url.
|
|
397
|
+
key = getKey([this.url.patterns[matched[0]]]);
|
|
381
398
|
}
|
|
382
399
|
let item = this.sharedState.catalog.get(key);
|
|
383
400
|
if (!item) {
|
|
384
401
|
item = newItem({ id: msgInfo.msgStr }, this.#opts.config.locales);
|
|
385
402
|
this.sharedState.catalog.set(key, item);
|
|
403
|
+
this.#newKeys.add(key);
|
|
386
404
|
storageUpdated = true;
|
|
387
405
|
compileUpdated = true;
|
|
388
406
|
}
|
|
389
|
-
|
|
407
|
+
const modifyRefs = modifyExistingRefs || (this.#opts.devMode === 'add' && this.#newKeys.has(key));
|
|
408
|
+
if (modifyRefs && this.updateRef(item, key, filename, msgInfo, previousReferences)) {
|
|
390
409
|
storageUpdated = true;
|
|
391
410
|
if (msgInfo.type === 'url') {
|
|
392
411
|
compileUpdated = true;
|
|
@@ -416,16 +435,18 @@ export class AdapterHandler {
|
|
|
416
435
|
this.aiQueue.add(toTranslate);
|
|
417
436
|
await this.aiQueue.running;
|
|
418
437
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
438
|
+
if (modifyExistingRefs) {
|
|
439
|
+
const { cleaned, cleanedUrls } = this.cleanTrackedRefs(previousReferences);
|
|
440
|
+
if (cleaned) {
|
|
441
|
+
storageUpdated = true;
|
|
442
|
+
}
|
|
443
|
+
if (cleanedUrls) {
|
|
444
|
+
compileUpdated = true;
|
|
445
|
+
}
|
|
425
446
|
}
|
|
447
|
+
// cli saves and compiles at the end
|
|
426
448
|
if (storageUpdated && this.#opts.mode !== 'cli') {
|
|
427
|
-
|
|
428
|
-
await this.saveStorage();
|
|
449
|
+
this.#opts.devMode && (await this.saveStorage());
|
|
429
450
|
if (compileUpdated) {
|
|
430
451
|
await this.compile();
|
|
431
452
|
}
|
|
@@ -435,10 +456,10 @@ export class AdapterHandler {
|
|
|
435
456
|
transform = async (content, filename, hmrVersion = -1, forServer = false) => {
|
|
436
457
|
filename = normalizeSep(filename);
|
|
437
458
|
let indexTracker = this.sharedState.indexTracker;
|
|
438
|
-
let loadID =
|
|
459
|
+
let loadID = defaultLoadID;
|
|
439
460
|
let compiled = this.sharedState.compiled;
|
|
440
|
-
if (this.adapter.
|
|
441
|
-
const state = await this.granularState.byFileCreate(filename, this.#opts.config.locales);
|
|
461
|
+
if (this.adapter.loading.granular) {
|
|
462
|
+
const state = await this.granularState.byFileCreate(filename, this.#opts.config.locales, newItemsAllowed(this.#opts.mode, this.#opts.devMode));
|
|
442
463
|
indexTracker = state.indexTracker;
|
|
443
464
|
loadID = state.id;
|
|
444
465
|
compiled = state.compiled;
|
|
@@ -481,7 +502,9 @@ export class AdapterHandler {
|
|
|
481
502
|
if (msgs.length) {
|
|
482
503
|
output = result.output(this.#prepareHeader(filename, loadID, hmrData, msgs.some(m => m.type === 'url'), forServer));
|
|
483
504
|
}
|
|
484
|
-
|
|
505
|
+
if (this.#opts.modifyInplace && output.code) {
|
|
506
|
+
await writeFile(filename, output.code);
|
|
507
|
+
}
|
|
485
508
|
return [output, updated];
|
|
486
509
|
};
|
|
487
510
|
}
|
package/dist/handler/state.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IndexTracker } from '../adapters.js';
|
|
1
|
+
import { IndexTracker, type LoadGroupPatt } from '../adapters.js';
|
|
2
2
|
import type { CompiledElement } from '../compile.js';
|
|
3
3
|
import { type Catalog, type CatalogStorage, type PluralRules } from '../storage.js';
|
|
4
4
|
export type Compiled = {
|
|
@@ -15,21 +15,20 @@ export declare class SharedState {
|
|
|
15
15
|
storage: CatalogStorage;
|
|
16
16
|
catalog: Catalog;
|
|
17
17
|
pluralRules: PluralRules;
|
|
18
|
-
constructor(storage: CatalogStorage, ownerKey: string, sourceLocale: string);
|
|
18
|
+
constructor(storage: CatalogStorage, ownerKey: string, sourceLocale: string, allowNewItems: boolean);
|
|
19
19
|
load(locales: string[]): Promise<void>;
|
|
20
|
-
save(): Promise<void>;
|
|
20
|
+
save(onlyReferenced: boolean): Promise<void>;
|
|
21
21
|
}
|
|
22
22
|
export type GranularState = {
|
|
23
|
-
id:
|
|
23
|
+
id: number;
|
|
24
24
|
compiled: CompiledCatalogs;
|
|
25
25
|
indexTracker: IndexTracker;
|
|
26
26
|
};
|
|
27
|
-
export type WriteProxies = (
|
|
27
|
+
export type WriteProxies = (groupPatterns: LoadGroupPatt[]) => Promise<void>;
|
|
28
28
|
export declare class State {
|
|
29
|
-
|
|
30
|
-
byID: Map<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
byFileCreate(filename: string, locales: string[]): Promise<GranularState>;
|
|
29
|
+
#private;
|
|
30
|
+
readonly byID: Map<number, GranularState>;
|
|
31
|
+
readonly groupPatterns: LoadGroupPatt[];
|
|
32
|
+
constructor(writeProxies: WriteProxies, groupPatterns: LoadGroupPatt[]);
|
|
33
|
+
byFileCreate(filename: string, locales: string[], allowNewItems: boolean): Promise<GranularState>;
|
|
35
34
|
}
|
package/dist/handler/state.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import pm from 'picomatch';
|
|
1
2
|
import { getKey, IndexTracker } from '../adapters.js';
|
|
2
|
-
import { defaultPluralRule, fillTranslations } from '../storage.js';
|
|
3
|
+
import { defaultPluralRule, fillTranslations, itemIsObsolete, } from '../storage.js';
|
|
3
4
|
/**
|
|
4
5
|
* plural rule expressions should be
|
|
5
6
|
* - made of ternary and binary expressions
|
|
@@ -25,15 +26,16 @@ export class SharedState {
|
|
|
25
26
|
ownerKey;
|
|
26
27
|
sourceLocale;
|
|
27
28
|
compiled = new Map();
|
|
28
|
-
indexTracker
|
|
29
|
+
indexTracker;
|
|
29
30
|
// storage
|
|
30
31
|
storage;
|
|
31
32
|
catalog = new Map();
|
|
32
33
|
pluralRules = new Map();
|
|
33
|
-
constructor(storage, ownerKey, sourceLocale) {
|
|
34
|
+
constructor(storage, ownerKey, sourceLocale, allowNewItems) {
|
|
34
35
|
this.ownerKey = ownerKey;
|
|
35
36
|
this.sourceLocale = sourceLocale;
|
|
36
37
|
this.storage = storage;
|
|
38
|
+
this.indexTracker = new IndexTracker(allowNewItems);
|
|
37
39
|
}
|
|
38
40
|
async load(locales) {
|
|
39
41
|
const loaded = await this.storage.load();
|
|
@@ -54,50 +56,60 @@ export class SharedState {
|
|
|
54
56
|
this.catalog.set(getKey(id, item.context), item);
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
|
-
async save() {
|
|
59
|
+
async save(onlyReferenced) {
|
|
60
|
+
const items = Array.from(this.catalog.values());
|
|
58
61
|
await this.storage.save({
|
|
59
62
|
pluralRules: this.pluralRules,
|
|
60
|
-
|
|
61
|
-
items: Array.from(this.catalog.values()),
|
|
63
|
+
items: onlyReferenced ? items.filter(i => !itemIsObsolete(i)) : items,
|
|
62
64
|
});
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
export class State {
|
|
66
|
-
byFile = new Map();
|
|
68
|
+
#byFile = new Map();
|
|
67
69
|
byID = new Map();
|
|
68
|
-
writeProxies;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this
|
|
70
|
+
#writeProxies;
|
|
71
|
+
groupPatterns = [];
|
|
72
|
+
#groupMatches = [];
|
|
73
|
+
constructor(writeProxies, groupPatterns) {
|
|
74
|
+
this.#writeProxies = writeProxies;
|
|
75
|
+
this.groupPatterns = groupPatterns;
|
|
76
|
+
this.#groupMatches = groupPatterns.map(p => pm(p));
|
|
73
77
|
}
|
|
74
|
-
|
|
75
|
-
let
|
|
78
|
+
#getLoadID(filename) {
|
|
79
|
+
let id = -1;
|
|
80
|
+
for (const [i, match] of this.#groupMatches.entries()) {
|
|
81
|
+
if (!match(filename)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
id = i;
|
|
85
|
+
}
|
|
86
|
+
if (id === -1) {
|
|
87
|
+
id = this.groupPatterns.length;
|
|
88
|
+
this.groupPatterns.push(filename);
|
|
89
|
+
this.#groupMatches.push(f => f === filename);
|
|
90
|
+
}
|
|
91
|
+
return id + 1; // not to start from 0 which is reserved for the shared
|
|
92
|
+
}
|
|
93
|
+
async byFileCreate(filename, locales, allowNewItems) {
|
|
94
|
+
let state = this.#byFile.get(filename);
|
|
76
95
|
if (state != null) {
|
|
77
96
|
return state;
|
|
78
97
|
}
|
|
79
|
-
const id = this
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
state = stateG;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
const compiledLoaded = new Map();
|
|
98
|
+
const id = this.#getLoadID(filename);
|
|
99
|
+
state = this.byID.get(id);
|
|
100
|
+
if (!state) {
|
|
86
101
|
state = {
|
|
87
102
|
id,
|
|
88
103
|
compiled: new Map(),
|
|
89
|
-
indexTracker: new IndexTracker(),
|
|
104
|
+
indexTracker: new IndexTracker(allowNewItems),
|
|
90
105
|
};
|
|
91
106
|
for (const loc of locales) {
|
|
92
|
-
state.compiled.set(loc,
|
|
93
|
-
hasPlurals: false,
|
|
94
|
-
items: [],
|
|
95
|
-
});
|
|
107
|
+
state.compiled.set(loc, { hasPlurals: false, items: [] });
|
|
96
108
|
}
|
|
97
109
|
this.byID.set(id, state);
|
|
98
|
-
await this
|
|
110
|
+
await this.#writeProxies(this.groupPatterns);
|
|
99
111
|
}
|
|
100
|
-
this
|
|
112
|
+
this.#byFile.set(filename, state);
|
|
101
113
|
return state;
|
|
102
114
|
}
|
|
103
115
|
}
|
package/dist/handler/url.d.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type URLConf } from '../adapters.js';
|
|
1
|
+
import { type URLConf, type UrlMatcher } from '../adapters.js';
|
|
3
2
|
import type AIQueue from '../ai/index.js';
|
|
4
3
|
import { type Catalog } from '../storage.js';
|
|
5
|
-
import type
|
|
6
|
-
export declare function patternFromTranslate(patternTranslated: string, keys: Token[]): string;
|
|
7
|
-
export declare function patternToTranslate(pattern: string): string;
|
|
4
|
+
import { type Pattern, type URLManifest } from '../url.js';
|
|
8
5
|
export declare class URLHandler {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
readonly locales: string[];
|
|
7
|
+
readonly sourceLocale: string;
|
|
8
|
+
readonly patterns: string[];
|
|
9
|
+
readonly compiledPatterns: Map<string, Pattern>[];
|
|
13
10
|
constructor(locales: string[], sourceLocale: string, urlConf?: URLConf);
|
|
14
|
-
buildManifest: (
|
|
15
|
-
initPatterns: (adapterKey: string, catalog: Catalog, aiQueue?: AIQueue) => Promise<boolean>;
|
|
16
|
-
match:
|
|
17
|
-
matchToCompile: (key: string,
|
|
11
|
+
buildManifest: () => URLManifest;
|
|
12
|
+
initPatterns: (adapterKey: string, catalog: Catalog, fallbackChains: Map<string, string[]>, aiQueue?: AIQueue) => Promise<boolean>;
|
|
13
|
+
match: UrlMatcher;
|
|
14
|
+
matchToCompile: (key: string, locale: string) => string;
|
|
18
15
|
}
|