@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.
- package/LICENSE +21 -0
- package/README.md +419 -0
- package/dist/Cef.d.ts +188 -0
- package/dist/Cef.d.ts.map +1 -0
- package/dist/Cef.js +291 -0
- package/dist/CefFormat.d.ts +57 -0
- package/dist/CefFormat.d.ts.map +1 -0
- package/dist/CefFormat.js +133 -0
- package/dist/CommentLine.d.ts +18 -0
- package/dist/CommentLine.d.ts.map +1 -0
- package/dist/CommentLine.js +27 -0
- package/dist/Exception/CefFormatException.d.ts +16 -0
- package/dist/Exception/CefFormatException.d.ts.map +1 -0
- package/dist/Exception/CefFormatException.js +19 -0
- package/dist/Exception/CefWriteException.d.ts +12 -0
- package/dist/Exception/CefWriteException.d.ts.map +1 -0
- package/dist/Exception/CefWriteException.js +13 -0
- package/dist/Exception/DuplicateCandidateException.d.ts +9 -0
- package/dist/Exception/DuplicateCandidateException.d.ts.map +1 -0
- package/dist/Exception/DuplicateCandidateException.js +8 -0
- package/dist/Exception/InvalidUtf8Exception.d.ts +13 -0
- package/dist/Exception/InvalidUtf8Exception.d.ts.map +1 -0
- package/dist/Exception/InvalidUtf8Exception.js +12 -0
- package/dist/Exception/InvalidValueException.d.ts +15 -0
- package/dist/Exception/InvalidValueException.d.ts.map +1 -0
- package/dist/Exception/InvalidValueException.js +14 -0
- package/dist/Exception/InvalidWriterStateException.d.ts +14 -0
- package/dist/Exception/InvalidWriterStateException.d.ts.map +1 -0
- package/dist/Exception/InvalidWriterStateException.js +13 -0
- package/dist/Exception/ReservedCharacterException.d.ts +12 -0
- package/dist/Exception/ReservedCharacterException.d.ts.map +1 -0
- package/dist/Exception/ReservedCharacterException.js +11 -0
- package/dist/Exception/index.d.ts +8 -0
- package/dist/Exception/index.d.ts.map +1 -0
- package/dist/Exception/index.js +7 -0
- package/dist/FileWriteTarget.d.ts +27 -0
- package/dist/FileWriteTarget.d.ts.map +1 -0
- package/dist/FileWriteTarget.js +35 -0
- package/dist/Parameter/CandidatesParameter.d.ts +20 -0
- package/dist/Parameter/CandidatesParameter.d.ts.map +1 -0
- package/dist/Parameter/CandidatesParameter.js +39 -0
- package/dist/Parameter/CustomParameter.d.ts +19 -0
- package/dist/Parameter/CustomParameter.d.ts.map +1 -0
- package/dist/Parameter/CustomParameter.js +35 -0
- package/dist/Parameter/ImplicitRankingParameter.d.ts +11 -0
- package/dist/Parameter/ImplicitRankingParameter.d.ts.map +1 -0
- package/dist/Parameter/ImplicitRankingParameter.js +16 -0
- package/dist/Parameter/NumberOfSeatsParameter.d.ts +14 -0
- package/dist/Parameter/NumberOfSeatsParameter.d.ts.map +1 -0
- package/dist/Parameter/NumberOfSeatsParameter.js +23 -0
- package/dist/Parameter/ParameterInterface.d.ts +20 -0
- package/dist/Parameter/ParameterInterface.d.ts.map +1 -0
- package/dist/Parameter/ParameterInterface.js +1 -0
- package/dist/Parameter/StandardParameter.d.ts +14 -0
- package/dist/Parameter/StandardParameter.d.ts.map +1 -0
- package/dist/Parameter/StandardParameter.js +14 -0
- package/dist/Parameter/VotingMethodsParameter.d.ts +16 -0
- package/dist/Parameter/VotingMethodsParameter.d.ts.map +1 -0
- package/dist/Parameter/VotingMethodsParameter.js +29 -0
- package/dist/Parameter/WeightAllowedParameter.d.ts +11 -0
- package/dist/Parameter/WeightAllowedParameter.d.ts.map +1 -0
- package/dist/Parameter/WeightAllowedParameter.js +16 -0
- package/dist/Parameter/index.d.ts +9 -0
- package/dist/Parameter/index.d.ts.map +1 -0
- package/dist/Parameter/index.js +7 -0
- package/dist/Ranking.d.ts +91 -0
- package/dist/Ranking.d.ts.map +1 -0
- package/dist/Ranking.js +162 -0
- package/dist/VoteLine.d.ts +156 -0
- package/dist/VoteLine.d.ts.map +1 -0
- package/dist/VoteLine.js +289 -0
- package/dist/index.browser.d.ts +17 -0
- package/dist/index.browser.d.ts.map +1 -0
- package/dist/index.browser.js +16 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.node.d.ts +19 -0
- package/dist/index.node.d.ts.map +1 -0
- package/dist/index.node.js +25 -0
- package/package.json +79 -0
- package/src/Cef.ts +405 -0
- package/src/CefFormat.ts +152 -0
- package/src/CommentLine.ts +32 -0
- package/src/Exception/CefFormatException.ts +19 -0
- package/src/Exception/CefWriteException.ts +13 -0
- package/src/Exception/DuplicateCandidateException.ts +8 -0
- package/src/Exception/InvalidUtf8Exception.ts +12 -0
- package/src/Exception/InvalidValueException.ts +14 -0
- package/src/Exception/InvalidWriterStateException.ts +13 -0
- package/src/Exception/ReservedCharacterException.ts +11 -0
- package/src/Exception/index.ts +7 -0
- package/src/FileWriteTarget.ts +42 -0
- package/src/Parameter/CandidatesParameter.ts +49 -0
- package/src/Parameter/CustomParameter.ts +45 -0
- package/src/Parameter/ImplicitRankingParameter.ts +17 -0
- package/src/Parameter/NumberOfSeatsParameter.ts +25 -0
- package/src/Parameter/ParameterInterface.ts +20 -0
- package/src/Parameter/StandardParameter.ts +13 -0
- package/src/Parameter/VotingMethodsParameter.ts +36 -0
- package/src/Parameter/WeightAllowedParameter.ts +17 -0
- package/src/Parameter/index.ts +8 -0
- package/src/Ranking.ts +197 -0
- package/src/VoteLine.ts +398 -0
- package/src/index.browser.ts +36 -0
- package/src/index.node.ts +47 -0
- package/src/index.ts +8 -0
package/dist/VoteLine.js
ADDED
|
@@ -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';
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|