pronouny 0.5.0 → 1.0.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.
Files changed (76) hide show
  1. package/README.md +225 -79
  2. package/lib/cjs/Pronoun.d.ts +55 -0
  3. package/lib/cjs/Pronoun.d.ts.map +1 -0
  4. package/lib/cjs/Pronoun.js +109 -0
  5. package/lib/cjs/Pronoun.js.map +1 -0
  6. package/lib/cjs/PronounSet.d.ts +70 -0
  7. package/lib/cjs/PronounSet.d.ts.map +1 -0
  8. package/lib/cjs/PronounSet.js +126 -0
  9. package/lib/cjs/PronounSet.js.map +1 -0
  10. package/lib/cjs/Pronouny.d.ts +91 -0
  11. package/lib/cjs/Pronouny.d.ts.map +1 -0
  12. package/lib/cjs/Pronouny.js +171 -0
  13. package/lib/cjs/Pronouny.js.map +1 -0
  14. package/lib/cjs/defaults.d.ts +13 -0
  15. package/lib/cjs/defaults.d.ts.map +1 -0
  16. package/lib/cjs/defaults.js +65 -0
  17. package/lib/cjs/defaults.js.map +1 -0
  18. package/lib/cjs/errors.d.ts +20 -0
  19. package/lib/cjs/errors.d.ts.map +1 -0
  20. package/lib/cjs/errors.js +29 -0
  21. package/lib/cjs/errors.js.map +1 -0
  22. package/lib/cjs/index.d.ts +24 -341
  23. package/lib/cjs/index.d.ts.map +1 -0
  24. package/lib/cjs/index.js +32 -639
  25. package/lib/cjs/index.js.map +1 -0
  26. package/lib/cjs/package.json +3 -0
  27. package/lib/cjs/template.d.ts +26 -0
  28. package/lib/cjs/template.d.ts.map +1 -0
  29. package/lib/cjs/template.js +46 -0
  30. package/lib/cjs/template.js.map +1 -0
  31. package/lib/cjs/types.d.ts +93 -0
  32. package/lib/cjs/types.d.ts.map +1 -0
  33. package/lib/cjs/types.js +48 -0
  34. package/lib/cjs/types.js.map +1 -0
  35. package/lib/cjs/utils.d.ts +24 -0
  36. package/lib/cjs/utils.d.ts.map +1 -0
  37. package/lib/cjs/utils.js +45 -0
  38. package/lib/cjs/utils.js.map +1 -0
  39. package/lib/esm/Pronoun.d.ts +55 -0
  40. package/lib/esm/Pronoun.d.ts.map +1 -0
  41. package/lib/esm/Pronoun.js +104 -0
  42. package/lib/esm/Pronoun.js.map +1 -0
  43. package/lib/esm/PronounSet.d.ts +70 -0
  44. package/lib/esm/PronounSet.d.ts.map +1 -0
  45. package/lib/esm/PronounSet.js +122 -0
  46. package/lib/esm/PronounSet.js.map +1 -0
  47. package/lib/esm/Pronouny.d.ts +91 -0
  48. package/lib/esm/Pronouny.d.ts.map +1 -0
  49. package/lib/esm/Pronouny.js +168 -0
  50. package/lib/esm/Pronouny.js.map +1 -0
  51. package/lib/esm/defaults.d.ts +13 -0
  52. package/lib/esm/defaults.d.ts.map +1 -0
  53. package/lib/esm/defaults.js +62 -0
  54. package/lib/esm/defaults.js.map +1 -0
  55. package/lib/esm/errors.d.ts +20 -0
  56. package/lib/esm/errors.d.ts.map +1 -0
  57. package/lib/esm/errors.js +25 -0
  58. package/lib/esm/errors.js.map +1 -0
  59. package/lib/esm/index.d.ts +24 -341
  60. package/lib/esm/index.d.ts.map +1 -0
  61. package/lib/esm/index.js +22 -637
  62. package/lib/esm/index.js.map +1 -0
  63. package/lib/esm/package.json +3 -0
  64. package/lib/esm/template.d.ts +26 -0
  65. package/lib/esm/template.d.ts.map +1 -0
  66. package/lib/esm/template.js +43 -0
  67. package/lib/esm/template.js.map +1 -0
  68. package/lib/esm/types.d.ts +93 -0
  69. package/lib/esm/types.d.ts.map +1 -0
  70. package/lib/esm/types.js +44 -0
  71. package/lib/esm/types.js.map +1 -0
  72. package/lib/esm/utils.d.ts +24 -0
  73. package/lib/esm/utils.d.ts.map +1 -0
  74. package/lib/esm/utils.js +38 -0
  75. package/lib/esm/utils.js.map +1 -0
  76. package/package.json +19 -4
