saykit 0.11.0 → 0.11.1
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.d.mts +26 -2
- package/dist/index.mjs +16 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -70,6 +70,20 @@ declare namespace View {
|
|
|
70
70
|
}) & {
|
|
71
71
|
[match: string | number]: unknown;
|
|
72
72
|
};
|
|
73
|
+
interface Options {
|
|
74
|
+
/**
|
|
75
|
+
* Whether a substituted value is wrapped in Unicode bidi isolation marks,
|
|
76
|
+
* U+2068 and U+2069, so right-to-left text cannot reorder the sentence
|
|
77
|
+
* around it.
|
|
78
|
+
*
|
|
79
|
+
* `'none'` leaves values byte-for-byte as given, for output that is parsed
|
|
80
|
+
* after it is formatted: a Discord mention such as `<#123>` stops being
|
|
81
|
+
* one once the id inside it is isolated.
|
|
82
|
+
*
|
|
83
|
+
* @default 'default'
|
|
84
|
+
*/
|
|
85
|
+
bidiIsolation?: 'default' | 'none';
|
|
86
|
+
}
|
|
73
87
|
}
|
|
74
88
|
/**
|
|
75
89
|
* One locale, bound to the messages it formats against.
|
|
@@ -115,6 +129,11 @@ interface View<Locale extends string = string> {
|
|
|
115
129
|
readonly locale: Locale;
|
|
116
130
|
/** The messages this view formats against. */
|
|
117
131
|
readonly messages: Readonly<View.Messages>;
|
|
132
|
+
/**
|
|
133
|
+
* How this view formats its messages. Plain data, so it can cross a
|
|
134
|
+
* server/client boundary alongside {@link locale} and {@link messages}.
|
|
135
|
+
*/
|
|
136
|
+
readonly options: Readonly<View.Options>;
|
|
118
137
|
/**
|
|
119
138
|
* Format the message a descriptor names, or the message it carries.
|
|
120
139
|
*
|
|
@@ -252,9 +271,10 @@ interface View<Locale extends string = string> {
|
|
|
252
271
|
*
|
|
253
272
|
* @param locale The locale to bind to
|
|
254
273
|
* @param messages The messages this view formats against
|
|
274
|
+
* @param options How this view formats its messages
|
|
255
275
|
* @returns The view
|
|
256
276
|
*/
|
|
257
|
-
declare function createView<Locale extends string>(locale: Locale, messages: View.Messages): View<Locale>;
|
|
277
|
+
declare function createView<Locale extends string>(locale: Locale, messages: View.Messages, options?: View.Options): View<Locale>;
|
|
258
278
|
//#endregion
|
|
259
279
|
//#region src/catalogue.d.ts
|
|
260
280
|
declare namespace Catalogue {
|
|
@@ -281,6 +301,8 @@ declare namespace Catalogue {
|
|
|
281
301
|
type Produced = View.Messages | {
|
|
282
302
|
default: View.Messages;
|
|
283
303
|
};
|
|
304
|
+
/** How every view the catalogue hands back formats its messages. */
|
|
305
|
+
type Options = View.Options;
|
|
284
306
|
}
|
|
285
307
|
/**
|
|
286
308
|
* Everything an application knows how to say: its locales and where their
|
|
@@ -365,9 +387,11 @@ interface Catalogue<Locale extends string = string> {
|
|
|
365
387
|
* @param messages Where each locale's messages come from, keyed by locale. The
|
|
366
388
|
* keys are the catalogue's locales, in the order they are written, and the
|
|
367
389
|
* first of them is the default locale
|
|
390
|
+
* @param options How every view the catalogue hands back formats its
|
|
391
|
+
* messages, such as `{ bidiIsolation: 'none' }`
|
|
368
392
|
* @returns The catalogue
|
|
369
393
|
*/
|
|
370
|
-
declare function createCatalogue<const Locale extends string = string>(messages: Record<Locale, Catalogue.Source
|
|
394
|
+
declare function createCatalogue<const Locale extends string = string>(messages: Record<Locale, Catalogue.Source>, options?: Catalogue.Options): Catalogue<Locale>;
|
|
371
395
|
//#endregion
|
|
372
396
|
//#region src/store.d.ts
|
|
373
397
|
declare namespace Store {
|
package/dist/index.mjs
CHANGED
|
@@ -420,8 +420,11 @@ const functions = {
|
|
|
420
420
|
};
|
|
421
421
|
//#endregion
|
|
422
422
|
//#region src/messageformat/index.ts
|
|
423
|
-
function compile(locale, source) {
|
|
424
|
-
return new MessageFormat(locale, toMessage(parse(source)), {
|
|
423
|
+
function compile(locale, source, options) {
|
|
424
|
+
return new MessageFormat(locale, toMessage(parse(source)), {
|
|
425
|
+
...options,
|
|
426
|
+
functions
|
|
427
|
+
});
|
|
425
428
|
}
|
|
426
429
|
//#endregion
|
|
427
430
|
//#region src/view.ts
|
|
@@ -431,7 +434,9 @@ function resolveDescriptorValues(descriptor) {
|
|
|
431
434
|
function macro(name) {
|
|
432
435
|
throw new Error(`'say.${name}' is a macro and must be used with the relevant saykit plugin`);
|
|
433
436
|
}
|
|
434
|
-
function createView(locale, messages) {
|
|
437
|
+
function createView(locale, messages, options = {}) {
|
|
438
|
+
const { bidiIsolation } = options;
|
|
439
|
+
const ownOptions = Object.freeze(bidiIsolation ? { bidiIsolation } : {});
|
|
435
440
|
const own = Object.freeze({ ...messages });
|
|
436
441
|
const formats = /* @__PURE__ */ new Map();
|
|
437
442
|
const say = (() => {
|
|
@@ -441,7 +446,7 @@ function createView(locale, messages) {
|
|
|
441
446
|
const { id, message = own[id] } = descriptor;
|
|
442
447
|
if (typeof message !== "string") throw new Error(`Message for ${id} is not a string`);
|
|
443
448
|
let format = formats.get(message);
|
|
444
|
-
if (!format) formats.set(message, format = compile(locale, message));
|
|
449
|
+
if (!format) formats.set(message, format = compile(locale, message, { bidiIsolation }));
|
|
445
450
|
return String(format.format(resolveDescriptorValues(descriptor)));
|
|
446
451
|
}
|
|
447
452
|
return Object.freeze(Object.defineProperties(say, {
|
|
@@ -453,6 +458,10 @@ function createView(locale, messages) {
|
|
|
453
458
|
value: own,
|
|
454
459
|
enumerable: true
|
|
455
460
|
},
|
|
461
|
+
options: {
|
|
462
|
+
value: ownOptions,
|
|
463
|
+
enumerable: true
|
|
464
|
+
},
|
|
456
465
|
call: { value: call },
|
|
457
466
|
plural: { value: () => macro("plural") },
|
|
458
467
|
ordinal: { value: () => macro("ordinal") },
|
|
@@ -465,7 +474,8 @@ function createView(locale, messages) {
|
|
|
465
474
|
}
|
|
466
475
|
//#endregion
|
|
467
476
|
//#region src/catalogue.ts
|
|
468
|
-
function createCatalogue(messages) {
|
|
477
|
+
function createCatalogue(messages, options = {}) {
|
|
478
|
+
const { bidiIsolation } = options;
|
|
469
479
|
const sources = Object.assign(Object.create(null), messages);
|
|
470
480
|
const keys = Object.freeze(Object.keys(sources));
|
|
471
481
|
if (keys.length === 0) throw new Error("A catalogue needs at least one locale, none were given");
|
|
@@ -484,7 +494,7 @@ function createCatalogue(messages) {
|
|
|
484
494
|
const messages = store.get(locale);
|
|
485
495
|
if (!messages) throw new Error(typeof sources[locale] === "function" ? `Messages for locale '${locale}' have not been loaded yet` : `No messages for locale '${locale}'`);
|
|
486
496
|
let view = views.get(locale);
|
|
487
|
-
if (!view) views.set(locale, view = createView(locale, messages));
|
|
497
|
+
if (!view) views.set(locale, view = createView(locale, messages, { bidiIsolation }));
|
|
488
498
|
return view;
|
|
489
499
|
},
|
|
490
500
|
loaded(locale) {
|