react-cheminfo 0.53.0 → 0.54.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/lib/i18n/core/index.d.ts +2 -0
- package/lib/i18n/core/index.d.ts.map +1 -1
- package/lib/i18n/core/index.js +1 -0
- package/lib/i18n/core/index.js.map +1 -1
- package/lib/i18n/core/messageCatalog.d.ts +10 -0
- package/lib/i18n/core/messageCatalog.d.ts.map +1 -1
- package/lib/i18n/core/messageCatalog.js +12 -0
- package/lib/i18n/core/messageCatalog.js.map +1 -1
- package/lib/i18n/core/translate.d.ts +35 -0
- package/lib/i18n/core/translate.d.ts.map +1 -0
- package/lib/i18n/core/translate.js +27 -0
- package/lib/i18n/core/translate.js.map +1 -0
- package/lib/i18n/ui/useT.d.ts +2 -12
- package/lib/i18n/ui/useT.d.ts.map +1 -1
- package/lib/i18n/ui/useT.js +2 -8
- package/lib/i18n/ui/useT.js.map +1 -1
- package/lib/i18n/vite/index.d.ts +3 -0
- package/lib/i18n/vite/index.d.ts.map +1 -0
- package/lib/i18n/vite/index.js +2 -0
- package/lib/i18n/vite/index.js.map +1 -0
- package/lib/i18n/vite/localeCatalog.d.ts +70 -0
- package/lib/i18n/vite/localeCatalog.d.ts.map +1 -0
- package/lib/i18n/vite/localeCatalog.js +80 -0
- package/lib/i18n/vite/localeCatalog.js.map +1 -0
- package/lib/vite.d.ts +1 -0
- package/lib/vite.d.ts.map +1 -1
- package/lib/vite.js +1 -0
- package/lib/vite.js.map +1 -1
- package/package.json +1 -1
- package/src/i18n/core/index.ts +2 -0
- package/src/i18n/core/messageCatalog.ts +13 -0
- package/src/i18n/core/translate.ts +51 -0
- package/src/i18n/ui/useT.ts +6 -29
- package/src/i18n/vite/index.ts +5 -0
- package/src/i18n/vite/localeCatalog.ts +121 -0
- package/src/vite.ts +1 -0
package/lib/i18n/core/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export { DEFAULT_LANGUAGE, LANGUAGES, LANGUAGE_LABELS, isLanguage, } from './lan
|
|
|
5
5
|
export type { LooseKey, MessageCatalogOptions, MessagesLoader, TranslateOptions, } from './messageCatalog.ts';
|
|
6
6
|
export { MessageCatalog } from './messageCatalog.ts';
|
|
7
7
|
export type { MessageValues } from './messageValues.ts';
|
|
8
|
+
export type { Translate } from './translate.ts';
|
|
9
|
+
export { catalogTranslate } from './translate.ts';
|
|
8
10
|
export type { ProsePiece } from './prose.ts';
|
|
9
11
|
export { splitProse } from './prose.ts';
|
|
10
12
|
export type { MessageSession } from './session.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/i18n/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,QAAQ,EACR,qBAAqB,EACrB,cAAc,EACd,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/i18n/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,QAAQ,EACR,qBAAqB,EACrB,cAAc,EACd,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
package/lib/i18n/core/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { CHROME_CATALOG, CHROME_CATALOG_ID } from "./chromeCatalog.js";
|
|
2
2
|
export { DEFAULT_LANGUAGE, LANGUAGES, LANGUAGE_LABELS, isLanguage, } from "./languages.js";
|
|
3
3
|
export { MessageCatalog } from "./messageCatalog.js";
|
|
4
|
+
export { catalogTranslate } from "./translate.js";
|
|
4
5
|
export { splitProse } from "./prose.js";
|
|
5
6
|
export { messageSession, messagesVersion, setMessageSession, subscribeToMessages, } from "./session.js";
|
|
6
7
|
export { loadCatalogs } from "./translateSetup.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/i18n/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/i18n/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -90,6 +90,16 @@ export declare class MessageCatalog<TKey extends string = string> {
|
|
|
90
90
|
* @returns The text.
|
|
91
91
|
*/
|
|
92
92
|
translate(key: LooseKey<TKey>, language: Language, options?: TranslateOptions): string;
|
|
93
|
+
/**
|
|
94
|
+
* Whether the catalog declares a key at all.
|
|
95
|
+
*
|
|
96
|
+
* English is the list of keys, so this is what a loop walking a numbered
|
|
97
|
+
* family of messages — `how.limits.p1`, `p2`, … — stops on, and what tells a
|
|
98
|
+
* page a section was never written from one left untranslated.
|
|
99
|
+
* @param key - Key to look for.
|
|
100
|
+
* @returns True when English carries it.
|
|
101
|
+
*/
|
|
102
|
+
declares(key: string): boolean;
|
|
93
103
|
/**
|
|
94
104
|
* The messages of a language, once they are in memory.
|
|
95
105
|
* @param language - Language asked for.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageCatalog.d.ts","sourceRoot":"","sources":["../../../src/i18n/core/messageCatalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAG/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,MAAM,IACtC,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEzC,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,iCAAiC;AACjC,MAAM,WAAW,qBAAqB,CAAC,IAAI,SAAS,MAAM;IACxD;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC;CACrE;AAED;;;GAGG;AACH,qBAAa,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;;IACtD,+CAA+C;IAC/C,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,SAAgB,MAAM,EAAE,aAAa,CAAC;IAMtC;;;OAGG;gBACgB,OAAO,EAAE,qBAAqB,CAAC,IAAI,CAAC;IAevD;;;OAGG;IACH,IAAW,SAAS,IAAI,QAAQ,EAAE,CAEjC;IAED;;;;;;OAMG;IACI,SAAS,CACd,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EACnB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,gBAAqB,GAC7B,MAAM;IAkBT;;;;OAIG;IACI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ;IAI7C;;;;OAIG;IACU,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyBxD;;;;;OAKG;IACI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAI1C"}
|
|
1
|
+
{"version":3,"file":"messageCatalog.d.ts","sourceRoot":"","sources":["../../../src/i18n/core/messageCatalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAG/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,MAAM,IACtC,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEzC,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,iCAAiC;AACjC,MAAM,WAAW,qBAAqB,CAAC,IAAI,SAAS,MAAM;IACxD;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC;CACrE;AAED;;;GAGG;AACH,qBAAa,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;;IACtD,+CAA+C;IAC/C,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,SAAgB,MAAM,EAAE,aAAa,CAAC;IAMtC;;;OAGG;gBACgB,OAAO,EAAE,qBAAqB,CAAC,IAAI,CAAC;IAevD;;;OAGG;IACH,IAAW,SAAS,IAAI,QAAQ,EAAE,CAEjC;IAED;;;;;;OAMG;IACI,SAAS,CACd,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EACnB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,gBAAqB,GAC7B,MAAM;IAkBT;;;;;;;;OAQG;IACI,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIrC;;;;OAIG;IACI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ;IAI7C;;;;OAIG;IACU,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyBxD;;;;;OAKG;IACI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAI1C"}
|
|
@@ -77,6 +77,18 @@ export class MessageCatalog {
|
|
|
77
77
|
fallback;
|
|
78
78
|
return fill(message, values);
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether the catalog declares a key at all.
|
|
82
|
+
*
|
|
83
|
+
* English is the list of keys, so this is what a loop walking a numbered
|
|
84
|
+
* family of messages — `how.limits.p1`, `p2`, … — stops on, and what tells a
|
|
85
|
+
* page a section was never written from one left untranslated.
|
|
86
|
+
* @param key - Key to look for.
|
|
87
|
+
* @returns True when English carries it.
|
|
88
|
+
*/
|
|
89
|
+
declares(key) {
|
|
90
|
+
return ownMessage(this.source.messages, key) !== undefined;
|
|
91
|
+
}
|
|
80
92
|
/**
|
|
81
93
|
* The messages of a language, once they are in memory.
|
|
82
94
|
* @param language - Language asked for.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageCatalog.js","sourceRoot":"","sources":["../../../src/i18n/core/messageCatalog.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"messageCatalog.js","sourceRoot":"","sources":["../../../src/i18n/core/messageCatalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The formatter a catalog's text is read through, outside React.
|
|
3
|
+
*
|
|
4
|
+
* `useT` is this function with the page's language and a redraw wired to it;
|
|
5
|
+
* the build and a site's own tests need the same shape without either, so it
|
|
6
|
+
* lives here rather than in the hook. A site never writes its own: four of
|
|
7
|
+
* them had, each with a slightly different fallback.
|
|
8
|
+
*/
|
|
9
|
+
import type { Language } from './languages.ts';
|
|
10
|
+
import type { LooseKey, MessageCatalog } from './messageCatalog.ts';
|
|
11
|
+
import type { MessageValues } from './messageValues.ts';
|
|
12
|
+
/**
|
|
13
|
+
* What text is read with.
|
|
14
|
+
*
|
|
15
|
+
* `t(key)` is a key the catalog declares, checked at compile time.
|
|
16
|
+
* `t.or(key, fallback)` is a key built from the data — a site's id, an
|
|
17
|
+
* element's symbol — which the catalog may not have caught up with yet; it
|
|
18
|
+
* reads as the fallback rather than as a raw key.
|
|
19
|
+
*/
|
|
20
|
+
export type Translate<TKey extends string> = ((key: LooseKey<TKey>, values?: MessageValues) => string) & {
|
|
21
|
+
or: (key: string, fallback: string, values?: MessageValues) => string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* A catalog's formatter, in one language.
|
|
25
|
+
*
|
|
26
|
+
* In a component this is `useT`, which also redraws when the language or a
|
|
27
|
+
* translator's edit changes it. Here it is for the places a hook cannot go:
|
|
28
|
+
* the build writing a head per address per language, a test asserting on the
|
|
29
|
+
* text a page shows, a label computed in a module helper.
|
|
30
|
+
* @param catalog - The catalog to read, typed by its English keys.
|
|
31
|
+
* @param language - The language to read it in.
|
|
32
|
+
* @returns See {@link Translate}.
|
|
33
|
+
*/
|
|
34
|
+
export declare function catalogTranslate<TKey extends string>(catalog: MessageCatalog<TKey>, language: Language): Translate<TKey>;
|
|
35
|
+
//# sourceMappingURL=translate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../../src/i18n/core/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,CAAC,IAAI,SAAS,MAAM,IAAI,CAAC,CAC5C,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EACnB,MAAM,CAAC,EAAE,aAAa,KACnB,MAAM,CAAC,GAAG;IACb,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,KAAK,MAAM,CAAC;CACvE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,SAAS,MAAM,EAClD,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,EAC7B,QAAQ,EAAE,QAAQ,GACjB,SAAS,CAAC,IAAI,CAAC,CAQjB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The formatter a catalog's text is read through, outside React.
|
|
3
|
+
*
|
|
4
|
+
* `useT` is this function with the page's language and a redraw wired to it;
|
|
5
|
+
* the build and a site's own tests need the same shape without either, so it
|
|
6
|
+
* lives here rather than in the hook. A site never writes its own: four of
|
|
7
|
+
* them had, each with a slightly different fallback.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* A catalog's formatter, in one language.
|
|
11
|
+
*
|
|
12
|
+
* In a component this is `useT`, which also redraws when the language or a
|
|
13
|
+
* translator's edit changes it. Here it is for the places a hook cannot go:
|
|
14
|
+
* the build writing a head per address per language, a test asserting on the
|
|
15
|
+
* text a page shows, a label computed in a module helper.
|
|
16
|
+
* @param catalog - The catalog to read, typed by its English keys.
|
|
17
|
+
* @param language - The language to read it in.
|
|
18
|
+
* @returns See {@link Translate}.
|
|
19
|
+
*/
|
|
20
|
+
export function catalogTranslate(catalog, language) {
|
|
21
|
+
// `or` is a property of the function itself, so the two are built together
|
|
22
|
+
// rather than assigned onto a value a render may already have read.
|
|
23
|
+
const translate = (key, values) => catalog.translate(key, language, { values });
|
|
24
|
+
translate.or = (key, fallback, values) => catalog.translate(key, language, { fallback, values });
|
|
25
|
+
return translate;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=translate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../../src/i18n/core/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqBH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAA6B,EAC7B,QAAkB;IAElB,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,SAAS,GAAG,CAAC,GAAmB,EAAE,MAAsB,EAAE,EAAE,CAChE,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,SAAS,CAAC,EAAE,GAAG,CAAC,GAAW,EAAE,QAAgB,EAAE,MAAsB,EAAE,EAAE,CACvE,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACzD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/lib/i18n/ui/useT.d.ts
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
import type { ChromeKey } from '../core/chromeCatalog.ts';
|
|
2
|
-
import type { Language, LooseKey,
|
|
2
|
+
import type { Language, LooseKey, Translate, TranslateOptions } from '../core/index.ts';
|
|
3
3
|
import type { MessageCatalog } from '../core/messageCatalog.ts';
|
|
4
|
-
|
|
5
|
-
* What a component reads its text with.
|
|
6
|
-
*
|
|
7
|
-
* `t(key)` is a key the catalog declares, checked at compile time.
|
|
8
|
-
* `t.or(key, fallback)` is a key built from the data — a site's id, an
|
|
9
|
-
* element's symbol — which the catalog may not have caught up with yet; it
|
|
10
|
-
* reads as the fallback rather than as a raw key.
|
|
11
|
-
*/
|
|
12
|
-
export type Translate<TKey extends string> = ((key: LooseKey<TKey>, values?: MessageValues) => string) & {
|
|
13
|
-
or: (key: string, fallback: string, values?: MessageValues) => string;
|
|
14
|
-
};
|
|
4
|
+
export type { Translate } from '../core/index.ts';
|
|
15
5
|
/**
|
|
16
6
|
* The formatter of a catalog's text, in the language the page is written in.
|
|
17
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useT.d.ts","sourceRoot":"","sources":["../../../src/i18n/ui/useT.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"useT.d.ts","sourceRoot":"","sources":["../../../src/i18n/ui/useT.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMhE,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,IAAI,SAAS,MAAM,EACtC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAC5B,SAAS,CAAC,IAAI,CAAC,CAKjB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,SAAS,CAAC,SAAS,CAAC,CAEjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,SAAS,MAAM,EAClD,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,EAC7B,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EACnB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAER"}
|
package/lib/i18n/ui/useT.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CHROME_CATALOG } from "../core/chromeCatalog.js";
|
|
2
|
+
import { catalogTranslate } from "../core/index.js";
|
|
2
3
|
import { useLanguage, useMessagesVersion } from "./useLanguage.js";
|
|
3
4
|
/**
|
|
4
5
|
* The formatter of a catalog's text, in the language the page is written in.
|
|
@@ -13,14 +14,7 @@ export function useT(catalog) {
|
|
|
13
14
|
const language = useLanguage();
|
|
14
15
|
useMessagesVersion();
|
|
15
16
|
catalog.prefetch(language);
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
// Built outside the hook, because the `or` form is a property of the function
|
|
19
|
-
// itself and a render may not write to a value it has just read.
|
|
20
|
-
function translator(catalog, language) {
|
|
21
|
-
const translate = (key, values) => catalog.translate(key, language, { values });
|
|
22
|
-
translate.or = (key, fallback, values) => catalog.translate(key, language, { fallback, values });
|
|
23
|
-
return translate;
|
|
17
|
+
return catalogTranslate(catalog, language);
|
|
24
18
|
}
|
|
25
19
|
/**
|
|
26
20
|
* The formatter of this library's own text — the header, the Tools menu, the
|
package/lib/i18n/ui/useT.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useT.js","sourceRoot":"","sources":["../../../src/i18n/ui/useT.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"useT.js","sourceRoot":"","sources":["../../../src/i18n/ui/useT.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAMnE;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAClB,OAA6B;IAE7B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,kBAAkB,EAAE,CAAC;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3B,OAAO,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAA6B,EAC7B,GAAmB,EACnB,QAAkB,EAClB,OAA0B;IAE1B,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/i18n/vite/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/i18n/vite/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A site's catalogs as the build reads them: all of them, off disk, at once.
|
|
3
|
+
*
|
|
4
|
+
* The page and the build want opposite things from the same files. A browser
|
|
5
|
+
* fetches one language — the one being read — so `en.json` is part of the
|
|
6
|
+
* bundle and the others are `import()`ed when a visitor asks, which is what
|
|
7
|
+
* keeps a site nobody reads in German from downloading the German. The build
|
|
8
|
+
* writes a head per address per language in one pass, so it wants every
|
|
9
|
+
* language, synchronously, before the first route table is asked for.
|
|
10
|
+
*
|
|
11
|
+
* Reading them rather than fetching them is what makes that possible. The
|
|
12
|
+
* page's loaders are written bare — `import('../locales/fr.json')` with no
|
|
13
|
+
* `with { type: 'json' }` — because the dev server serves a JSON file as a
|
|
14
|
+
* JavaScript module and a browser refuses a chunk it was promised JSON for.
|
|
15
|
+
* Node demands the attribute, so it cannot run those loaders: a build that
|
|
16
|
+
* awaited them had to be async and still only worked by keeping a second,
|
|
17
|
+
* eagerly imported copy of every catalog beside the first. `readFileSync` has
|
|
18
|
+
* no attribute, so there is nothing to work around.
|
|
19
|
+
*
|
|
20
|
+
* The identity comes from the page's own catalog, never re-typed here: pass
|
|
21
|
+
* `SITE_CATALOG.source` and the two provably name the same files.
|
|
22
|
+
*/
|
|
23
|
+
import { MessageCatalog } from '../core/index.ts';
|
|
24
|
+
/**
|
|
25
|
+
* Which catalog to read, which is the page catalog's own `source`.
|
|
26
|
+
*
|
|
27
|
+
* `MessageCatalog` publishes it for the translate overlay, and it already
|
|
28
|
+
* carries the three things a reader needs. Hand it over rather than writing
|
|
29
|
+
* them twice: a build that names its own directory is a build that can come to
|
|
30
|
+
* disagree with the page about which files the site is translated in.
|
|
31
|
+
*/
|
|
32
|
+
export interface LocaleCatalogSource {
|
|
33
|
+
/**
|
|
34
|
+
* The name the page knows the catalog by, which is the site's host, e.g.
|
|
35
|
+
* `surge.cheminfo.org`. A translator's edit is routed back to the right
|
|
36
|
+
* repository with it, so the build and the page must agree on it.
|
|
37
|
+
*/
|
|
38
|
+
id: string;
|
|
39
|
+
/** The GitHub repository the files live in, written `owner/repo`. */
|
|
40
|
+
repository: string;
|
|
41
|
+
/** The directory holding the locale files, relative to the repository root. */
|
|
42
|
+
directory: string;
|
|
43
|
+
}
|
|
44
|
+
/** Where the directory is looked for. */
|
|
45
|
+
export interface LocaleCatalogOptions {
|
|
46
|
+
/**
|
|
47
|
+
* What the source's relative `directory` is resolved against. The default is
|
|
48
|
+
* the working directory, which is the repository root for both callers: a
|
|
49
|
+
* Vite config and a vitest run.
|
|
50
|
+
* @default process.cwd()
|
|
51
|
+
*/
|
|
52
|
+
root?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Every language a site is written in, read off disk into one catalog.
|
|
56
|
+
*
|
|
57
|
+
* For the build and for a site's own tests, never for the page: it reads the
|
|
58
|
+
* filesystem, and the translations it holds are tens of kilobytes a first
|
|
59
|
+
* visit must not pay for. Read one language out of it with `catalogTranslate`.
|
|
60
|
+
*
|
|
61
|
+
* A language whose file is absent is left out, which the catalog already reads
|
|
62
|
+
* as English — a half-translated site serves the pages it has rather than
|
|
63
|
+
* failing the build. A missing English file is a misconfiguration and throws:
|
|
64
|
+
* every key and every fallback is declared there.
|
|
65
|
+
* @param source - The page catalog's own `source`. See {@link LocaleCatalogSource}.
|
|
66
|
+
* @param options - See {@link LocaleCatalogOptions}.
|
|
67
|
+
* @returns The catalog, every language it carries already in memory.
|
|
68
|
+
*/
|
|
69
|
+
export declare function readLocaleCatalog<TKey extends string = string>(source: LocaleCatalogSource, options?: LocaleCatalogOptions): MessageCatalog<TKey>;
|
|
70
|
+
//# sourceMappingURL=localeCatalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localeCatalog.d.ts","sourceRoot":"","sources":["../../../src/i18n/vite/localeCatalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,EAA+B,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5D,MAAM,EAAE,mBAAmB,EAC3B,OAAO,GAAE,oBAAyB,GACjC,cAAc,CAAC,IAAI,CAAC,CAsBtB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A site's catalogs as the build reads them: all of them, off disk, at once.
|
|
3
|
+
*
|
|
4
|
+
* The page and the build want opposite things from the same files. A browser
|
|
5
|
+
* fetches one language — the one being read — so `en.json` is part of the
|
|
6
|
+
* bundle and the others are `import()`ed when a visitor asks, which is what
|
|
7
|
+
* keeps a site nobody reads in German from downloading the German. The build
|
|
8
|
+
* writes a head per address per language in one pass, so it wants every
|
|
9
|
+
* language, synchronously, before the first route table is asked for.
|
|
10
|
+
*
|
|
11
|
+
* Reading them rather than fetching them is what makes that possible. The
|
|
12
|
+
* page's loaders are written bare — `import('../locales/fr.json')` with no
|
|
13
|
+
* `with { type: 'json' }` — because the dev server serves a JSON file as a
|
|
14
|
+
* JavaScript module and a browser refuses a chunk it was promised JSON for.
|
|
15
|
+
* Node demands the attribute, so it cannot run those loaders: a build that
|
|
16
|
+
* awaited them had to be async and still only worked by keeping a second,
|
|
17
|
+
* eagerly imported copy of every catalog beside the first. `readFileSync` has
|
|
18
|
+
* no attribute, so there is nothing to work around.
|
|
19
|
+
*
|
|
20
|
+
* The identity comes from the page's own catalog, never re-typed here: pass
|
|
21
|
+
* `SITE_CATALOG.source` and the two provably name the same files.
|
|
22
|
+
*/
|
|
23
|
+
import { readFileSync } from 'node:fs';
|
|
24
|
+
import { join, resolve } from 'node:path';
|
|
25
|
+
import { DEFAULT_LANGUAGE, LANGUAGES, MessageCatalog } from "../core/index.js";
|
|
26
|
+
/**
|
|
27
|
+
* Every language a site is written in, read off disk into one catalog.
|
|
28
|
+
*
|
|
29
|
+
* For the build and for a site's own tests, never for the page: it reads the
|
|
30
|
+
* filesystem, and the translations it holds are tens of kilobytes a first
|
|
31
|
+
* visit must not pay for. Read one language out of it with `catalogTranslate`.
|
|
32
|
+
*
|
|
33
|
+
* A language whose file is absent is left out, which the catalog already reads
|
|
34
|
+
* as English — a half-translated site serves the pages it has rather than
|
|
35
|
+
* failing the build. A missing English file is a misconfiguration and throws:
|
|
36
|
+
* every key and every fallback is declared there.
|
|
37
|
+
* @param source - The page catalog's own `source`. See {@link LocaleCatalogSource}.
|
|
38
|
+
* @param options - See {@link LocaleCatalogOptions}.
|
|
39
|
+
* @returns The catalog, every language it carries already in memory.
|
|
40
|
+
*/
|
|
41
|
+
export function readLocaleCatalog(source, options = {}) {
|
|
42
|
+
const { id, repository, directory } = source;
|
|
43
|
+
const folder = resolve(options.root ?? process.cwd(), directory);
|
|
44
|
+
const english = readMessages(folder, DEFAULT_LANGUAGE);
|
|
45
|
+
if (english === undefined) {
|
|
46
|
+
throw new Error(`no ${DEFAULT_LANGUAGE}.json in ${folder}: a catalog declares its keys and its fallbacks there`);
|
|
47
|
+
}
|
|
48
|
+
const translations = {};
|
|
49
|
+
for (const language of LANGUAGES) {
|
|
50
|
+
if (language === DEFAULT_LANGUAGE)
|
|
51
|
+
continue;
|
|
52
|
+
const messages = readMessages(folder, language);
|
|
53
|
+
if (messages !== undefined)
|
|
54
|
+
translations[language] = messages;
|
|
55
|
+
}
|
|
56
|
+
return new MessageCatalog({
|
|
57
|
+
id,
|
|
58
|
+
repository,
|
|
59
|
+
directory,
|
|
60
|
+
source: english,
|
|
61
|
+
translations,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* One language's messages, read off disk.
|
|
66
|
+
* @param folder - The resolved directory holding the locale files.
|
|
67
|
+
* @param language - The language whose file to read.
|
|
68
|
+
* @returns Its messages, or `undefined` when the site does not carry it.
|
|
69
|
+
*/
|
|
70
|
+
function readMessages(folder, language) {
|
|
71
|
+
let text;
|
|
72
|
+
try {
|
|
73
|
+
text = readFileSync(join(folder, `${language}.json`), 'utf8');
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
return JSON.parse(text);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=localeCatalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localeCatalog.js","sourceRoot":"","sources":["../../../src/i18n/vite/localeCatalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAkC/E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA2B,EAC3B,UAAgC,EAAE;IAElC,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACvD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,MAAM,gBAAgB,YAAY,MAAM,uDAAuD,CAChG,CAAC;IACJ,CAAC;IACD,MAAM,YAAY,GAAsD,EAAE,CAAC;IAC3E,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,QAAQ,KAAK,gBAAgB;YAAE,SAAS;QAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,SAAS;YAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,cAAc,CAAO;QAC9B,EAAE;QACF,UAAU;QACV,SAAS;QACT,MAAM,EAAE,OAAO;QACf,YAAY;KACb,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CACnB,MAAc,EACd,QAAkB;IAElB,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAA2B,CAAC;AACpD,CAAC"}
|
package/lib/vite.d.ts
CHANGED
package/lib/vite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
|
package/lib/vite.js
CHANGED
package/lib/vite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-cheminfo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React components, hooks and framework-free helpers shared by the cheminfo sites: site chrome, citations, sharing, routing, pedagogy, charts, and the structure, orbital and 3D molecule viewers",
|
|
6
6
|
"author": "Luc Patiny",
|
package/src/i18n/core/index.ts
CHANGED
|
@@ -15,6 +15,8 @@ export type {
|
|
|
15
15
|
} from './messageCatalog.ts';
|
|
16
16
|
export { MessageCatalog } from './messageCatalog.ts';
|
|
17
17
|
export type { MessageValues } from './messageValues.ts';
|
|
18
|
+
export type { Translate } from './translate.ts';
|
|
19
|
+
export { catalogTranslate } from './translate.ts';
|
|
18
20
|
export type { ProsePiece } from './prose.ts';
|
|
19
21
|
export { splitProse } from './prose.ts';
|
|
20
22
|
export type { MessageSession } from './session.ts';
|
|
@@ -141,6 +141,19 @@ export class MessageCatalog<TKey extends string = string> {
|
|
|
141
141
|
return fill(message, values);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Whether the catalog declares a key at all.
|
|
146
|
+
*
|
|
147
|
+
* English is the list of keys, so this is what a loop walking a numbered
|
|
148
|
+
* family of messages — `how.limits.p1`, `p2`, … — stops on, and what tells a
|
|
149
|
+
* page a section was never written from one left untranslated.
|
|
150
|
+
* @param key - Key to look for.
|
|
151
|
+
* @returns True when English carries it.
|
|
152
|
+
*/
|
|
153
|
+
public declares(key: string): boolean {
|
|
154
|
+
return ownMessage(this.source.messages, key) !== undefined;
|
|
155
|
+
}
|
|
156
|
+
|
|
144
157
|
/**
|
|
145
158
|
* The messages of a language, once they are in memory.
|
|
146
159
|
* @param language - Language asked for.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The formatter a catalog's text is read through, outside React.
|
|
3
|
+
*
|
|
4
|
+
* `useT` is this function with the page's language and a redraw wired to it;
|
|
5
|
+
* the build and a site's own tests need the same shape without either, so it
|
|
6
|
+
* lives here rather than in the hook. A site never writes its own: four of
|
|
7
|
+
* them had, each with a slightly different fallback.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Language } from './languages.ts';
|
|
11
|
+
import type { LooseKey, MessageCatalog } from './messageCatalog.ts';
|
|
12
|
+
import type { MessageValues } from './messageValues.ts';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* What text is read with.
|
|
16
|
+
*
|
|
17
|
+
* `t(key)` is a key the catalog declares, checked at compile time.
|
|
18
|
+
* `t.or(key, fallback)` is a key built from the data — a site's id, an
|
|
19
|
+
* element's symbol — which the catalog may not have caught up with yet; it
|
|
20
|
+
* reads as the fallback rather than as a raw key.
|
|
21
|
+
*/
|
|
22
|
+
export type Translate<TKey extends string> = ((
|
|
23
|
+
key: LooseKey<TKey>,
|
|
24
|
+
values?: MessageValues,
|
|
25
|
+
) => string) & {
|
|
26
|
+
or: (key: string, fallback: string, values?: MessageValues) => string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A catalog's formatter, in one language.
|
|
31
|
+
*
|
|
32
|
+
* In a component this is `useT`, which also redraws when the language or a
|
|
33
|
+
* translator's edit changes it. Here it is for the places a hook cannot go:
|
|
34
|
+
* the build writing a head per address per language, a test asserting on the
|
|
35
|
+
* text a page shows, a label computed in a module helper.
|
|
36
|
+
* @param catalog - The catalog to read, typed by its English keys.
|
|
37
|
+
* @param language - The language to read it in.
|
|
38
|
+
* @returns See {@link Translate}.
|
|
39
|
+
*/
|
|
40
|
+
export function catalogTranslate<TKey extends string>(
|
|
41
|
+
catalog: MessageCatalog<TKey>,
|
|
42
|
+
language: Language,
|
|
43
|
+
): Translate<TKey> {
|
|
44
|
+
// `or` is a property of the function itself, so the two are built together
|
|
45
|
+
// rather than assigned onto a value a render may already have read.
|
|
46
|
+
const translate = (key: LooseKey<TKey>, values?: MessageValues) =>
|
|
47
|
+
catalog.translate(key, language, { values });
|
|
48
|
+
translate.or = (key: string, fallback: string, values?: MessageValues) =>
|
|
49
|
+
catalog.translate(key, language, { fallback, values });
|
|
50
|
+
return translate;
|
|
51
|
+
}
|
package/src/i18n/ui/useT.ts
CHANGED
|
@@ -3,27 +3,17 @@ import { CHROME_CATALOG } from '../core/chromeCatalog.ts';
|
|
|
3
3
|
import type {
|
|
4
4
|
Language,
|
|
5
5
|
LooseKey,
|
|
6
|
-
|
|
6
|
+
Translate,
|
|
7
7
|
TranslateOptions,
|
|
8
8
|
} from '../core/index.ts';
|
|
9
|
+
import { catalogTranslate } from '../core/index.ts';
|
|
9
10
|
import type { MessageCatalog } from '../core/messageCatalog.ts';
|
|
10
11
|
|
|
11
12
|
import { useLanguage, useMessagesVersion } from './useLanguage.ts';
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* `t(key)` is a key the catalog declares, checked at compile time.
|
|
17
|
-
* `t.or(key, fallback)` is a key built from the data — a site's id, an
|
|
18
|
-
* element's symbol — which the catalog may not have caught up with yet; it
|
|
19
|
-
* reads as the fallback rather than as a raw key.
|
|
20
|
-
*/
|
|
21
|
-
export type Translate<TKey extends string> = ((
|
|
22
|
-
key: LooseKey<TKey>,
|
|
23
|
-
values?: MessageValues,
|
|
24
|
-
) => string) & {
|
|
25
|
-
or: (key: string, fallback: string, values?: MessageValues) => string;
|
|
26
|
-
};
|
|
14
|
+
// The formatter's own shape belongs to the catalog, not to the hook, and a site
|
|
15
|
+
// reads it from either entry point.
|
|
16
|
+
export type { Translate } from '../core/index.ts';
|
|
27
17
|
|
|
28
18
|
/**
|
|
29
19
|
* The formatter of a catalog's text, in the language the page is written in.
|
|
@@ -40,20 +30,7 @@ export function useT<TKey extends string>(
|
|
|
40
30
|
const language = useLanguage();
|
|
41
31
|
useMessagesVersion();
|
|
42
32
|
catalog.prefetch(language);
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Built outside the hook, because the `or` form is a property of the function
|
|
47
|
-
// itself and a render may not write to a value it has just read.
|
|
48
|
-
function translator<TKey extends string>(
|
|
49
|
-
catalog: MessageCatalog<TKey>,
|
|
50
|
-
language: Language,
|
|
51
|
-
): Translate<TKey> {
|
|
52
|
-
const translate = (key: LooseKey<TKey>, values?: MessageValues) =>
|
|
53
|
-
catalog.translate(key, language, { values });
|
|
54
|
-
translate.or = (key: string, fallback: string, values?: MessageValues) =>
|
|
55
|
-
catalog.translate(key, language, { fallback, values });
|
|
56
|
-
return translate;
|
|
33
|
+
return catalogTranslate(catalog, language);
|
|
57
34
|
}
|
|
58
35
|
|
|
59
36
|
/**
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A site's catalogs as the build reads them: all of them, off disk, at once.
|
|
3
|
+
*
|
|
4
|
+
* The page and the build want opposite things from the same files. A browser
|
|
5
|
+
* fetches one language — the one being read — so `en.json` is part of the
|
|
6
|
+
* bundle and the others are `import()`ed when a visitor asks, which is what
|
|
7
|
+
* keeps a site nobody reads in German from downloading the German. The build
|
|
8
|
+
* writes a head per address per language in one pass, so it wants every
|
|
9
|
+
* language, synchronously, before the first route table is asked for.
|
|
10
|
+
*
|
|
11
|
+
* Reading them rather than fetching them is what makes that possible. The
|
|
12
|
+
* page's loaders are written bare — `import('../locales/fr.json')` with no
|
|
13
|
+
* `with { type: 'json' }` — because the dev server serves a JSON file as a
|
|
14
|
+
* JavaScript module and a browser refuses a chunk it was promised JSON for.
|
|
15
|
+
* Node demands the attribute, so it cannot run those loaders: a build that
|
|
16
|
+
* awaited them had to be async and still only worked by keeping a second,
|
|
17
|
+
* eagerly imported copy of every catalog beside the first. `readFileSync` has
|
|
18
|
+
* no attribute, so there is nothing to work around.
|
|
19
|
+
*
|
|
20
|
+
* The identity comes from the page's own catalog, never re-typed here: pass
|
|
21
|
+
* `SITE_CATALOG.source` and the two provably name the same files.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { readFileSync } from 'node:fs';
|
|
25
|
+
import { join, resolve } from 'node:path';
|
|
26
|
+
|
|
27
|
+
import type { Language } from '../core/index.ts';
|
|
28
|
+
import { DEFAULT_LANGUAGE, LANGUAGES, MessageCatalog } from '../core/index.ts';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Which catalog to read, which is the page catalog's own `source`.
|
|
32
|
+
*
|
|
33
|
+
* `MessageCatalog` publishes it for the translate overlay, and it already
|
|
34
|
+
* carries the three things a reader needs. Hand it over rather than writing
|
|
35
|
+
* them twice: a build that names its own directory is a build that can come to
|
|
36
|
+
* disagree with the page about which files the site is translated in.
|
|
37
|
+
*/
|
|
38
|
+
export interface LocaleCatalogSource {
|
|
39
|
+
/**
|
|
40
|
+
* The name the page knows the catalog by, which is the site's host, e.g.
|
|
41
|
+
* `surge.cheminfo.org`. A translator's edit is routed back to the right
|
|
42
|
+
* repository with it, so the build and the page must agree on it.
|
|
43
|
+
*/
|
|
44
|
+
id: string;
|
|
45
|
+
/** The GitHub repository the files live in, written `owner/repo`. */
|
|
46
|
+
repository: string;
|
|
47
|
+
/** The directory holding the locale files, relative to the repository root. */
|
|
48
|
+
directory: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Where the directory is looked for. */
|
|
52
|
+
export interface LocaleCatalogOptions {
|
|
53
|
+
/**
|
|
54
|
+
* What the source's relative `directory` is resolved against. The default is
|
|
55
|
+
* the working directory, which is the repository root for both callers: a
|
|
56
|
+
* Vite config and a vitest run.
|
|
57
|
+
* @default process.cwd()
|
|
58
|
+
*/
|
|
59
|
+
root?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Every language a site is written in, read off disk into one catalog.
|
|
64
|
+
*
|
|
65
|
+
* For the build and for a site's own tests, never for the page: it reads the
|
|
66
|
+
* filesystem, and the translations it holds are tens of kilobytes a first
|
|
67
|
+
* visit must not pay for. Read one language out of it with `catalogTranslate`.
|
|
68
|
+
*
|
|
69
|
+
* A language whose file is absent is left out, which the catalog already reads
|
|
70
|
+
* as English — a half-translated site serves the pages it has rather than
|
|
71
|
+
* failing the build. A missing English file is a misconfiguration and throws:
|
|
72
|
+
* every key and every fallback is declared there.
|
|
73
|
+
* @param source - The page catalog's own `source`. See {@link LocaleCatalogSource}.
|
|
74
|
+
* @param options - See {@link LocaleCatalogOptions}.
|
|
75
|
+
* @returns The catalog, every language it carries already in memory.
|
|
76
|
+
*/
|
|
77
|
+
export function readLocaleCatalog<TKey extends string = string>(
|
|
78
|
+
source: LocaleCatalogSource,
|
|
79
|
+
options: LocaleCatalogOptions = {},
|
|
80
|
+
): MessageCatalog<TKey> {
|
|
81
|
+
const { id, repository, directory } = source;
|
|
82
|
+
const folder = resolve(options.root ?? process.cwd(), directory);
|
|
83
|
+
const english = readMessages(folder, DEFAULT_LANGUAGE);
|
|
84
|
+
if (english === undefined) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`no ${DEFAULT_LANGUAGE}.json in ${folder}: a catalog declares its keys and its fallbacks there`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const translations: Partial<Record<Language, Record<string, string>>> = {};
|
|
90
|
+
for (const language of LANGUAGES) {
|
|
91
|
+
if (language === DEFAULT_LANGUAGE) continue;
|
|
92
|
+
const messages = readMessages(folder, language);
|
|
93
|
+
if (messages !== undefined) translations[language] = messages;
|
|
94
|
+
}
|
|
95
|
+
return new MessageCatalog<TKey>({
|
|
96
|
+
id,
|
|
97
|
+
repository,
|
|
98
|
+
directory,
|
|
99
|
+
source: english,
|
|
100
|
+
translations,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* One language's messages, read off disk.
|
|
106
|
+
* @param folder - The resolved directory holding the locale files.
|
|
107
|
+
* @param language - The language whose file to read.
|
|
108
|
+
* @returns Its messages, or `undefined` when the site does not carry it.
|
|
109
|
+
*/
|
|
110
|
+
function readMessages(
|
|
111
|
+
folder: string,
|
|
112
|
+
language: Language,
|
|
113
|
+
): Record<string, string> | undefined {
|
|
114
|
+
let text: string;
|
|
115
|
+
try {
|
|
116
|
+
text = readFileSync(join(folder, `${language}.json`), 'utf8');
|
|
117
|
+
} catch {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
return JSON.parse(text) as Record<string, string>;
|
|
121
|
+
}
|
package/src/vite.ts
CHANGED