package/README.md CHANGED
@@ -1,129 +1,275 @@
1
1
  # Pronouny
2
2
 
3
- **Pronouny** is a typed library intended to make programmatically resolving English pronouns easier.
3
+ **Pronouny** is a small, typed library that makes programmatically resolving English pronouns easy. It ships as both ESM and CommonJS, has zero runtime dependencies, and is designed to be extended.
4
4
 
5
5
  ## Installation
6
6
 
7
- To install, simply run `npm install pronouny`.
7
+ ```sh
8
+ npm install pronouny
9
+ ```
8
10
 
9
- ## Usage
11
+ ## Quick start
10
12
 
11
13
  ```ts
12
- // Single import
13
14
  import Pronouny from "pronouny";
14
15
 
15
- // Create a new instance of Pronouny. All config is optional.
16
- // Below are defaults.
16
+ const p = new Pronouny();
17
+
18
+ const vayne = {
19
+ username: "vaynegarden",
20
+ pronouns: p.set("she/they"),
21
+ };
22
+
23
+ console.log(vayne.pronouns.parse`${vayne.username} updated ${"their"} status.`);
24
+ // "vaynegarden updated her status." or "...their status.", chosen
25
+ // consistently for the whole sentence.
26
+ ```
27
+
28
+ ## Concepts
29
+
30
+ Pronouny has three classes:
31
+
32
+ | Class | What it is |
33
+ | ---------------- | ------------------------------------------------------------------- |
34
+ | **`Pronouny`** | The resolver. Registers pronouns and turns strings into `Pronoun`s. |
35
+ | **`Pronoun`** | A single pronoun with all five grammatical forms. |
36
+ | **`PronounSet`** | An ordered set of `Pronoun`s for one entity (e.g. `she/they`). |
37
+
38
+ Every pronoun has five **forms**:
39
+
40
+ | Form | Example (`she`) | Aliases accepted on input |
41
+ | ---------------------- | --------------- | ------------------------- |
42
+ | `subject` | she | |
43
+ | `object` | her | |
44
+ | `possessive` | hers | |
45
+ | `possessiveDeterminer` | her | `possessiveAdjective` |
46
+ | `reflexive` | herself | `intensive` |
47
+
48
+ ## Configuration
49
+
50
+ All configuration is optional. The defaults are shown below, and any
51
+ option can be overridden per call by passing a partial config as the
52
+ last argument to most methods.
53
+
54
+ ```ts
17
55
  const p = new Pronouny({
18
- // Will default to failing quietly into "they".
56
+ // Recoverable errors resolve to a fallback instead of throwing.
19
57
  failQuietly: true,
20
58
 
21
- // Will default to only querying the first subject
22
- // pronoun to limit scope. Set to "true" to force
23
- // recursive search.
59
+ // resolve() only matches ids/subject forms. Set true to match any form.
24
60
  deepSearch: false,
25
61
 
26
- // Will default to using random pronouns in arrays.
27
- // Set to false to force using 0 index.
62
+ // Pick forms/pronouns at random. Set false to always use the first.
28
63
  useRandom: true,
29
64
 
30
- // Will default to using "they" as a fallback pronoun.
65
+ // The id used whenever resolution fails quietly.
31
66
  fallbackPronoun: "they",
32
67
  });
68
+ ```
69
+
70
+ Pronouny ships with `he`, `she`, `they`, `it`, `you`, `we`, and `i`
71
+ registered by default.
72
+
73
+ ## Usage
74
+
75
+ ### Adding and removing pronouns
76
+
77
+ ```ts
78
+ // Register a pronoun under a unique id. A form may be a single string
79
+ // or an array of accepted spellings.
80
+ const ze = p.add("ze", {
81
+ subject: "ze",
82
+ object: "hir",
83
+ possessive: "hirs",
84
+ possessiveDeterminer: "hir",
85
+ reflexive: "hirself",
86
+ });
33
87
 
34
- // Create a new Pronoun object using Pronouny.new()
35
- const pronounZe: Pronoun = p.new(
36
- {
37
- subject: "ze",
38
- object: "hir",
39
- possessive: "hirs",
40
- psAdjective: "hir",
41
- reflexive: "hirself",
42
- },
43
- false
44
- );
88
+ // Because ids are explicit, two pronouns can share a subject form —
89
+ // e.g. a plural and a singular "they":
90
+ p.add("they-singular", {
91
+ subject: "they",
92
+ object: "them",
93
+ possessive: "theirs",
94
+ possessiveDeterminer: "their",
95
+ reflexive: "themself",
96
+ });
45
97
 
46
- // .new() will automatically add new Pronouns to its
47
- // validation map. however, if you want to do so manually,
48
- // you can do it with Pronouny.add().
49
- p.add(pronounZe);
98
+ // Remove a pronoun by id.
99
+ p.remove("it");
100
+ ```
50
101
 
