You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Formats message strings with number, date, plural, and select placeholders to create localized messages.
4
19
5
-
***Small.** Between 0.6 kilobytes and 1 kilobytes (minified and gzipped).
20
+
***Small.** Between 700 bytes and 1.3 kilobytes (minified and gzipped).
6
21
Zero dependencies.
7
-
***Fast.** Does absolute minimum amount of computations necessary.
22
+
***Fast.** Does absolute minimum amount of computations necessary. View [benchmarks](#benchmarks).
8
23
***Tree Shakable.** Includes separate global transformers config that can be omitted.
9
24
***Pipe syntax.** Transformer functions can customized and chained.
10
25
***View framework support.** Use React/Preact etc. components as transformers.
@@ -58,28 +73,28 @@ npm install messagepipe
58
73
└-message
59
74
```
60
75
61
-
In one `message` there can only be one `selector`, but there can be unlimited number of `pipes` with unlimited number of `arguments` in them. It is possible to build dynamic `selector` (meaning `message` can be inside it), but it is not possible to build dynamic `pipes` except for `argument values`.
76
+
In one [message](#message) there can only be one [selector](#selector), but there can be unlimited number of [pipes](#pipe) with unlimited number of [arguments](#argument) in them. It is possible to build dynamic [selector](#selector) (meaning [message](#message) can be inside it), but it is not possible to build dynamic [pipes](#pipe) except for [argument values](#argument).
62
77
63
78
So both of these are valid:
64
79
1.`"Hello {agents.{index}.fistName}"`;
65
80
2.`"{a} + {b} = {a | sum, sequence:{b}}"`.
66
81
_(Note: sum is a custom transformer in this case)_.
67
82
68
-
### `message`
69
-
Contains everything between `{` and `}` that in large includes 1 `selector` and n `pipes`.
83
+
### Message
84
+
Contains everything between `{` and `}` that in large includes 1 [selector](#selector) and n [pipes](#pipe).
70
85
71
-
### `selector`
86
+
### Selector
72
87
String value that points to value from given props object e.g.:
A combination of 1 `transformer` and n `arguments` e.g.:
78
93
-`"{name | capitalize}"`;
79
94
-`"{name | reverse | capitalize}"`;
80
95
-`"{a | sum, sequence:1, double}"`_(Note: argument "double" will pass `true` value to "sum" transformer)_.
81
96
82
-
### `transformer`
97
+
### Transformer
83
98
Function that can transform value that is being selected from given props.
84
99
85
100
Lets define "capitalize" transformer that would uppercase the first letter of any string:
@@ -99,7 +114,7 @@ const msgPipe = MessagePipe({
99
114
100
115
This would be valid use case for it: `"Greetings {name | capitalize}!"`.
101
116
102
-
### `argument`
117
+
### Argument
103
118
To allow more functionality, we can use arguments, that are passed to transformer function.
104
119
105
120
```ts
@@ -116,42 +131,119 @@ We can now use it like this:
116
131
We can stack any number of arguments separated by `,` (comma).
117
132
118
133
### Global transformers
134
+
There are number of already provided transformers, but they MUST be added to MessagePipe function when initiating. This is by design to help with tree shaking (although they don't contribute that much to package size, if there are additions in future, that won't hurt anyone).
119
135
120
136
### `defaultTransformers`
137
+
```ts
138
+
function defaultTransformers():MessagePipeTransformers
function intlTransformers(locale?: string): MessagePipeTransformers
158
+
```
159
+
160
+
#### number
161
+
Formatsnumbersusing [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat). All options are available as arguments in pipes.
Selectscorrecttexttoshowbasedon [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules). All options are available as arguments in pipes.
Formatsdateusing [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat). All options are available as arguments in pipes.
129
188
130
-
-#### number
131
-
@TODO: Write about this
189
+
```ts
190
+
const msg = compile('Todays date {now | date}')
132
191
133
-
-#### plural
134
-
@TODO: Write about this
192
+
msg({ now: new Date('1977-05-25') }) // "Todays date 25/05/1977"
193
+
```
135
194
136
-
-#### date
137
-
@TODO: Write about this
195
+
#### time
196
+
Formatstimeusing [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat). All options are available as arguments in pipes.
138
197
139
-
-#### time
140
-
@TODO: Write about this
198
+
```ts
199
+
const msg = compile('Currently it is {now | time}')
141
200
142
-
-#### relativeTime
143
-
@TODO: Write about this
201
+
msg({ now: new Date('1983-05-25 16:42') }) // "Currently it is 16:42:00"
202
+
```
144
203
145
204
## API
146
205
147
-
### @TODO: `MessagePipe`
148
-
#### @TODO: `compile`
206
+
### `MessagePipe`
207
+
Thisisthemainfunction that takes in all the transformers that will be available to all the messages.
149
208
150
-
#### @TODO: `compileRaw`
209
+
```ts
210
+
function MessagePipe(transformers?:MessagePipeTransformers): {
Now all the messages that get compiled from `messagePipe` can use this transformer like so `"{name | hello}"`.
225
+
226
+
#### `compile`
227
+
This is where given [message](#message) gets parsed and prepared for usage. It is very efficient compiler that does only 1 pass and prepares very tiny and performant function from it.
228
+
229
+
Given this message `"Hello {name | capitalize}!"`, compiler will output this function `(a) =>"Hello "+capitalize(a.name) +"!"` and that is the only thing that runs when executing it. No hidden performance penalties.
153
230
154
-
Works with React and Preact out of the box. Just swap out `compile` with `compileRaw` and good to go. This works because it returns raw array of values that was the output of selectors and transformers.
231
+
#### `compileRaw`
232
+
This is practically the same as [compile](#compile) but instead of it returning one string, it returns array of all of the things as a separate chunks so that this compiler can be used as part of React component for example.
233
+
234
+
So from the example that was before, the output of that message would be `(a) => ["Hello ", capitalize(a.name), "!"]`.
235
+
236
+
## Benchmarks
237
+
It is necessary for me that this library is as small and as fast as possible. Since this library compares directly with MessageFormat, I treated both as equal in benchmarks.
Works with React and Preact out of the box. Just swap out [`compile`](#compile) with [`compileRaw`](#compile) and good to go. This works because it returns raw array of values that was the output of selectors and transformers.
Since we used `compileRaw`, library would output something like this: `['Hello ', [ReactElement], '!']`.
266
+
Since we used [compileRaw](#compileraw), library would output something like this: `['Hello ', [ReactElement], '!']`.
175
267
176
268
This will work with any kind of framework or custom library.
177
269
178
270
# Motivation
179
271
I was used to messageformat being the go to for this sort of stuff, but it has big flaws in the spec and library maintainers obviously wouldn't want to deviate from it. So the goal for messagepipe was to create NEW spec that solves all of the issues with it + must be faster & smaller.
180
272
181
-
One immediate flaw that messagepipe solves is ability to select nested values.
0 commit comments