@saykit/config 0.0.0-beta-20260729112211 → 0.0.0-beta-20260729131250
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.
|
@@ -25,28 +25,28 @@ function assignSequenceIdentifiers(message, sequence = { current: 0 }, equivalen
|
|
|
25
25
|
* Collect the identifiers already assigned before this pass runs, so generated
|
|
26
26
|
* sequence numbers never shadow an explicit one (e.g. an element tagged `0`).
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
28
|
+
* A name is claimed by what produced it, not by the name alone. Two that differ
|
|
29
|
+
* each compile to their own prop, and a translator moving them around a sentence
|
|
30
|
+
* has to be able to tell them apart, so they are a build error. Repeats are fine
|
|
31
|
+
* when nothing distinguishes them: the same variable interpolated twice is one
|
|
32
|
+
* value, and two identical elements are one tag.
|
|
33
33
|
*/
|
|
34
34
|
function collectAssignedIdentifiers(message, equivalent) {
|
|
35
35
|
const tags = /* @__PURE__ */ new Map();
|
|
36
|
-
const values = /* @__PURE__ */ new
|
|
36
|
+
const values = /* @__PURE__ */ new Map();
|
|
37
|
+
function claim(claimed, identifier, expression, conflict) {
|
|
38
|
+
if (claimed.has(identifier) && !equivalent(claimed.get(identifier), expression)) throw new Error(conflict);
|
|
39
|
+
claimed.set(identifier, expression);
|
|
40
|
+
}
|
|
37
41
|
function walk(message) {
|
|
38
|
-
if (message instanceof ElementMessage && typeof message.identifier === "string") {
|
|
39
|
-
|
|
40
|
-
if (previous && !equivalent(previous.expression, message.expression)) throw new Error(`Duplicate element tag '${message.identifier}', give each element in a message its own tag unless they are identical`);
|
|
41
|
-
tags.set(message.identifier, message);
|
|
42
|
-
}
|
|
43
|
-
if ((message instanceof ArgumentMessage || message instanceof ChoiceMessage) && typeof message.identifier === "string") values.add(message.identifier);
|
|
42
|
+
if (message instanceof ElementMessage && typeof message.identifier === "string") claim(tags, message.identifier, message.expression, `Duplicate element tag '${message.identifier}', give each element in a message its own tag unless they are identical`);
|
|
43
|
+
if ((message instanceof ArgumentMessage || message instanceof ChoiceMessage) && typeof message.identifier === "string") claim(values, message.identifier, message.expression, `Duplicate placeholder name '${message.identifier}', give each value in a message its own name unless they are identical`);
|
|
44
44
|
if (message instanceof CompositeMessage || message instanceof ElementMessage) for (const child of message.children) walk(child);
|
|
45
45
|
if (message instanceof ChoiceMessage) for (const branch of message.branches) walk(branch.value);
|
|
46
46
|
}
|
|
47
47
|
walk(message);
|
|
48
48
|
for (const tag of tags.keys()) if (values.has(tag)) throw new Error(`Element tag '${tag}' collides with an argument of the same name`);
|
|
49
|
-
return /* @__PURE__ */ new Set([...tags.keys(), ...values]);
|
|
49
|
+
return /* @__PURE__ */ new Set([...tags.keys(), ...values.keys()]);
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/features/messages/types.ts
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//#region src/features/messages/identifier.d.ts
|
|
2
2
|
declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
3
3
|
/**
|
|
4
|
-
* Decides whether two
|
|
5
|
-
* share it. Only the syntax that produced them can answer that, so the
|
|
6
|
-
* supplies the comparison; by default
|
|
4
|
+
* Decides whether two placeholders sharing a name are the same placeholder, and
|
|
5
|
+
* so may share it. Only the syntax that produced them can answer that, so the
|
|
6
|
+
* caller supplies the comparison; by default nothing is interchangeable.
|
|
7
7
|
*/
|
|
8
|
-
type
|
|
8
|
+
type PlaceholderEquivalence = (a: any, b: any) => boolean;
|
|
9
9
|
declare function assignSequenceIdentifiers(message: Message, sequence?: {
|
|
10
10
|
current: number;
|
|
11
|
-
}, equivalent?:
|
|
11
|
+
}, equivalent?: PlaceholderEquivalence): void;
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/features/messages/types.d.ts
|
|
14
14
|
declare abstract class Base {
|
|
@@ -66,4 +66,4 @@ declare function convertMessageToIcu(message: Message): string;
|
|
|
66
66
|
//#region src/features/messages/hash.d.ts
|
|
67
67
|
declare function generateHash(input: string, context?: string): string;
|
|
68
68
|
//#endregion
|
|
69
|
-
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage,
|
|
69
|
+
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, PlaceholderEquivalence, assignSequenceIdentifiers, convertMessageToIcu, generateHash };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//#region src/features/messages/identifier.d.ts
|
|
2
2
|
declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
3
3
|
/**
|
|
4
|
-
* Decides whether two
|
|
5
|
-
* share it. Only the syntax that produced them can answer that, so the
|
|
6
|
-
* supplies the comparison; by default
|
|
4
|
+
* Decides whether two placeholders sharing a name are the same placeholder, and
|
|
5
|
+
* so may share it. Only the syntax that produced them can answer that, so the
|
|
6
|
+
* caller supplies the comparison; by default nothing is interchangeable.
|
|
7
7
|
*/
|
|
8
|
-
type
|
|
8
|
+
type PlaceholderEquivalence = (a: any, b: any) => boolean;
|
|
9
9
|
declare function assignSequenceIdentifiers(message: Message, sequence?: {
|
|
10
10
|
current: number;
|
|
11
|
-
}, equivalent?:
|
|
11
|
+
}, equivalent?: PlaceholderEquivalence): void;
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/features/messages/types.d.ts
|
|
14
14
|
declare abstract class Base {
|
|
@@ -66,4 +66,4 @@ declare function convertMessageToIcu(message: Message): string;
|
|
|
66
66
|
//#region src/features/messages/hash.d.ts
|
|
67
67
|
declare function generateHash(input: string, context?: string): string;
|
|
68
68
|
//#endregion
|
|
69
|
-
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage,
|
|
69
|
+
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, PlaceholderEquivalence, assignSequenceIdentifiers, convertMessageToIcu, generateHash };
|
|
@@ -24,28 +24,28 @@ function assignSequenceIdentifiers(message, sequence = { current: 0 }, equivalen
|
|
|
24
24
|
* Collect the identifiers already assigned before this pass runs, so generated
|
|
25
25
|
* sequence numbers never shadow an explicit one (e.g. an element tagged `0`).
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* A name is claimed by what produced it, not by the name alone. Two that differ
|
|
28
|
+
* each compile to their own prop, and a translator moving them around a sentence
|
|
29
|
+
* has to be able to tell them apart, so they are a build error. Repeats are fine
|
|
30
|
+
* when nothing distinguishes them: the same variable interpolated twice is one
|
|
31
|
+
* value, and two identical elements are one tag.
|
|
32
32
|
*/
|
|
33
33
|
function collectAssignedIdentifiers(message, equivalent) {
|
|
34
34
|
const tags = /* @__PURE__ */ new Map();
|
|
35
|
-
const values = /* @__PURE__ */ new
|
|
35
|
+
const values = /* @__PURE__ */ new Map();
|
|
36
|
+
function claim(claimed, identifier, expression, conflict) {
|
|
37
|
+
if (claimed.has(identifier) && !equivalent(claimed.get(identifier), expression)) throw new Error(conflict);
|
|
38
|
+
claimed.set(identifier, expression);
|
|
39
|
+
}
|
|
36
40
|
function walk(message) {
|
|
37
|
-
if (message instanceof ElementMessage && typeof message.identifier === "string") {
|
|
38
|
-
|
|
39
|
-
if (previous && !equivalent(previous.expression, message.expression)) throw new Error(`Duplicate element tag '${message.identifier}', give each element in a message its own tag unless they are identical`);
|
|
40
|
-
tags.set(message.identifier, message);
|
|
41
|
-
}
|
|
42
|
-
if ((message instanceof ArgumentMessage || message instanceof ChoiceMessage) && typeof message.identifier === "string") values.add(message.identifier);
|
|
41
|
+
if (message instanceof ElementMessage && typeof message.identifier === "string") claim(tags, message.identifier, message.expression, `Duplicate element tag '${message.identifier}', give each element in a message its own tag unless they are identical`);
|
|
42
|
+
if ((message instanceof ArgumentMessage || message instanceof ChoiceMessage) && typeof message.identifier === "string") claim(values, message.identifier, message.expression, `Duplicate placeholder name '${message.identifier}', give each value in a message its own name unless they are identical`);
|
|
43
43
|
if (message instanceof CompositeMessage || message instanceof ElementMessage) for (const child of message.children) walk(child);
|
|
44
44
|
if (message instanceof ChoiceMessage) for (const branch of message.branches) walk(branch.value);
|
|
45
45
|
}
|
|
46
46
|
walk(message);
|
|
47
47
|
for (const tag of tags.keys()) if (values.has(tag)) throw new Error(`Element tag '${tag}' collides with an argument of the same name`);
|
|
48
|
-
return /* @__PURE__ */ new Set([...tags.keys(), ...values]);
|
|
48
|
+
return /* @__PURE__ */ new Set([...tags.keys(), ...values.keys()]);
|
|
49
49
|
}
|
|
50
50
|
//#endregion
|
|
51
51
|
//#region src/features/messages/types.ts
|