@condorcet.vote/cef-writer 1.2.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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +419 -0
  3. package/dist/Cef.d.ts +188 -0
  4. package/dist/Cef.d.ts.map +1 -0
  5. package/dist/Cef.js +291 -0
  6. package/dist/CefFormat.d.ts +57 -0
  7. package/dist/CefFormat.d.ts.map +1 -0
  8. package/dist/CefFormat.js +133 -0
  9. package/dist/CommentLine.d.ts +18 -0
  10. package/dist/CommentLine.d.ts.map +1 -0
  11. package/dist/CommentLine.js +27 -0
  12. package/dist/Exception/CefFormatException.d.ts +16 -0
  13. package/dist/Exception/CefFormatException.d.ts.map +1 -0
  14. package/dist/Exception/CefFormatException.js +19 -0
  15. package/dist/Exception/CefWriteException.d.ts +12 -0
  16. package/dist/Exception/CefWriteException.d.ts.map +1 -0
  17. package/dist/Exception/CefWriteException.js +13 -0
  18. package/dist/Exception/DuplicateCandidateException.d.ts +9 -0
  19. package/dist/Exception/DuplicateCandidateException.d.ts.map +1 -0
  20. package/dist/Exception/DuplicateCandidateException.js +8 -0
  21. package/dist/Exception/InvalidUtf8Exception.d.ts +13 -0
  22. package/dist/Exception/InvalidUtf8Exception.d.ts.map +1 -0
  23. package/dist/Exception/InvalidUtf8Exception.js +12 -0
  24. package/dist/Exception/InvalidValueException.d.ts +15 -0
  25. package/dist/Exception/InvalidValueException.d.ts.map +1 -0
  26. package/dist/Exception/InvalidValueException.js +14 -0
  27. package/dist/Exception/InvalidWriterStateException.d.ts +14 -0
  28. package/dist/Exception/InvalidWriterStateException.d.ts.map +1 -0
  29. package/dist/Exception/InvalidWriterStateException.js +13 -0
  30. package/dist/Exception/ReservedCharacterException.d.ts +12 -0
  31. package/dist/Exception/ReservedCharacterException.d.ts.map +1 -0
  32. package/dist/Exception/ReservedCharacterException.js +11 -0
  33. package/dist/Exception/index.d.ts +8 -0
  34. package/dist/Exception/index.d.ts.map +1 -0
  35. package/dist/Exception/index.js +7 -0
  36. package/dist/FileWriteTarget.d.ts +27 -0
  37. package/dist/FileWriteTarget.d.ts.map +1 -0
  38. package/dist/FileWriteTarget.js +35 -0
  39. package/dist/Parameter/CandidatesParameter.d.ts +20 -0
  40. package/dist/Parameter/CandidatesParameter.d.ts.map +1 -0
  41. package/dist/Parameter/CandidatesParameter.js +39 -0
  42. package/dist/Parameter/CustomParameter.d.ts +19 -0
  43. package/dist/Parameter/CustomParameter.d.ts.map +1 -0
  44. package/dist/Parameter/CustomParameter.js +35 -0
  45. package/dist/Parameter/ImplicitRankingParameter.d.ts +11 -0
  46. package/dist/Parameter/ImplicitRankingParameter.d.ts.map +1 -0
  47. package/dist/Parameter/ImplicitRankingParameter.js +16 -0
  48. package/dist/Parameter/NumberOfSeatsParameter.d.ts +14 -0
  49. package/dist/Parameter/NumberOfSeatsParameter.d.ts.map +1 -0
  50. package/dist/Parameter/NumberOfSeatsParameter.js +23 -0
  51. package/dist/Parameter/ParameterInterface.d.ts +20 -0
  52. package/dist/Parameter/ParameterInterface.d.ts.map +1 -0
  53. package/dist/Parameter/ParameterInterface.js +1 -0
  54. package/dist/Parameter/StandardParameter.d.ts +14 -0
  55. package/dist/Parameter/StandardParameter.d.ts.map +1 -0
  56. package/dist/Parameter/StandardParameter.js +14 -0
  57. package/dist/Parameter/VotingMethodsParameter.d.ts +16 -0
  58. package/dist/Parameter/VotingMethodsParameter.d.ts.map +1 -0
  59. package/dist/Parameter/VotingMethodsParameter.js +29 -0
  60. package/dist/Parameter/WeightAllowedParameter.d.ts +11 -0
  61. package/dist/Parameter/WeightAllowedParameter.d.ts.map +1 -0
  62. package/dist/Parameter/WeightAllowedParameter.js +16 -0
  63. package/dist/Parameter/index.d.ts +9 -0
  64. package/dist/Parameter/index.d.ts.map +1 -0
  65. package/dist/Parameter/index.js +7 -0
  66. package/dist/Ranking.d.ts +91 -0
  67. package/dist/Ranking.d.ts.map +1 -0
  68. package/dist/Ranking.js +162 -0
  69. package/dist/VoteLine.d.ts +156 -0
  70. package/dist/VoteLine.d.ts.map +1 -0
  71. package/dist/VoteLine.js +289 -0
  72. package/dist/index.browser.d.ts +17 -0
  73. package/dist/index.browser.d.ts.map +1 -0
  74. package/dist/index.browser.js +16 -0
  75. package/dist/index.d.ts +8 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +7 -0
  78. package/dist/index.node.d.ts +19 -0
  79. package/dist/index.node.d.ts.map +1 -0
  80. package/dist/index.node.js +25 -0
  81. package/package.json +79 -0
  82. package/src/Cef.ts +405 -0
  83. package/src/CefFormat.ts +152 -0
  84. package/src/CommentLine.ts +32 -0
  85. package/src/Exception/CefFormatException.ts +19 -0
  86. package/src/Exception/CefWriteException.ts +13 -0
  87. package/src/Exception/DuplicateCandidateException.ts +8 -0
  88. package/src/Exception/InvalidUtf8Exception.ts +12 -0
  89. package/src/Exception/InvalidValueException.ts +14 -0
  90. package/src/Exception/InvalidWriterStateException.ts +13 -0
  91. package/src/Exception/ReservedCharacterException.ts +11 -0
  92. package/src/Exception/index.ts +7 -0
  93. package/src/FileWriteTarget.ts +42 -0
  94. package/src/Parameter/CandidatesParameter.ts +49 -0
  95. package/src/Parameter/CustomParameter.ts +45 -0
  96. package/src/Parameter/ImplicitRankingParameter.ts +17 -0
  97. package/src/Parameter/NumberOfSeatsParameter.ts +25 -0
  98. package/src/Parameter/ParameterInterface.ts +20 -0
  99. package/src/Parameter/StandardParameter.ts +13 -0
  100. package/src/Parameter/VotingMethodsParameter.ts +36 -0
  101. package/src/Parameter/WeightAllowedParameter.ts +17 -0
  102. package/src/Parameter/index.ts +8 -0
  103. package/src/Ranking.ts +197 -0
  104. package/src/VoteLine.ts +398 -0
  105. package/src/index.browser.ts +36 -0
  106. package/src/index.node.ts +47 -0
  107. package/src/index.ts +8 -0
