Skip to content

Commit c328609

Browse files
authored
Merge pull request #151 from eemeli/data-model
Update data_model/ts_eemeli in experiments
2 parents 7aaf1da + 0e8396f commit c328609

File tree

2 files changed

+134
-65
lines changed

2 files changed

+134
-65
lines changed
Lines changed: 94 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// MF1: { gender, select, male{he} female{she} other{they} }
22
const genderSelect: Select = {
3-
select: [['gender']],
3+
select: [{ var_path: ['gender'] }],
44
cases: [
55
{ key: ['male'], value: ['he'] },
66
{ key: ['female'], value: ['she'] },
@@ -10,83 +10,124 @@ const genderSelect: Select = {
1010

1111
// MF1: { count, plural, one{a message} other{# messages} }
1212
const countPlural: Select = {
13-
select: [{ func: 'plural', args: [['count']] }],
13+
select: [{ func: 'plural', args: [{ var_path: ['count'] }] }],
1414
cases: [
1515
{ key: ['one'], value: ['a message'] },
1616
{
1717
key: ['other'],
18-
value: [{ func: 'number', args: [['count']] }, ' messages']
18+
value: [{ func: 'number', args: [{ var_path: ['count'] }] }, ' messages']
1919
}
2020
]
2121
}
2222

2323
const gameMessages: Resource = {
2424
id: 'game-messages',
2525
locale: 'en',
26-
messages: {
27-
monsters: {
28-
dinosaur: { indefinite: ['a Dinosaur'], plural: ['Dinosaurs'] },
29-
elephant: { indefinite: ['an Elephant'], plural: ['Elephants'] },
30-
ogre: { indefinite: ['an Ogre'], plural: ['Ogres'] },
31-
other: { indefinite: ['a Monster'], plural: ['Monsters'] }
32-
},
33-
'killed-by': [
34-
'You have been killed by ',
35-
{ msg: ['monsters', ['monster'], 'indefinite'] }
36-
],
37-
'kill-count': {
38-
select: [
39-
{ func: 'plural', args: [['monster-count']] },
40-
{ func: 'plural', args: [['dungeon-count']] }
41-
],
42-
cases: [
26+
entries: [
27+
{
28+
id: 'monsters',
29+
entries: [
30+
{
31+
id: 'dinosaur',
32+
entries: [
33+
{ id: 'indefinite', value: ['a Dinosaur'] },
34+
{ id: 'plural', value: ['Dinosaurs'] }
35+
]
36+
},
4337
{
44-
key: ['one'],
45-
value: [
46-
'You have killed ',
47-
{ msg: ['monsters', ['monster'], 'indefinite'] },
48-
'.'
38+
id: 'elephant',
39+
entries: [
40+
{ id: 'indefinite', value: ['an Elephant'] },
41+
{ id: 'plural', value: ['Elephants'] }
4942
]
5043
},
5144
{
52-
key: ['other', 'one'],
53-
value: [
54-
'You have killed ',
55-
{ func: 'number', args: [['monster-count']] },
56-
' ',
57-
{ msg: ['monsters', ['monster'], 'plural'] },
58-
' in one dungeon.'
45+
id: 'ogre',
46+
entries: [
47+
{ id: 'indefinite', value: ['an Ogre'] },
48+
{ id: 'plural', value: ['Ogres'] }
5949
]
6050
},
6151
{
62-
key: ['other', 'other'],
63-
value: [
64-
'You have killed ',
65-
{ func: 'number', args: [['monster-count']] },
66-
' ',
67-
{ msg: ['monsters', ['monster'], 'plural'] },
68-
' in ',
69-
{ func: 'number', args: [['dungeon-count']] },
70-
' dungeons.'
52+
id: 'other',
53+
entries: [
54+
{ id: 'indefinite', value: ['a Monster'] },
55+
{ id: 'plural', value: ['Monsters'] }
7156
]
7257
}
7358
]
59+
},
60+
{
61+
id: 'killed-by',
62+
value: [
63+
'You have been killed by ',
64+
{ msg_path: ['monsters', { var_path: ['monster'] }, 'indefinite'] }
65+
]
66+
},
67+
{
68+
id: 'kill-count',
69+
value: {
70+
select: [
71+
{ func: 'plural', args: [{ var_path: ['monster-count'] }] },
72+
{ func: 'plural', args: [{ var_path: ['dungeon-count'] }] }
73+
],
74+
cases: [
75+
{
76+
key: ['one'],
77+
value: [
78+
'You have killed ',
79+
{
80+
msg_path: ['monsters', { var_path: ['monster'] }, 'indefinite']
81+
},
82+
'.'
83+
]
84+
},
85+
{
86+
key: ['other', 'one'],
87+
value: [
88+
'You have killed ',
89+
{ func: 'number', args: [{ var_path: ['monster-count'] }] },
90+
' ',
91+
{ msg_path: ['monsters', { var_path: ['monster'] }, 'plural'] },
92+
' in one dungeon.'
93+
]
94+
},
95+
{
96+
key: ['other', 'other'],
97+
value: [
98+
'You have killed ',
99+
{ func: 'number', args: [{ var_path: ['monster-count'] }] },
100+
' ',
101+
{ msg_path: ['monsters', { var_path: ['monster'] }, 'plural'] },
102+
' in ',
103+
{ func: 'number', args: [{ var_path: ['dungeon-count'] }] },
104+
' dungeons.'
105+
]
106+
}
107+
]
108+
}
74109
}
75-
}
110+
]
76111
}
77112

78113
const extMessages: Resource = {
79114
id: 'remote-ref',
80115
locale: 'en',
81-
messages: {
82-
friend: [
83-
'Your friend has become ',
84-
{
85-
func: 'sparkle',
86-
args: [
87-
{ id: 'game-messages', msg: ['monsters', ['monster'], 'indefinite'] }
88-
]
89-
}
90-
]
91-
}
116+
entries: [
117+
{
118+
id: 'friend',
119+
value: [
120+
'Your friend has become ',
121+
{
122+
func: 'sparkle',
123+
args: [
124+
{
125+
res_id: 'game-messages',
126+
msg_path: ['monsters', { var_path: ['monster'] }, 'indefinite']
127+
}
128+
]
129+
}
130+
]
131+
}
132+
]
92133
}

experiments/data_model/ts_eemeli/data-model.d.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,36 @@
66
interface Resource {
77
id: string
88
locale: string
9-
messages: MessageSet
9+
entries: Entry[]
10+
meta?: Meta
11+
}
12+
13+
type Entry = Message | MessageSet
14+
15+
interface MessageSet {
16+
id: string
17+
entries: Entry[]
18+
meta?: Meta
1019
}
1120

1221
/**
13-
* Really this ought to be a Record, but TS only allows circular references for
14-
* a limited set of types.
22+
* Additional meta information amy be attached to most nodes. In common use,
23+
* this information is not required when formatting a message.
1524
*/
16-
type MessageSet = { [key in string]: Message | Select | MessageSet }
25+
interface Meta {
26+
comment?: string
27+
[key: string]: unknown
28+
}
1729

1830
/**
1931
* The string parts of a message represent fixed values, while placeholder
2032
* values are variable.
2133
*/
22-
type Message = Value[]
34+
interface Message {
35+
id: string
36+
value: Value[] | Select
37+
meta?: Meta
38+
}
2339

2440
/**
2541
* Select generalises the plural, selectordinal and select argument types of
@@ -32,7 +48,7 @@ type Message = Value[]
3248
*/
3349
interface Select {
3450
select: Value[]
35-
cases: Array<{ key: string[]; value: Message }>
51+
cases: Array<{ key: Literal[]; value: Value[]; meta?: Meta }>
3652
}
3753

3854
/**
@@ -61,7 +77,10 @@ type Literal = string | number
6177
* object value, so e.g. `['user', 'name']` would require something like
6278
* `{ name: 'Kat' }` as the value of the `'user'` scope variable.
6379
*/
64-
type VariableReference = string[]
80+
interface VariableReference {
81+
var_path: Path
82+
meta?: Meta
83+
}
6584

6685
/**
6786
* To resolve a FunctionReference, an externally defined function is called.
@@ -79,13 +98,14 @@ type VariableReference = string[]
7998
interface FunctionReference {
8099
func: string
81100
args: Value[]
82-
options?: Record<string, string | number | boolean>
101+
options?: Array<{ key: string; value: string | number | boolean }>
102+
meta?: Meta
83103
}
84104

85105
/**
86106
* A MessageReference is a pointer to a Message or a Select.
87107
*
88-
* If `id` is undefined, the message is sought in the current Resource.
108+
* If `resource` is undefined, the message is sought in the current Resource.
89109
* If it is set, it identifies the resource for the sought message.
90110
*
91111
* While `msg` has superficially the same type as a Message, all but the last
@@ -96,7 +116,15 @@ interface FunctionReference {
96116
* `scope` overrides values in the current scope when resolving the message.
97117
*/
98118
interface MessageReference {
99-
id?: string
100-
msg: Value[]
101-
scope?: Record<string, Value>
119+
res_id?: string
120+
msg_path: Path
121+
scope?: Scope[]
122+
meta?: Meta
102123
}
124+
125+
interface Scope {
126+
name: string
127+
value: Value | boolean | Scope
128+
}
129+
130+
type Path = Value[]

0 commit comments

Comments
 (0)