51
- // .remove() also works;
52
- p.remove(p.resolve("I"));
53
- // this deletes the "I" pronoun from the map.
102
+ ### Resolving and identifying
54
103
 
55
- // Methods are chainable so you can reach the Pronoun class.
56
- p.add(pronounZe).set("he/they").use().subject();
57
- // ^Pronouny ^PronounSet ^Pronoun ^string
104
+ ```ts
105
+ p.resolve("she").id; // "she"
58
106
 
59
- // Instantiate a set of pronouns using Pronouny.set().
60
- const vayne = {
61
- username: "vaynegarden",
62
- pronouns: p.set("she/ze/they"),
63
- };
64
- // from there, you can use `[PronounSet].use()` to get a random `Pronoun`.
107
+ // Shallow resolution (default) only matches ids and subject forms, so
108
+ // "him" falls back to "they":
109
+ p.resolve("him").id; // "they"
65
110
 
66
- // Resolve the pronouns in your app by referencing the form
67
- // that you need. There's `subject`, `object`, `possessive`,
68
- // `psAdjective`, and `reflexive`.
69
- console.log(
70
- `${vayne.username} has updated ${vayne.pronouns.psAdjective()} status.`
71
- );
72
- // This returns "vaynegarden updated her status", "vaynegarden
73
- // updated hir status", or "vaynegarden updated their status",
74
- // selected randomly among the three.
75
-
76
- // Alternatively, you can use the `parse()` template string method
77
- // to parse a string with pronouns and write in reasonably natural syntax.
78
- // This functionality will be updated more in the future.
79
- console.log(
80
- vayne.pronouns.parse`${vayne.username} has updated ${"her"} status.`
111
+ // Deep resolution matches any form:
112
+ p.resolve("him", { deepSearch: true }).id; // "he"
113
+
114
+ // identify() reports which form a word is, or undefined:
115
+ p.identify("her"); // "object"
116
+ p.identify("their"); // "possessiveDeterminer"
117
+ p.identify("banana"); // undefined
118
+ ```
119
+
120
+ ### Getting a specific form
121
+
122
+ Use `.as(form)` on a `Pronoun`, or on a `PronounSet` to pick one member
123
+ first.
124
+
125
+ ```ts
126
+ const they = p.resolve("they");
127
+ they.as("subject"); // "they"
128
+ they.as("possessiveDeterminer"); // "their"
129
+ they.as("intensive"); // alias of "reflexive"
130
+
131
+ // A PronounSet picks a member (per config) then returns the form:
132
+ p.set("she/they").as("object"); // "her" or "them"
133
+ ```
134
+
135
+ ### Template parsing
136
+
137
+ `parse` is a tagged-template helper. Interpolated pronoun words are
138
+ rewritten into the correct form and capitalisation is preserved;
139
+ everything else is left untouched.
140
+
141
+ On a `Pronoun`, every substitution uses that pronoun. On a `PronounSet`,
142
+ each substitution independently draws a pronoun from the set (per the
143
+ `useRandom` config), so a multi-pronoun set is distributed across the
144
+ string:
145
+
146
+ ```ts
147
+ const pronouns = p.set("she/they");
148
+
149
+ pronouns.parse`${"They"} lost ${"their"} keys — help ${"them"}!`;
150
+ // e.g. "She lost their keys — help them!" — each slot is drawn from the set.
151
+ ```
152
+
153
+ Set `useRandom: false` if you want every slot to use the first member of
154
+ the set instead.
155
+
156
+ ## Error handling
157
+
158
+ When `failQuietly` is `false`, recoverable problems throw a typed
159
+ [`PnyError`](src/errors.ts) instead of falling back:
160
+
161
+ ```ts
162
+ import Pronouny, { PnyError } from "pronouny";
163
+
164
+ const strict = new Pronouny({ failQuietly: false });
165
+
166
+ try {
167
+ strict.resolve("notapronoun");
168
+ } catch (err) {
169
+ if (err instanceof PnyError) {
170
+ console.error(err.type); // "PronounResolutionError"
171
+ }
172
+ }
173
+ ```
174
+
175
+ `PnyError` extends the native `Error`, so it works with normal
176
+ `try`/`catch` and `instanceof`.
177
+
178
+ ## Extending the defaults
179
+
180
+ Pass your own pronoun map as the second constructor argument to replace
181
+ the built-ins entirely:
182
+
183
+ ```ts
184
+ import Pronouny, { DEFAULT_PRONOUNS } from "pronouny";
185
+
186
+ // Start from the defaults and add to them.
187
+ const p = new Pronouny(
188
+ {},
189
+ {
190
+ ...DEFAULT_PRONOUNS,
191
+ xe: {
192
+ subject: "xe",
193
+ object: "xem",
194
+ possessive: "xyrs",
195
+ possessiveDeterminer: "xyr",
196
+ reflexive: "xemself",
197
+ },
198
+ },
81
199
  );
82
- // Returns the same as above.
200
+ ```
201
+
202
+ ## Development
203
+
204
+ ```sh
205
+ npm install
206
+ npm test # run the Jest suite
207
+ npm run build # emit ESM + CJS + type declarations to lib/
83
208
  ```
