moost 0.7.3 → 0.7.4
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.cjs +58 -18
- package/dist/index.d.ts +36 -8
- package/dist/index.mjs +58 -18
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -48,7 +48,7 @@ let stamped = false;
|
|
|
48
48
|
if (stamped) return;
|
|
49
49
|
stamped = true;
|
|
50
50
|
stampModuleIdentity({
|
|
51
|
-
version: "0.7.
|
|
51
|
+
version: "0.7.4",
|
|
52
52
|
path: typeof __filename === "string" ? __filename : require("url").pathToFileURL(__filename).href
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -3187,6 +3187,7 @@ function _define_property(obj, key, value) {
|
|
|
3187
3187
|
var _globalThis, _STATE, _state, _state1, _state2, _state3, _state4;
|
|
3188
3188
|
const STATE = Symbol.for("moost.i18n");
|
|
3189
3189
|
const NO_LOCALES = Object.freeze([]);
|
|
3190
|
+
/** Distinct scopes given memo keys per generation: keeps every memo keyed by `key` bounded. */ const MAX_SCOPES = 32;
|
|
3190
3191
|
const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE] = {});
|
|
3191
3192
|
(_state = state).locales ?? (_state.locales = NO_LOCALES);
|
|
3192
3193
|
(_state1 = state).generation ?? (_state1.generation = 0);
|
|
@@ -3216,9 +3217,14 @@ const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE]
|
|
|
3216
3217
|
*/ function setTranslator(translate, opts) {
|
|
3217
3218
|
const isMap = typeof translate === "object";
|
|
3218
3219
|
state.translate = isMap ? mapTranslator(translate) : translate;
|
|
3220
|
+
state.scoping = opts?.scope && {
|
|
3221
|
+
translate: state.translate,
|
|
3222
|
+
get: opts.scope
|
|
3223
|
+
};
|
|
3219
3224
|
const locales = opts?.locales ?? (isMap ? Object.keys(translate) : void 0);
|
|
3220
3225
|
state.locales = translate && locales?.length ? Object.freeze([...locales]) : NO_LOCALES;
|
|
3221
3226
|
state.failureLogged = false;
|
|
3227
|
+
state.scopeFailureLogged = false;
|
|
3222
3228
|
newGeneration();
|
|
3223
3229
|
}
|
|
3224
3230
|
/** The registered translator (a map wrapped as a function), or `undefined`. */ function getTranslator() {
|
|
@@ -3244,7 +3250,7 @@ const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE]
|
|
|
3244
3250
|
}
|
|
3245
3251
|
if (changed) newGeneration();
|
|
3246
3252
|
}
|
|
3247
|
-
/**
|
|
3253
|
+
/** Drops everything derived from the translator and the templates. */ function newGeneration() {
|
|
3248
3254
|
state.generation++;
|
|
3249
3255
|
state.memo.clear();
|
|
3250
3256
|
}
|
|
@@ -3279,10 +3285,7 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3279
3285
|
let translateCtx;
|
|
3280
3286
|
return (id, params, fallback) => {
|
|
3281
3287
|
const translate = state.translate;
|
|
3282
|
-
return (translate ? callTranslator(translate, id, params, translateCtx ?? (translateCtx =
|
|
3283
|
-
locale: (0, _wooksjs_event_core.useLocale)(event).get(),
|
|
3284
|
-
event
|
|
3285
|
-
})) : void 0) ?? untranslated(id, params, fallback);
|
|
3288
|
+
return (translate ? callTranslator(translate, id, params, translateCtx ?? (translateCtx = translateContext(event, (0, _wooksjs_event_core.useLocale)(event).get(), readScope(event)))) : void 0) ?? untranslated(id, params, fallback);
|
|
3286
3289
|
};
|
|
3287
3290
|
}
|
|
3288
3291
|
/** `t`'s text without a translation: `fallback` as is, else the filled template (or id). */ function untranslated(id, params, fallback) {
|
|
@@ -3298,12 +3301,11 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3298
3301
|
const event = ctx ?? (0, _wooksjs_event_core.current)();
|
|
3299
3302
|
const locale = (0, _wooksjs_event_core.useLocale)(event).get();
|
|
3300
3303
|
if (locale === void 0) return;
|
|
3301
|
-
const
|
|
3302
|
-
|
|
3303
|
-
event
|
|
3304
|
-
};
|
|
3304
|
+
const scope = readScope(event);
|
|
3305
|
+
const translateCtx = translateContext(event, locale, scope);
|
|
3305
3306
|
const generation = state.generation;
|
|
3306
|
-
const
|
|
3307
|
+
const partition = typeof scope === "string" ? `${locale}:${scope}` : locale;
|
|
3308
|
+
const key = state.locales.includes(locale) && (scope === void 0 || scope !== null && admitted(scope)) ? `${generation}:${partition}` : void 0;
|
|
3307
3309
|
const t = (id, params, fallback) => callTranslator(translate, id, params, translateCtx) ?? untranslated(id, params, fallback);
|
|
3308
3310
|
const messages = () => {
|
|
3309
3311
|
if (key === void 0 || state.generation !== generation) return translateTemplates(translate, translateCtx);
|
|
@@ -3316,11 +3318,52 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3316
3318
|
};
|
|
3317
3319
|
return {
|
|
3318
3320
|
locale,
|
|
3321
|
+
partition,
|
|
3319
3322
|
key,
|
|
3320
3323
|
t,
|
|
3321
3324
|
messages
|
|
3322
3325
|
};
|
|
3323
3326
|
}
|
|
3327
|
+
function translateContext(event, locale, scope) {
|
|
3328
|
+
return typeof scope === "string" ? {
|
|
3329
|
+
locale,
|
|
3330
|
+
scope,
|
|
3331
|
+
event
|
|
3332
|
+
} : {
|
|
3333
|
+
locale,
|
|
3334
|
+
event
|
|
3335
|
+
};
|
|
3336
|
+
}
|
|
3337
|
+
/**
|
|
3338
|
+
* The event's scope (`opts.scope`): `undefined` without one, `null` when the scope function
|
|
3339
|
+
* threw (logged once) — translated unscoped then, and not memoized.
|
|
3340
|
+
*/ function readScope(event) {
|
|
3341
|
+
const scoping = state.scoping;
|
|
3342
|
+
if (!scoping || scoping.translate !== state.translate) return;
|
|
3343
|
+
try {
|
|
3344
|
+
const { get } = scoping;
|
|
3345
|
+
const scope = (0, _wooksjs_event_core.tryGetCurrent)() === event ? get() : (0, _wooksjs_event_core.run)(event, get);
|
|
3346
|
+
return typeof scope === "string" ? scope : typeof scope === "number" && Number.isFinite(scope) ? String(scope) : void 0;
|
|
3347
|
+
} catch (error) {
|
|
3348
|
+
logOnce("scopeFailureLogged", event, "The translation scope threw — translating unscoped, without memoizing (logged once)", error);
|
|
3349
|
+
return null;
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
/** Whether `scope` gets memo keys: one of the first {@link MAX_SCOPES} of the generation. */ function admitted(scope) {
|
|
3353
|
+
if (state.admittedScopes?.generation !== state.generation) state.admittedScopes = {
|
|
3354
|
+
generation: state.generation,
|
|
3355
|
+
names: /* @__PURE__ */ new Set()
|
|
3356
|
+
};
|
|
3357
|
+
const { names } = state.admittedScopes;
|
|
3358
|
+
if (names.size < MAX_SCOPES) names.add(scope);
|
|
3359
|
+
return names.has(scope);
|
|
3360
|
+
}
|
|
3361
|
+
/** Logs a failure of the translator or the scope function once per `setTranslator`. */ function logOnce(flag, event, message, error) {
|
|
3362
|
+
if (!state[flag]) {
|
|
3363
|
+
state[flag] = true;
|
|
3364
|
+
(0, _wooksjs_event_core.useLogger)("i18n", event).error(message, error);
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3324
3367
|
/**
|
|
3325
3368
|
* Returns a translated copy of an error body (`{ message, code?, params?, errors? }`) in the
|
|
3326
3369
|
* event's locale — the body itself when there is no translation ({@link useTranslation}).
|
|
@@ -3332,9 +3375,9 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3332
3375
|
*
|
|
3333
3376
|
* `MoostHttp` applies it to every error body when it creates the HTTP app.
|
|
3334
3377
|
*/ function translateErrorBody(body, ctx) {
|
|
3335
|
-
const
|
|
3336
|
-
if (!
|
|
3337
|
-
const
|
|
3378
|
+
const event = ctx ?? (0, _wooksjs_event_core.current)();
|
|
3379
|
+
if (!state.translate || (0, _wooksjs_event_core.useLocale)(event).get() === void 0) return body;
|
|
3380
|
+
const t = useTranslate(event);
|
|
3338
3381
|
const source = Array.isArray(body.errors) ? body.errors : void 0;
|
|
3339
3382
|
const errors = source && translateEntries(source, t);
|
|
3340
3383
|
let message;
|
|
@@ -3361,10 +3404,7 @@ function mapTranslator(map) {
|
|
|
3361
3404
|
const out = translate(id, params, ctx);
|
|
3362
3405
|
return typeof out === "string" ? out : void 0;
|
|
3363
3406
|
} catch (error) {
|
|
3364
|
-
|
|
3365
|
-
state.failureLogged = true;
|
|
3366
|
-
(0, _wooksjs_event_core.useLogger)("i18n", ctx.event).error(`The translator threw for "${id}" — using the untranslated text (logged once)`, error);
|
|
3367
|
-
}
|
|
3407
|
+
logOnce("failureLogged", ctx.event, `The translator threw for "${id}" — using the untranslated text (logged once)`, error);
|
|
3368
3408
|
return;
|
|
3369
3409
|
}
|
|
3370
3410
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1771,10 +1771,15 @@ declare function defineInterceptor(def: TInterceptorDef, priority?: TInterceptor
|
|
|
1771
1771
|
*/
|
|
1772
1772
|
declare function definePipeFn<T extends TObject = TEmpty>(fn: TPipeFn<T>, priority?: TPipePriority): TPipeFn<T>;
|
|
1773
1773
|
|
|
1774
|
-
/** What a translator gets besides the text: the event's locale and the event itself. */
|
|
1774
|
+
/** What a translator gets besides the text: the event's locale, its scope and the event itself. */
|
|
1775
1775
|
interface TTranslateContext {
|
|
1776
1776
|
/** `useLocale().get()` of the event the text is translated for. */
|
|
1777
1777
|
locale: string | undefined;
|
|
1778
|
+
/**
|
|
1779
|
+
* The event's translation scope ({@link TTranslatorOptions.scope}) — e.g. a tenant whose
|
|
1780
|
+
* wording differs. `undefined`: the shared wording.
|
|
1781
|
+
*/
|
|
1782
|
+
scope?: string;
|
|
1778
1783
|
/** The event context — read anything else your policy needs from it. */
|
|
1779
1784
|
event: EventContext;
|
|
1780
1785
|
}
|
|
@@ -1792,6 +1797,23 @@ type TTranslate = (text: string, params: Record<string, unknown> | undefined, ct
|
|
|
1792
1797
|
* placeholders, filled with {@link formatMessage}.
|
|
1793
1798
|
*/
|
|
1794
1799
|
type TTranslations = Record<string, Record<string, string>>;
|
|
1800
|
+
/** The options of {@link setTranslator}. */
|
|
1801
|
+
interface TTranslatorOptions {
|
|
1802
|
+
/** The locales the app serves, the default first. For a map: its keys by default. */
|
|
1803
|
+
locales?: readonly string[];
|
|
1804
|
+
/**
|
|
1805
|
+
* The event's translation scope, for wording that differs by more than the locale (per
|
|
1806
|
+
* tenant, brand, user group, …). Called in the event's context each time a translation is
|
|
1807
|
+
* taken — keep it cheap. Its result is passed to the translator ({@link TTranslateContext.scope})
|
|
1808
|
+
* and partitions everything memoized per translation ({@link TTranslation.key}); a finite
|
|
1809
|
+
* number counts as its string, and `undefined` (or any other value) is the shared, unscoped
|
|
1810
|
+
* wording. The translator must return the same text for the same (id, params, locale, scope).
|
|
1811
|
+
*
|
|
1812
|
+
* Derive it from a validated value (the authenticated principal's tenant), never straight from
|
|
1813
|
+
* request input: only the first 32 scopes seen per generation get a {@link TTranslation.key}.
|
|
1814
|
+
*/
|
|
1815
|
+
scope?: () => string | number | undefined;
|
|
1816
|
+
}
|
|
1795
1817
|
/** `t(id, params?, fallback?)` — see {@link useTranslate}. */
|
|
1796
1818
|
type TTranslateFn = (id: string, params?: Record<string, unknown>, fallback?: string) => string;
|
|
1797
1819
|
/** The translation of one event's locale — see {@link useTranslation}. */
|
|
@@ -1799,9 +1821,17 @@ interface TTranslation {
|
|
|
1799
1821
|
/** The event's locale. */
|
|
1800
1822
|
locale: string;
|
|
1801
1823
|
/**
|
|
1802
|
-
*
|
|
1803
|
-
* {@link
|
|
1804
|
-
*
|
|
1824
|
+
* What to index memoized results by: the locale, plus the event's scope when it has one
|
|
1825
|
+
* ({@link TTranslatorOptions.scope}). Keep one entry per partition, replaced when
|
|
1826
|
+
* {@link TTranslation.key} changes.
|
|
1827
|
+
*/
|
|
1828
|
+
partition: string;
|
|
1829
|
+
/**
|
|
1830
|
+
* A memo key for anything derived from this translation: the locale, the scope (if any) and
|
|
1831
|
+
* the generation — changes with every {@link setTranslator} call and every
|
|
1832
|
+
* {@link registerMessages} call that adds or changes a template. `undefined` for a locale
|
|
1833
|
+
* outside the translator's `locales`, or a scope past the cap ({@link TTranslatorOptions.scope})
|
|
1834
|
+
* — don't memoize then.
|
|
1805
1835
|
*/
|
|
1806
1836
|
key: string | undefined;
|
|
1807
1837
|
/** {@link useTranslate}'s `t`, bound to this translation. */
|
|
@@ -1834,9 +1864,7 @@ interface TTranslation {
|
|
|
1834
1864
|
* )
|
|
1835
1865
|
* ```
|
|
1836
1866
|
*/
|
|
1837
|
-
declare function setTranslator(translate: TTranslate | TTranslations | undefined, opts?:
|
|
1838
|
-
locales?: readonly string[];
|
|
1839
|
-
}): void;
|
|
1867
|
+
declare function setTranslator(translate: TTranslate | TTranslations | undefined, opts?: TTranslatorOptions): void;
|
|
1840
1868
|
/** The registered translator (a map wrapped as a function), or `undefined`. */
|
|
1841
1869
|
declare function getTranslator(): TTranslate | undefined;
|
|
1842
1870
|
/** The locales of the registered translator, the default first (empty without a translator). */
|
|
@@ -1901,4 +1929,4 @@ declare function createLogger(opts?: Partial<TProstoLoggerOptions>): ProstoLogge
|
|
|
1901
1929
|
declare const loggerConsoleTransport: _prostojs_logger.TProstoLoggerTransportFn<any>;
|
|
1902
1930
|
|
|
1903
1931
|
export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, Locale, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, detachedKind, disposeInstances, forkEventContext, formatMessage, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, getTranslator, getTranslatorLocales, globalKey, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, registerMessages, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptOriginal, setInterceptResult, setOvertake, setTranslator, stampModuleIdentity, stampOnce, translateErrorBody, useControllerContext, useHandlerPaths, useInterceptOriginal, useInterceptResult, useOvertake, useScopeId, useTranslate, useTranslation, withControllerContext };
|
|
1904
|
-
export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TControllerRegistration, TControllersGroup, TDisposeError, TDisposeOptions, TDisposeResult, TEmpty, TForkEventContextOptions, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TIsolatedSlot, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostModuleIdentity, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives, TRegistryMergeOptions, TRunDetachedOptions, TTranslate, TTranslateContext, TTranslation, TTranslations, TWithControllerContextOptions };
|
|
1932
|
+
export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TControllerRegistration, TControllersGroup, TDisposeError, TDisposeOptions, TDisposeResult, TEmpty, TForkEventContextOptions, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TIsolatedSlot, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostModuleIdentity, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives, TRegistryMergeOptions, TRunDetachedOptions, TTranslate, TTranslateContext, TTranslation, TTranslations, TTranslatorOptions, TWithControllerContextOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -47,7 +47,7 @@ let stamped = false;
|
|
|
47
47
|
if (stamped) return;
|
|
48
48
|
stamped = true;
|
|
49
49
|
stampModuleIdentity({
|
|
50
|
-
version: "0.7.
|
|
50
|
+
version: "0.7.4",
|
|
51
51
|
path: typeof __filename === "string" ? __filename : import.meta.url
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -3186,6 +3186,7 @@ function _define_property(obj, key, value) {
|
|
|
3186
3186
|
var _globalThis, _STATE, _state, _state1, _state2, _state3, _state4;
|
|
3187
3187
|
const STATE = Symbol.for("moost.i18n");
|
|
3188
3188
|
const NO_LOCALES = Object.freeze([]);
|
|
3189
|
+
/** Distinct scopes given memo keys per generation: keeps every memo keyed by `key` bounded. */ const MAX_SCOPES = 32;
|
|
3189
3190
|
const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE] = {});
|
|
3190
3191
|
(_state = state).locales ?? (_state.locales = NO_LOCALES);
|
|
3191
3192
|
(_state1 = state).generation ?? (_state1.generation = 0);
|
|
@@ -3215,9 +3216,14 @@ const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE]
|
|
|
3215
3216
|
*/ function setTranslator(translate, opts) {
|
|
3216
3217
|
const isMap = typeof translate === "object";
|
|
3217
3218
|
state.translate = isMap ? mapTranslator(translate) : translate;
|
|
3219
|
+
state.scoping = opts?.scope && {
|
|
3220
|
+
translate: state.translate,
|
|
3221
|
+
get: opts.scope
|
|
3222
|
+
};
|
|
3218
3223
|
const locales = opts?.locales ?? (isMap ? Object.keys(translate) : void 0);
|
|
3219
3224
|
state.locales = translate && locales?.length ? Object.freeze([...locales]) : NO_LOCALES;
|
|
3220
3225
|
state.failureLogged = false;
|
|
3226
|
+
state.scopeFailureLogged = false;
|
|
3221
3227
|
newGeneration();
|
|
3222
3228
|
}
|
|
3223
3229
|
/** The registered translator (a map wrapped as a function), or `undefined`. */ function getTranslator() {
|
|
@@ -3243,7 +3249,7 @@ const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE]
|
|
|
3243
3249
|
}
|
|
3244
3250
|
if (changed) newGeneration();
|
|
3245
3251
|
}
|
|
3246
|
-
/**
|
|
3252
|
+
/** Drops everything derived from the translator and the templates. */ function newGeneration() {
|
|
3247
3253
|
state.generation++;
|
|
3248
3254
|
state.memo.clear();
|
|
3249
3255
|
}
|
|
@@ -3278,10 +3284,7 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3278
3284
|
let translateCtx;
|
|
3279
3285
|
return (id, params, fallback) => {
|
|
3280
3286
|
const translate = state.translate;
|
|
3281
|
-
return (translate ? callTranslator(translate, id, params, translateCtx ?? (translateCtx =
|
|
3282
|
-
locale: useLocale$1(event).get(),
|
|
3283
|
-
event
|
|
3284
|
-
})) : void 0) ?? untranslated(id, params, fallback);
|
|
3287
|
+
return (translate ? callTranslator(translate, id, params, translateCtx ?? (translateCtx = translateContext(event, useLocale$1(event).get(), readScope(event)))) : void 0) ?? untranslated(id, params, fallback);
|
|
3285
3288
|
};
|
|
3286
3289
|
}
|
|
3287
3290
|
/** `t`'s text without a translation: `fallback` as is, else the filled template (or id). */ function untranslated(id, params, fallback) {
|
|
@@ -3297,12 +3300,11 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3297
3300
|
const event = ctx ?? current$1();
|
|
3298
3301
|
const locale = useLocale$1(event).get();
|
|
3299
3302
|
if (locale === void 0) return;
|
|
3300
|
-
const
|
|
3301
|
-
|
|
3302
|
-
event
|
|
3303
|
-
};
|
|
3303
|
+
const scope = readScope(event);
|
|
3304
|
+
const translateCtx = translateContext(event, locale, scope);
|
|
3304
3305
|
const generation = state.generation;
|
|
3305
|
-
const
|
|
3306
|
+
const partition = typeof scope === "string" ? `${locale}:${scope}` : locale;
|
|
3307
|
+
const key = state.locales.includes(locale) && (scope === void 0 || scope !== null && admitted(scope)) ? `${generation}:${partition}` : void 0;
|
|
3306
3308
|
const t = (id, params, fallback) => callTranslator(translate, id, params, translateCtx) ?? untranslated(id, params, fallback);
|
|
3307
3309
|
const messages = () => {
|
|
3308
3310
|
if (key === void 0 || state.generation !== generation) return translateTemplates(translate, translateCtx);
|
|
@@ -3315,11 +3317,52 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3315
3317
|
};
|
|
3316
3318
|
return {
|
|
3317
3319
|
locale,
|
|
3320
|
+
partition,
|
|
3318
3321
|
key,
|
|
3319
3322
|
t,
|
|
3320
3323
|
messages
|
|
3321
3324
|
};
|
|
3322
3325
|
}
|
|
3326
|
+
function translateContext(event, locale, scope) {
|
|
3327
|
+
return typeof scope === "string" ? {
|
|
3328
|
+
locale,
|
|
3329
|
+
scope,
|
|
3330
|
+
event
|
|
3331
|
+
} : {
|
|
3332
|
+
locale,
|
|
3333
|
+
event
|
|
3334
|
+
};
|
|
3335
|
+
}
|
|
3336
|
+
/**
|
|
3337
|
+
* The event's scope (`opts.scope`): `undefined` without one, `null` when the scope function
|
|
3338
|
+
* threw (logged once) — translated unscoped then, and not memoized.
|
|
3339
|
+
*/ function readScope(event) {
|
|
3340
|
+
const scoping = state.scoping;
|
|
3341
|
+
if (!scoping || scoping.translate !== state.translate) return;
|
|
3342
|
+
try {
|
|
3343
|
+
const { get } = scoping;
|
|
3344
|
+
const scope = tryGetCurrent() === event ? get() : run$1(event, get);
|
|
3345
|
+
return typeof scope === "string" ? scope : typeof scope === "number" && Number.isFinite(scope) ? String(scope) : void 0;
|
|
3346
|
+
} catch (error) {
|
|
3347
|
+
logOnce("scopeFailureLogged", event, "The translation scope threw — translating unscoped, without memoizing (logged once)", error);
|
|
3348
|
+
return null;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
/** Whether `scope` gets memo keys: one of the first {@link MAX_SCOPES} of the generation. */ function admitted(scope) {
|
|
3352
|
+
if (state.admittedScopes?.generation !== state.generation) state.admittedScopes = {
|
|
3353
|
+
generation: state.generation,
|
|
3354
|
+
names: /* @__PURE__ */ new Set()
|
|
3355
|
+
};
|
|
3356
|
+
const { names } = state.admittedScopes;
|
|
3357
|
+
if (names.size < MAX_SCOPES) names.add(scope);
|
|
3358
|
+
return names.has(scope);
|
|
3359
|
+
}
|
|
3360
|
+
/** Logs a failure of the translator or the scope function once per `setTranslator`. */ function logOnce(flag, event, message, error) {
|
|
3361
|
+
if (!state[flag]) {
|
|
3362
|
+
state[flag] = true;
|
|
3363
|
+
useLogger$1("i18n", event).error(message, error);
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3323
3366
|
/**
|
|
3324
3367
|
* Returns a translated copy of an error body (`{ message, code?, params?, errors? }`) in the
|
|
3325
3368
|
* event's locale — the body itself when there is no translation ({@link useTranslation}).
|
|
@@ -3331,9 +3374,9 @@ const PLACEHOLDER = /\{(\w+)\}/g;
|
|
|
3331
3374
|
*
|
|
3332
3375
|
* `MoostHttp` applies it to every error body when it creates the HTTP app.
|
|
3333
3376
|
*/ function translateErrorBody(body, ctx) {
|
|
3334
|
-
const
|
|
3335
|
-
if (!
|
|
3336
|
-
const
|
|
3377
|
+
const event = ctx ?? current$1();
|
|
3378
|
+
if (!state.translate || useLocale$1(event).get() === void 0) return body;
|
|
3379
|
+
const t = useTranslate(event);
|
|
3337
3380
|
const source = Array.isArray(body.errors) ? body.errors : void 0;
|
|
3338
3381
|
const errors = source && translateEntries(source, t);
|
|
3339
3382
|
let message;
|
|
@@ -3360,10 +3403,7 @@ function mapTranslator(map) {
|
|
|
3360
3403
|
const out = translate(id, params, ctx);
|
|
3361
3404
|
return typeof out === "string" ? out : void 0;
|
|
3362
3405
|
} catch (error) {
|
|
3363
|
-
|
|
3364
|
-
state.failureLogged = true;
|
|
3365
|
-
useLogger$1("i18n", ctx.event).error(`The translator threw for "${id}" — using the untranslated text (logged once)`, error);
|
|
3366
|
-
}
|
|
3406
|
+
logOnce("failureLogged", ctx.event, `The translator threw for "${id}" — using the untranslated text (logged once)`, error);
|
|
3367
3407
|
return;
|
|
3368
3408
|
}
|
|
3369
3409
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moost",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "moost",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"composables",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@wooksjs/event-http": "^0.8.1",
|
|
50
50
|
"@wooksjs/http-body": "^0.8.1",
|
|
51
51
|
"vitest": "4.1.12",
|
|
52
|
-
"@moostjs/event-http": "^0.7.
|
|
52
|
+
"@moostjs/event-http": "^0.7.4"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"pub": "pnpm publish --access public",
|