@@ -0,0 +1,289 @@
1
+ import { CefFormat } from './CefFormat';
2
+ import { InvalidValueException, InvalidWriterStateException } from './Exception';
3
+ import { Ranking } from './Ranking';
4
+ /**
5
+ * A single ballot.
6
+ *
7
+ * Instances are never built with `new`: use one of the static named
8
+ * constructors — {@link fromRanking} (typed ranks or a {@link Ranking}),
9
+ * {@link fromString} (a full CEF vote-line string), or
10
+ * {@link fromRawRankingString} (a pre-validated *verbatim* ranking string).
11
+ *
12
+ * The ranking is held as a {@link Ranking} value object on {@link ranking}. An
13
+ * empty ranking renders as the `/EMPTY_RANKING/` blank-ballot sentinel. In the
14
+ * verbatim mode the ranking string is written untouched and is *not* parsed,
15
+ * so {@link ranking} is `null`.
16
+ *
17
+ * Optional companions:
18
+ * - `tags` — labels separated by `,`, appended before `||`;
19
+ * - `weight` — strictly positive integer; only meaningful when the
20
+ * `Weight Allowed` parameter is enabled in the document;
21
+ * - `quantifier` — strictly positive integer that collapses identical
22
+ * votes onto a single line;
23
+ * - `inlineComment` — free-form trailing comment introduced by `#`.
24
+ */
25
+ export class VoteLine {
26
+ /**
27
+ * The parsed ranking, or `null` when the ballot was built from a verbatim
28
+ * ranking string via {@link fromRawRankingString} — in that mode the ranking
29
+ * is deliberately *not* parsed into a {@link Ranking} structure.
30
+ */
31
+ ranking;
32
+ /**
33
+ * Verbatim, pre-validated ranking string written to the output untouched.
34
+ * Set only in the {@link fromRawRankingString} mode; `null` otherwise (when
35
+ * {@link ranking} carries the parsed structure instead).
36
+ */
37
+ rawRanking;
38
+ tags;
39
+ weight;
40
+ quantifier;
41
+ inlineComment;
42
+ /**
43
+ * @internal Use a static named constructor instead: {@link fromRanking},
44
+ * {@link fromString} or {@link fromRawRankingString}.
45
+ *
46
+ * @throws {CefFormatException} on any specification violation
47
+ */
48
+ constructor(ranking, verbatim, tags = [], weight = null, quantifier = null, inlineComment = null) {
49
+ if (verbatim) {
50
+ // Verbatim mode: validate the ranking string but skip parsing it into a
51
+ // Ranking — it is written as-is by format().
52
+ if (typeof ranking !== 'string') {
53
+ throw new InvalidWriterStateException('Verbatim mode requires a ranking string.');
54
+ }
55
+ Ranking.assertValidString(ranking);
56
+ this.ranking = null;
57
+ this.rawRanking = ranking.trim();
58
+ }
59
+ else {
60
+ if (!(ranking instanceof Ranking)) {
61
+ throw new InvalidWriterStateException('Non-verbatim mode requires a Ranking instance.');
62
+ }
63
+ this.ranking = ranking;
64
+ this.rawRanking = null;
65
+ }
66
+ this.tags = VoteLine.validateTags(tags);
67
+ VoteLine.assertCompanions(weight, quantifier);
68
+ if (inlineComment !== null) {
69
+ CefFormat.assertSingleLine(inlineComment, 'Inline comment');
70
+ }
71
+ this.weight = weight;
72
+ this.quantifier = quantifier;
73
+ this.inlineComment = inlineComment;
74
+ }
75
+ /**
76
+ * Build a {@link VoteLine} from typed ranks or a ready-made {@link Ranking}.
77
+ *
78
+ * This is the primary, typed constructor. The `ranking` argument is either an
79
+ * ordered list of ranks (each inner list a non-empty group of tied
80
+ * candidates; pass `[]` for the `/EMPTY_RANKING/` blank ballot) or a
81
+ * {@link Ranking} value object.
82
+ *
83
+ * @throws {CefFormatException} on any specification violation
84
+ */
85
+ static fromRanking(ranking, options = {}) {
86
+ return new VoteLine(ranking instanceof Ranking ? ranking : new Ranking(ranking), false, options.tags ?? [], options.weight ?? null, options.quantifier ?? null, options.inlineComment ?? null);
87
+ }
88
+ /**
89
+ * Build a {@link VoteLine} from a raw CEF vote-line string.
90
+ *
91
+ * Accepted shape — every component except the ranking is optional:
92
+ *
93
+ * [tag1, tag2 || ] ranking [ ^weight] [ *quantifier] [# comment]
94
+ *
95
+ * Both the relaxed and the compact spacing flavors are accepted, e.g.
96
+ * `"A>B^7*2"` and `"A > B ^7 * 2"` parse identically. The `/EMPTY_RANKING/`
97
+ * sentinel is recognised as a blank ballot.
98
+ *
99
+ * The string is parsed into its components; the resulting `VoteLine` is then
100
+ * constructed through the normal constructor, so every validation rule
101
+ * (reserved characters, empty rank, duplicate candidate, positive weight /
102
+ * quantifier) applies.
103
+ *
104
+ * @throws {CefFormatException}
105
+ */
106
+ static fromString(line) {
107
+ const parts = VoteLine.parseStringComponents(line);
108
+ return new VoteLine(parts.ranking, false, parts.tags, parts.weight, parts.quantifier, parts.inlineComment);
109
+ }
110
+ /**
111
+ * Validate that `line` is a syntactically valid CEF vote line, without
112
+ * allocating a `VoteLine` instance.
113
+ *
114
+ * The exact same parsing and validation pipeline that {@link fromString} uses
115
+ * is applied — only the final object construction is skipped. Useful for hot
116
+ * paths that want to write a pre-built line straight to the output after a
117
+ * strict format check.
118
+ *
119
+ * @throws {CefFormatException}
120
+ */
121
+ static assertValidString(line) {
122
+ VoteLine.parseStringComponents(line);
123
+ }
124
+ /**
125
+ * Build a {@link VoteLine} from a ranking-only string, kept *verbatim*.
126
+ *
127
+ * The special, allocation-light sibling of {@link fromRanking}: the ranking
128
+ * string is validated as a ranking and *nothing else* — any reserved
129
+ * character (`^`, `*`, `#`, `;`, `,`, `/`), the `||` tag separator, or a line
130
+ * break is rejected, so it cannot smuggle a weight, quantifier, tag or inline
131
+ * comment — but it is **not** parsed into a {@link Ranking}. The string is
132
+ * stored as-is and written untouched by {@link format} (only the
133
+ * library-built companions — the `||` separator, `^weight`, `*quantifier` —
134
+ * follow `autoFormat`). The resulting instance therefore has a `null`
135
+ * {@link ranking}. Used by `Cef.addRawVote()`.
136
+ *
137
+ * @throws {CefFormatException}
138
+ */
139
+ static fromRawRankingString(ranking, options = {}) {
140
+ return new VoteLine(ranking, true, options.tags ?? [], options.weight ?? null, options.quantifier ?? null);
141
+ }
142
+ /**
143
+ * Shared parser+validator used by {@link fromString} and
144
+ * {@link assertValidString}.
145
+ *
146
+ * Trims the input, extracts every component, and runs the same per-field
147
+ * validation (reserved characters, empty rank, duplicate candidate, positive
148
+ * weight / quantifier, single-line comment) that the constructor performs.
149
+ * Returns the components.
150
+ *
151
+ * @throws {CefFormatException}
152
+ */
153
+ static parseStringComponents(line) {
154
+ const original = line;
155
+ let work = line.trim();
156
+ if (work === '') {
157
+ throw new InvalidValueException('Vote line string cannot be empty.');
158
+ }
159
+ let inlineComment = null;
160
+ const hashPos = work.indexOf('#');
161
+ if (hashPos !== -1) {
162
+ let after = work.slice(hashPos + 1);
163
+ if (after.startsWith(' ')) {
164
+ after = after.slice(1);
165
+ }
166
+ after = VoteLine.rtrim(after);
167
+ inlineComment = after !== '' ? after : null;
168
+ work = VoteLine.rtrim(work.slice(0, hashPos));
169
+ }
170
+ if (inlineComment !== null) {
171
+ CefFormat.assertSingleLine(inlineComment, 'Inline comment');
172
+ }
173
+ const rawTags = [];
174
+ const separator = CefFormat.TAGS_SEPARATOR;
175
+ const separatorPos = work.indexOf(separator);
176
+ if (separatorPos !== -1) {
177
+ const tagsPart = work.slice(0, separatorPos);
178
+ work = work.slice(separatorPos + separator.length).trim();
179
+ for (const rawTag of tagsPart.split(',')) {
180
+ rawTags.push(rawTag.trim());
181
+ }
182
+ }
183
+ let weight = null;
184
+ let quantifier = null;
185
+ const matches = /^([\s\S]*?)(?:\s*\^\s*(\d+))?(?:\s*\*\s*(\d+))?\s*$/.exec(work);
186
+ if (matches !== null) {
187
+ work = matches[1].trim();
188
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
189
+ if (matches[2] !== undefined) {
190
+ weight = Number.parseInt(matches[2], 10);
191
+ }
192
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
193
+ if (matches[3] !== undefined) {
194
+ quantifier = Number.parseInt(matches[3], 10);
195
+ }
196
+ }
197
+ if (weight !== null && weight < 1) {
198
+ throw new InvalidValueException('Weight must be a positive integer.');
199
+ }
200
+ if (quantifier !== null && quantifier < 1) {
201
+ throw new InvalidValueException('Quantifier must be a positive integer.');
202
+ }
203
+ if (work === '') {
204
+ throw new InvalidWriterStateException(`Vote line "${original.trim()}" has no ranking.`);
205
+ }
206
+ return {
207
+ ranking: Ranking.fromString(work),
208
+ tags: VoteLine.validateTags(rawTags),
209
+ weight,
210
+ quantifier,
211
+ inlineComment,
212
+ };
213
+ }
214
+ /**
215
+ * Render the ballot — *without* trailing newline or inline comment — using
216
+ * the spacing flavor selected by `autoFormat`.
217
+ */
218
+ format(autoFormat = true) {
219
+ return this.assembleLine(this.renderRanking(autoFormat), autoFormat);
220
+ }
221
+ /**
222
+ * Return the ranking part of the line: the verbatim string in raw mode, or
223
+ * the parsed ranking rendered with `autoFormat` otherwise.
224
+ */
225
+ renderRanking(autoFormat) {
226
+ if (this.rawRanking !== null) {
227
+ return this.rawRanking;
228
+ }
229
+ if (this.ranking === null) {
230
+ throw new InvalidWriterStateException('VoteLine has neither a parsed ranking nor a verbatim ranking string.');
231
+ }
232
+ return this.ranking.format(autoFormat);
233
+ }
234
+ /**
235
+ * Reject a non-null, non-positive weight or quantifier.
236
+ *
237
+ * @throws {CefFormatException}
238
+ */
239
+ static assertCompanions(weight, quantifier) {
240
+ if (weight !== null && (!Number.isInteger(weight) || weight < 1)) {
241
+ throw new InvalidValueException('Weight must be a positive integer.');
242
+ }
243
+ if (quantifier !== null && (!Number.isInteger(quantifier) || quantifier < 1)) {
244
+ throw new InvalidValueException('Quantifier must be a positive integer.');
245
+ }
246
+ }
247
+ /**
248
+ * Wrap a ranking string with the tag prefix and the weight / quantifier
249
+ * suffix, using the spacing flavor selected by `autoFormat`.
250
+ */
251
+ assembleLine(ranking, autoFormat) {
252
+ let line = '';
253
+ if (this.tags.length > 0) {
254
+ const tagSeparator = autoFormat ? ', ' : ',';
255
+ line += this.tags.join(tagSeparator);
256
+ line += autoFormat ? ' || ' : '||';
257
+ }
258
+ line += ranking;
259
+ if (this.weight !== null) {
260
+ line += autoFormat ? ' ^' + String(this.weight) : '^' + String(this.weight);
261
+ }
262
+ if (this.quantifier !== null) {
263
+ line += autoFormat ? ' * ' + String(this.quantifier) : '*' + String(this.quantifier);
264
+ }
265
+ return line;
266
+ }
267
+ /**
268
+ * @throws {CefFormatException}
269
+ */
270
+ static validateTags(tags) {
271
+ const cleaned = [];
272
+ for (const tag of tags) {
273
+ const trimmed = tag.trim();
274
+ if (trimmed === '') {
275
+ throw new InvalidValueException('Tag cannot be empty.');
276
+ }
277
+ CefFormat.assertNoTagSeparator(trimmed, 'Tag');
278
+ CefFormat.assertValueIsClean(trimmed, 'Tag');
279
+ cleaned.push(trimmed);
280
+ }
281
+ return cleaned;
282
+ }
283
+ /**
284
+ * Strip trailing whitespace, mirroring PHP's `rtrim()`.
285
+ */
286
+ static rtrim(value) {
287
+ return value.replace(/\s+$/, '');
288
+ }
289
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * CEF Writer — a TypeScript library that streams valid Condorcet Election
3
+ * Format (CEF) documents to a string buffer with a friendly object API.
4
+ *
5
+ * This is the browser-only entry point. For Node.js usage, import from the
6
+ * main export which includes {@link FileWriteTarget} for file system access.
7
+ *
8
+ * TypeScript port of {@link https://github.com/CondorcetVote/CEF-Writer | CondorcetVote/CEF-Writer}.
9
+ */
10
+ export { Cef, StringBuffer, type CefOptions, type WriteTarget } from './Cef';
11
+ export { CefFormat } from './CefFormat';
12
+ export { CommentLine } from './CommentLine';
13
+ export { Ranking } from './Ranking';
14
+ export { VoteLine } from './VoteLine';
15
+ export { CefFormatException, CefWriteException, DuplicateCandidateException, InvalidUtf8Exception, InvalidValueException, InvalidWriterStateException, ReservedCharacterException, } from './Exception';
16
+ export { CandidatesParameter, CustomParameter, ImplicitRankingParameter, NumberOfSeatsParameter, StandardParameter, VotingMethodsParameter, WeightAllowedParameter, type ParameterInterface, } from './Parameter';
17
+ //# sourceMappingURL=index.browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * CEF Writer — a TypeScript library that streams valid Condorcet Election
3
+ * Format (CEF) documents to a string buffer with a friendly object API.
4
+ *
5
+ * This is the browser-only entry point. For Node.js usage, import from the
6
+ * main export which includes {@link FileWriteTarget} for file system access.
7
+ *
8
+ * TypeScript port of {@link https://github.com/CondorcetVote/CEF-Writer | CondorcetVote/CEF-Writer}.
9
+ */
10
+ export { Cef, StringBuffer } from './Cef';
11
+ export { CefFormat } from './CefFormat';
12
+ export { CommentLine } from './CommentLine';
13
+ export { Ranking } from './Ranking';
14
+ export { VoteLine } from './VoteLine';
15
+ export { CefFormatException, CefWriteException, DuplicateCandidateException, InvalidUtf8Exception, InvalidValueException, InvalidWriterStateException, ReservedCharacterException, } from './Exception';
16
+ export { CandidatesParameter, CustomParameter, ImplicitRankingParameter, NumberOfSeatsParameter, StandardParameter, VotingMethodsParameter, WeightAllowedParameter, } from './Parameter';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * CEF Writer — default export for Node.js environments.
3
+ *
4
+ * For browser usage, import from `@condorcet.vote/cef-writer/browser` instead.
5
+ * See {@link https://github.com/CondorcetVote/CEF-Writer-Typescript#browser-usage | browser usage documentation}.
6
+ */
7
+ export * from './index.node';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * CEF Writer — default export for Node.js environments.
3
+ *
4
+ * For browser usage, import from `@condorcet.vote/cef-writer/browser` instead.
5
+ * See {@link https://github.com/CondorcetVote/CEF-Writer-Typescript#browser-usage | browser usage documentation}.
6
+ */
7
+ export * from './index.node';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * CEF Writer — a TypeScript library that streams valid Condorcet Election
3
+ * Format (CEF) documents to a file or string buffer with a friendly object API.
4
+ *
5
+ * This is the Node.js entry point with full file system support via
6
+ * {@link FileWriteTarget}. For browser-only usage, import from
7
+ * `@condorcet.vote/cef-writer/browser` which excludes Node.js dependencies.
8
+ *
9
+ * TypeScript port of {@link https://github.com/CondorcetVote/CEF-Writer | CondorcetVote/CEF-Writer}.
10
+ */
11
+ export { Cef, StringBuffer, type CefOptions, type WriteTarget } from './Cef';
12
+ export { FileWriteTarget } from './FileWriteTarget';
13
+ export { CefFormat } from './CefFormat';
14
+ export { CommentLine } from './CommentLine';
15
+ export { Ranking } from './Ranking';
16
+ export { VoteLine } from './VoteLine';
17
+ export { CefFormatException, CefWriteException, DuplicateCandidateException, InvalidUtf8Exception, InvalidValueException, InvalidWriterStateException, ReservedCharacterException, } from './Exception';
18
+ export { CandidatesParameter, CustomParameter, ImplicitRankingParameter, NumberOfSeatsParameter, StandardParameter, VotingMethodsParameter, WeightAllowedParameter, type ParameterInterface, } from './Parameter';
19
+ //# sourceMappingURL=index.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.node.d.ts","sourceRoot":"","sources":["../src/index.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * CEF Writer — a TypeScript library that streams valid Condorcet Election
3
+ * Format (CEF) documents to a file or string buffer with a friendly object API.
4
+ *
5
+ * This is the Node.js entry point with full file system support via
6
+ * {@link FileWriteTarget}. For browser-only usage, import from
7
+ * `@condorcet.vote/cef-writer/browser` which excludes Node.js dependencies.
8
+ *
9
+ * TypeScript port of {@link https://github.com/CondorcetVote/CEF-Writer | CondorcetVote/CEF-Writer}.
10
+ */
11
+ import { Cef } from './Cef';
12
+ import { FileWriteTarget } from './FileWriteTarget';
13
+ // Wire the file-path convenience for Node.js. This is the side effect that
14
+ // makes `new Cef({ file: '/some/path' })` work; the browser entry point omits
15
+ // it, keeping `node:fs` out of browser bundles. Marked in package.json's
16
+ // `sideEffects` so bundlers never tree-shake this registration away.
17
+ Cef.fileWriteTargetFactory = (path) => new FileWriteTarget(path);
18
+ export { Cef, StringBuffer } from './Cef';
19
+ export { FileWriteTarget } from './FileWriteTarget';
20
+ export { CefFormat } from './CefFormat';
21
+ export { CommentLine } from './CommentLine';
22
+ export { Ranking } from './Ranking';
23
+ export { VoteLine } from './VoteLine';
24
+ export { CefFormatException, CefWriteException, DuplicateCandidateException, InvalidUtf8Exception, InvalidValueException, InvalidWriterStateException, ReservedCharacterException, } from './Exception';
25
+ export { CandidatesParameter, CustomParameter, ImplicitRankingParameter, NumberOfSeatsParameter, StandardParameter, VotingMethodsParameter, WeightAllowedParameter, } from './Parameter';
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@condorcet.vote/cef-writer",
3
+ "version": "1.2.0",
4
+ "description": "Streaming TypeScript writer that produces valid Condorcet Election Format (CEF) documents line by line. A faithful port of CondorcetVote/CEF-Writer.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "sideEffects": [
9
+ "./dist/index.node.js"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "browser": "./dist/index.browser.js",
15
+ "node": "./dist/index.node.js",
16
+ "import": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./browser": {
20
+ "types": "./dist/index.browser.d.ts",
21
+ "browser": "./dist/index.browser.js",
22
+ "import": "./dist/index.browser.js",
23
+ "default": "./dist/index.browser.js"
24
+ }
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "src",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "dev": "tsc --watch",
35
+ "clean": "rm -rf dist",
36
+ "prebuild": "npm run clean",
37
+ "lint": "eslint src",
38
+ "lint:fix": "eslint src --fix",
39
+ "format": "prettier --write \"src/**/*.ts\"",
40
+ "format:check": "prettier --check \"src/**/*.ts\"",
41
+ "type-check": "tsc --noEmit",
42
+ "test": "bun test",
43
+ "prepublishOnly": "npm run lint && npm run type-check && npm run build"
44
+ },
45
+ "packageManager": "bun@latest",
46
+ "keywords": [
47
+ "cef",
48
+ "condorcet",
49
+ "election",
50
+ "condorcet-election-format",
51
+ "voting",
52
+ "writer",
53
+ "typescript"
54
+ ],
55
+ "author": "Julien Boudry",
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/CondorcetVote/CEF-Writer-Typescript.git"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/CondorcetVote/CEF-Writer-Typescript/issues"
63
+ },
64
+ "homepage": "https://github.com/CondorcetVote/CEF-Writer-Typescript#readme",
65
+ "devDependencies": {
66
+ "@eslint/js": "^10.0.0",
67
+ "@types/bun": "1.3.14",
68
+ "@types/node": "^22.0.0",
69
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
70
+ "@typescript-eslint/parser": "^8.0.0",
71
+ "eslint": "^10.4.1",
72
+ "prettier": "^3.0.0",
73
+ "typescript": "^6.0.3",
74
+ "typescript-eslint": "8.61.0"
75
+ },
76
+ "engines": {
77
+ "node": ">=24.0.0"
78
+ }
79
+ }