84
209
 
85
210
  ## Changelog
86
211
 
212
+ ### v1.0.0
213
+
214
+ - **Rewritten as a modular, multi-file package** with a proper dual
215
+ ESM/CJS build, type declarations, and an `exports` map.
216
+ - **Bug fixes:**
217
+ - Per-call config no longer mutates the shared instance config.
218
+ - Random selection and index bounds now reach the last element and
219
+ no longer read out of bounds.
220
+ - `deepSearch` now actually performs a deep search.
221
+ - `parse()` compares words case-insensitively, so capitalised
222
+ non-pronoun words are left alone.
223
+ - **Performance:** resolution and identification are backed by
224
+ hash-map indexes (O(1)) instead of linear scans.
225
+ - **Errors:** `PnyError` now extends the native `Error` and is only
226
+ thrown when `failQuietly` is disabled (no more unconditional
227
+ `console.error`).
228
+ - Pronouns are registered under explicit ids, so multiple pronouns can
229
+ share the same subject form.
230
+ - Added `it` to the default pronouns and `identify()`, `has()`,
231
+ `get()`, and `list()` to `Pronouny`.
232
+
87
233
  ### v0.5.0
88
234
 
89
- - Added `parse()` method to `Pronoun` and `PronounSet` to allow for parsing of strings into their correct pronoun forms.
90
- - Added optional `resolver` property to `Pronoun`s to allow retracing to related Pronouny instance.
91
- - Added `identify()` method to `Pronouny` to allow for identification for type of pronouns.
235
+ - Added `parse()` method to `Pronoun` and `PronounSet` to allow for parsing of strings into their correct pronoun forms.
236
+ - Added optional `resolver` property to `Pronoun`s to allow retracing to related Pronouny instance.
237
+ - Added `identify()` method to `Pronouny` to allow for identification for type of pronouns.
92
238
 
93
239
  ### v0.4.0
94
240
 
95
- - Optimized `forEach()` calls to use `for` loops instead.
96
- - Added `fallbackPronoun` option to allow for configuration of pronoun to use in case of quiet failure states.
97
- - Removed redundant `set` parameter from `[PronounSet].remove()` calls.
241
+ - Optimized `forEach()` calls to use `for` loops instead.
242
+ - Added `fallbackPronoun` option to allow for configuration of pronoun to use in case of quiet failure states.
243
+ - Removed redundant `set` parameter from `[PronounSet].remove()` calls.
98
244
 
99
245
  ### v0.3.1
100
246
 
101
- - Added documentation.
102
- - Reordered `failQuietly` and `useRandom` on `Pronoun`.
103
- - Tested and fixed examples.
247
+ - Added documentation.
248
+ - Reordered `failQuietly` and `useRandom` on `Pronoun`.
249
+ - Tested and fixed examples.
104
250
 
105
251
  ### v0.3.0
106
252
 
107
- - Rewritten to consolidate functionality into a single default export `Pronouny`.
108
- - Includes "we", "you", and "I" pronouns by default.
109
- - Added a config object so you can decide on error handling globally.
110
- - All methods are now chainable for ease of use.
253
+ - Rewritten to consolidate functionality into a single default export `Pronouny`.
254
+ - Includes "we", "you", and "I" pronouns by default.
255
+ - Added a config object so you can decide on error handling globally.
256
+ - All methods are now chainable for ease of use.
111
257
 
112
258
  ### v0.2.0
113
259
 
114
- - Now fails silently when trying to resolve pronouns that don't exist or indexing out of bounds.
115
- - Implementation of `PronounSet` class changed to Set from Array to prevent duplicate pronouns.
116
- - added `get()` method to `PronounSet` class to retrieve a random Pronoun object.
117
- - Added `add()` and `remove()` on `PronounSet`
260
+ - Now fails silently when trying to resolve pronouns that don't exist or indexing out of bounds.
261
+ - Implementation of `PronounSet` class changed to Set from Array to prevent duplicate pronouns.
262
+ - added `get()` method to `PronounSet` class to retrieve a random Pronoun object.
263
+ - Added `add()` and `remove()` on `PronounSet`
118
264
 
119
265
  ### v0.1.2
120
266
 
121
- - Initial release.
267
+ - Initial release.
122
268
 
123
269
  ## TODO
124
270
 
125
- - [x] Consolidate implementation into one general-use class.
126
- - [x] Add global configuration for pronoun use.
127
- - [ ] Use more performant data structures.
128
- - [ ] Cleaner error handling.
129
- - [ ] Unique pronoun identifiers to allow for pronouns with the same first subject pronoun to have multiple forms.
271
+ - [x] Consolidate implementation into one general-use class.
272
+ - [x] Add global configuration for pronoun use.
273
+ - [x] Use more performant data structures. _(hash-map indexes for O(1) resolve/identify)_
274
+ - [x] Cleaner error handling. _(typed `PnyError extends Error`, thrown only when not failing quietly)_
275
+ - [x] Unique pronoun identifiers to allow for pronouns with the same first subject pronoun to have multiple forms. _(pronouns are keyed by explicit `id`)_
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The {@link Pronoun} class.
3
+ * @module
4
+ */
5
+ import type Pronouny from "./Pronouny.js";
6
+ import { type PartialConfig, type PronounComponents, type PronounFormInput, type PronounInput } from "./types.js";
7
+ /**
8
+ * Normalise a loose {@link PronounInput} into strict
9
+ * {@link PronounComponents}, accepting single strings or arrays and
10
+ * legacy alias keys. Throws a {@link PnyError} if any form is missing.
11
+ */
12
+ export declare function normalizeComponents(id: string, input: PronounInput): PronounComponents;
13
+ /**
14
+ * # `Pronoun`
15
+ * A single pronoun with all five grammatical {@link PronounForm forms}.
16
+ * Each form may hold several accepted spellings.
17
+ *
18
+ * Create pronouns through {@link Pronouny.add} so they are registered
19
+ * for resolution, or construct one directly for standalone use.
20
+ */
21
+ export declare class Pronoun {
22
+ /** Unique identifier within a {@link Pronouny} instance. */
23
+ readonly id: string;
24
+ /** The normalised forms of this pronoun. */
25
+ readonly components: PronounComponents;
26
+ /** The Pronouny instance this pronoun belongs to, if any. */
27
+ resolver?: Pronouny;
28
+ constructor(id: string, input: PronounInput, resolver?: Pronouny);
29
+ private get config();
30
+ /**
31
+ * Retrieve a single surface string for the requested grammatical
32
+ * form.
33
+ *
34
+ * @param form The form to retrieve. Accepts aliases such as
35
+ * `possessiveAdjective` and `intensive`. Defaults to
36
+ * `subject`.
37
+ * @param index Retrieve the `index`-th spelling of the form. When
38
+ * `-1` (default) a spelling is chosen according to the
39
+ * `useRandom` config.
40
+ * @param config Optional per-call config overrides.
41
+ */
42
+ as(form?: PronounFormInput, index?: number, config?: PartialConfig): string;
43
+ /**
44
+ * Tagged-template helper. Interpolated pronoun words are rewritten
45
+ * to the matching form of *this* pronoun, preserving capitalisation.
46
+ * Non-pronoun values pass through unchanged.
47
+ *
48
+ * ```ts
49
+ * he.parse`${"They"} updated ${"their"} status.`;
50
+ * // "He updated his status."
51
+ * ```
52
+ */
53
+ parse(strings: TemplateStringsArray, ...values: unknown[]): string;
54
+ }
55
+ //# sourceMappingURL=Pronoun.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pronoun.d.ts","sourceRoot":"","sources":["../../src/Pronoun.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAG1C,OAAO,EAIN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,MAAM,YAAY,CAAC;AAGpB;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACjB,iBAAiB,CAsCnB;AAED;;;;;;;GAOG;AACH,qBAAa,OAAO;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IAEvC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,QAAQ,CAAC;gBAER,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAMhE,OAAO,KAAK,MAAM,GAEjB;IAED;;;;;;;;;;;OAWG;IACH,EAAE,CACD,IAAI,GAAE,gBAA4B,EAClC,KAAK,SAAK,EACV,MAAM,CAAC,EAAE,aAAa,GACpB,MAAM;IA4BT;;;;;;;;;OASG;IACH,KAAK,CACJ,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,GAClB,MAAM;CAKT"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * The {@link Pronoun} class.
4
+ * @module
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Pronoun = void 0;
8
+ exports.normalizeComponents = normalizeComponents;
9
+ const errors_js_1 = require("./errors.js");
10
+ const template_js_1 = require("./template.js");
11
+ const types_js_1 = require("./types.js");
12
+ const utils_js_1 = require("./utils.js");
13
+ /**
14
+ * Normalise a loose {@link PronounInput} into strict
15
+ * {@link PronounComponents}, accepting single strings or arrays and
16
+ * legacy alias keys. Throws a {@link PnyError} if any form is missing.
17
+ */
18
+ function normalizeComponents(id, input) {
19
+ const source = input;
20
+ const pick = (...keys) => {
21
+ for (const key of keys) {
22
+ const value = source[key];
23
+ if (value !== undefined) {
24
+ return (0, utils_js_1.toArray)(value).map(String);
25
+ }
26
+ }
27
+ return undefined;
28
+ };
29
+ const components = {
30
+ subject: pick("subject"),
31
+ object: pick("object"),
32
+ possessive: pick("possessive"),
33
+ possessiveDeterminer: pick("possessiveDeterminer", "possessiveAdjective", "psAdjective"),
34
+ reflexive: pick("reflexive", "intensive"),
35
+ };
36
+ for (const form of types_js_1.PRONOUN_FORMS) {
37
+ const value = components[form];
38
+ if (!value || value.length === 0) {
39
+ throw new errors_js_1.PnyError("PronounValidationError", `Pronoun "${id}" is missing a value for the "${form}" form.`);
40
+ }
41
+ }
42
+ return components;
43
+ }
44
+ /**
45
+ * # `Pronoun`
46
+ * A single pronoun with all five grammatical {@link PronounForm forms}.
47
+ * Each form may hold several accepted spellings.
48
+ *
49
+ * Create pronouns through {@link Pronouny.add} so they are registered
50
+ * for resolution, or construct one directly for standalone use.
51
+ */
52
+ class Pronoun {
53
+ constructor(id, input, resolver) {
54
+ this.id = id;
55
+ this.components = normalizeComponents(id, input);
56
+ this.resolver = resolver;
57
+ }
58
+ get config() {
59
+ return this.resolver?.config ?? types_js_1.DEFAULT_CONFIG;
60
+ }
61
+ /**
62
+ * Retrieve a single surface string for the requested grammatical
63
+ * form.
64
+ *
65
+ * @param form The form to retrieve. Accepts aliases such as
66
+ * `possessiveAdjective` and `intensive`. Defaults to
67
+ * `subject`.
68
+ * @param index Retrieve the `index`-th spelling of the form. When
69
+ * `-1` (default) a spelling is chosen according to the
70
+ * `useRandom` config.
71
+ * @param config Optional per-call config overrides.
72
+ */
73
+ as(form = "subject", index = -1, config) {
74
+ const cfg = (0, utils_js_1.mergeConfig)(this.config, config);
75
+ const canonical = (0, types_js_1.canonicalForm)(form);
76
+ const ctx = this.components[canonical];
77
+ if (!ctx || ctx.length === 0) {
78
+ if (cfg.failQuietly)
79
+ return "";
80
+ throw new errors_js_1.PnyError("PronounFormError", `Pronoun "${this.id}" has no "${canonical}" form.`);
81
+ }
82
+ if (index >= 0) {
83
+ if (index >= ctx.length) {
84
+ if (cfg.failQuietly)
85
+ return ctx[0];
86
+ throw new errors_js_1.PnyError("PronounIndexingError", `Index ${index} is out of range for the "${canonical}" form of "${this.id}" (length ${ctx.length}).`);
87
+ }
88
+ return ctx[index];
89
+ }
90
+ if (!cfg.useRandom)
91
+ return ctx[0];
92
+ return ctx[(0, utils_js_1.randomIndex)(ctx.length)];
93
+ }
94
+ /**
95
+ * Tagged-template helper. Interpolated pronoun words are rewritten
96
+ * to the matching form of *this* pronoun, preserving capitalisation.
97
+ * Non-pronoun values pass through unchanged.
98
+ *
99
+ * ```ts
100
+ * he.parse`${"They"} updated ${"their"} status.`;
101
+ * // "He updated his status."
102
+ * ```
103
+ */
104
+ parse(strings, ...values) {
105
+ return (0, template_js_1.renderTemplate)(this.resolver, strings, values, (form) => this.as(form));
106
+ }
107
+ }
108
+ exports.Pronoun = Pronoun;
109
+ //# sourceMappingURL=Pronoun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pronoun.js","sourceRoot":"","sources":["../../src/Pronoun.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The {@link PronounSet} class.
3
+ * @module
4
+ */
5
+ import { Pronoun } from "./Pronoun.js";
6
+ import type Pronouny from "./Pronouny.js";
7
+ import type { PartialConfig, PronounFormInput } from "./types.js";
8
+ /** A pronoun, or a string that can be resolved to one. */
9
+ export type PronounLike = Pronoun | string;
10
+ /**
11
+ * # `PronounSet`
12
+ * An ordered, de-duplicated collection of {@link Pronoun}s representing
13
+ * how a single entity may be referred to (e.g. `she/they`).
14
+ *
15
+ * Create one with {@link Pronouny.set}. Call {@link PronounSet.use} to
16
+ * pick a pronoun, or {@link PronounSet.as} / {@link PronounSet.parse}
17
+ * to render a form directly.
18
+ */
19
+ export declare class PronounSet {
20
+ /** The pronouns in this set, in insertion order. */
21
+ readonly pronouns: Set<Pronoun>;
22
+ /** The Pronouny instance that owns this set. */
23
+ readonly resolver: Pronouny;
24
+ constructor(resolver: Pronouny, pronouns?: Iterable<PronounLike> | PronounLike);
25
+ private resolveOne;
26
+ /**
27
+ * Add one or more pronouns to the set. Strings are resolved through
28
+ * the owning {@link Pronouny} instance. Chainable.
29
+ */
30
+ add(pronoun: Iterable<PronounLike> | PronounLike): this;
31
+ /**
32
+ * Remove one or more pronouns from the set. Strings are resolved
33
+ * through the owning {@link Pronouny} instance. Chainable.
34
+ */
35
+ remove(pronoun: Iterable<PronounLike> | PronounLike): this;
36
+ /** The number of pronouns in the set. */
37
+ get size(): number;
38
+ /** The pronouns as an array, in insertion order. */
39
+ list(): Pronoun[];
40
+ /**
41
+ * Pick a single {@link Pronoun} from the set.
42
+ *
43
+ * @param index Retrieve the `index`-th pronoun. When `-1` (default)
44
+ * a pronoun is chosen according to the `useRandom`
45
+ * config.
46
+ * @param config Optional per-call config overrides.
47
+ */
48
+ use(index?: number, config?: PartialConfig): Pronoun;
49
+ /**
50
+ * Pick a pronoun from the set and return the requested grammatical
51
+ * form. Shorthand for `set.use(-1, config).as(form, -1, config)`.
52
+ */
53
+ as(form?: PronounFormInput, config?: PartialConfig): string;
54
+ /**
55
+ * Tagged-template helper. Each interpolated pronoun word is resolved
56
+ * independently, drawing a fresh pronoun from the set (per the
57
+ * `useRandom` config) for every substitution — so a multi-pronoun
58
+ * set is distributed across the string rather than fixed to one
59
+ * member. Interpolated pronoun words are rewritten to the matching
60
+ * form (preserving capitalisation); other values pass through
61
+ * unchanged.
62
+ *
63
+ * ```ts
64
+ * pronouns.parse`${"They"} updated ${"their"} status.`;
65
+ * // e.g. "She updated their status."
66
+ * ```
67
+ */
68
+ parse(strings: TemplateStringsArray, ...values: unknown[]): string;
69
+ }
70
+ //# sourceMappingURL=PronounSet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PronounSet.d.ts","sourceRoot":"","sources":["../../src/PronounSet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAG1C,OAAO,KAAK,EAAE,aAAa,EAAe,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/E,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACtB,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAEhC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAG3B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,WACjB;IAOlB,OAAO,CAAC,UAAU;IAMlB;;;OAGG;IACH,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,IAAI;IAWvD;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,IAAI;IAW1D,yCAAyC;IACzC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,oDAAoD;IACpD,IAAI,IAAI,OAAO,EAAE;IAIjB;;;;;;;OAOG;IACH,GAAG,CAAC,KAAK,SAAK,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO;IA6BhD;;;OAGG;IACH,EAAE,CAAC,IAAI,GAAE,gBAA4B,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM;IAItE;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM;CAQlE"}