@saykit/config 0.5.0 → 0.6.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.
|
@@ -2,15 +2,51 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_hash = require("../../hash-51ce8YiG.cjs");
|
|
3
3
|
//#region src/features/messages/identifier.ts
|
|
4
4
|
const AUTO_INCREMENT_IDENTIFIER = Symbol("auto-increment");
|
|
5
|
-
function assignSequenceIdentifiers(message, sequence = { current: 0 }) {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
function assignSequenceIdentifiers(message, sequence = { current: 0 }, equivalent = () => false) {
|
|
6
|
+
const reserved = collectAssignedIdentifiers(message, equivalent);
|
|
7
|
+
function next() {
|
|
8
|
+
let identifier = `${sequence.current++}`;
|
|
9
|
+
while (reserved.has(identifier)) identifier = `${sequence.current++}`;
|
|
10
|
+
return identifier;
|
|
8
11
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
function walk(message) {
|
|
13
|
+
if (message instanceof ArgumentMessage || message instanceof ElementMessage || message instanceof ChoiceMessage) {
|
|
14
|
+
if (message.identifier === AUTO_INCREMENT_IDENTIFIER) message.identifier = next();
|
|
15
|
+
}
|
|
16
|
+
if (message instanceof CompositeMessage || message instanceof ElementMessage) for (const child of message.children) walk(child);
|
|
17
|
+
if (message instanceof ChoiceMessage) for (const branch of message.branches) {
|
|
18
|
+
if (branch.identifier === AUTO_INCREMENT_IDENTIFIER) branch.identifier = next();
|
|
19
|
+
walk(branch.value);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
walk(message);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Collect the identifiers already assigned before this pass runs, so generated
|
|
26
|
+
* sequence numbers never shadow an explicit one (e.g. an element tagged `0`).
|
|
27
|
+
*
|
|
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
|
+
*/
|
|
34
|
+
function collectAssignedIdentifiers(message, equivalent) {
|
|
35
|
+
const tags = /* @__PURE__ */ new Map();
|
|
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
|
+
}
|
|
41
|
+
function walk(message) {
|
|
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
|
+
if (message instanceof CompositeMessage || message instanceof ElementMessage) for (const child of message.children) walk(child);
|
|
45
|
+
if (message instanceof ChoiceMessage) for (const branch of message.branches) walk(branch.value);
|
|
13
46
|
}
|
|
47
|
+
walk(message);
|
|
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.keys()]);
|
|
14
50
|
}
|
|
15
51
|
//#endregion
|
|
16
52
|
//#region src/features/messages/types.ts
|
|
@@ -88,6 +124,7 @@ function convertMessageToIcu(message) {
|
|
|
88
124
|
case message instanceof LiteralMessage: return String(message.text);
|
|
89
125
|
case message instanceof ArgumentMessage: return `{${String(message.identifier)}}`;
|
|
90
126
|
case message instanceof ElementMessage: {
|
|
127
|
+
if (message.children.length === 0) return `<${String(message.identifier)}/>`;
|
|
91
128
|
const children = message.children.map((m) => internalConvertMessageToIcu(m)).join("");
|
|
92
129
|
return `<${String(message.identifier)}>${children}</${String(message.identifier)}>`;
|
|
93
130
|
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
//#region src/features/messages/identifier.d.ts
|
|
2
2
|
declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
3
|
+
/**
|
|
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
|
+
*/
|
|
8
|
+
type PlaceholderEquivalence = (a: any, b: any) => boolean;
|
|
3
9
|
declare function assignSequenceIdentifiers(message: Message, sequence?: {
|
|
4
10
|
current: number;
|
|
5
|
-
}): void;
|
|
11
|
+
}, equivalent?: PlaceholderEquivalence): void;
|
|
6
12
|
//#endregion
|
|
7
13
|
//#region src/features/messages/types.d.ts
|
|
8
14
|
declare abstract class Base {
|
|
@@ -60,4 +66,4 @@ declare function convertMessageToIcu(message: Message): string;
|
|
|
60
66
|
//#region src/features/messages/hash.d.ts
|
|
61
67
|
declare function generateHash(input: string, context?: string): string;
|
|
62
68
|
//#endregion
|
|
63
|
-
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, assignSequenceIdentifiers, convertMessageToIcu, generateHash };
|
|
69
|
+
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, PlaceholderEquivalence, assignSequenceIdentifiers, convertMessageToIcu, generateHash };
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
//#region src/features/messages/identifier.d.ts
|
|
2
2
|
declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
3
|
+
/**
|
|
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
|
+
*/
|
|
8
|
+
type PlaceholderEquivalence = (a: any, b: any) => boolean;
|
|
3
9
|
declare function assignSequenceIdentifiers(message: Message, sequence?: {
|
|
4
10
|
current: number;
|
|
5
|
-
}): void;
|
|
11
|
+
}, equivalent?: PlaceholderEquivalence): void;
|
|
6
12
|
//#endregion
|
|
7
13
|
//#region src/features/messages/types.d.ts
|
|
8
14
|
declare abstract class Base {
|
|
@@ -60,4 +66,4 @@ declare function convertMessageToIcu(message: Message): string;
|
|
|
60
66
|
//#region src/features/messages/hash.d.ts
|
|
61
67
|
declare function generateHash(input: string, context?: string): string;
|
|
62
68
|
//#endregion
|
|
63
|
-
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, assignSequenceIdentifiers, convertMessageToIcu, generateHash };
|
|
69
|
+
export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, PlaceholderEquivalence, assignSequenceIdentifiers, convertMessageToIcu, generateHash };
|
|
@@ -1,15 +1,51 @@
|
|
|
1
1
|
import { t as generateHash } from "../../hash-DvzpieJD.mjs";
|
|
2
2
|
//#region src/features/messages/identifier.ts
|
|
3
3
|
const AUTO_INCREMENT_IDENTIFIER = Symbol("auto-increment");
|
|
4
|
-
function assignSequenceIdentifiers(message, sequence = { current: 0 }) {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
function assignSequenceIdentifiers(message, sequence = { current: 0 }, equivalent = () => false) {
|
|
5
|
+
const reserved = collectAssignedIdentifiers(message, equivalent);
|
|
6
|
+
function next() {
|
|
7
|
+
let identifier = `${sequence.current++}`;
|
|
8
|
+
while (reserved.has(identifier)) identifier = `${sequence.current++}`;
|
|
9
|
+
return identifier;
|
|
7
10
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
function walk(message) {
|
|
12
|
+
if (message instanceof ArgumentMessage || message instanceof ElementMessage || message instanceof ChoiceMessage) {
|
|
13
|
+
if (message.identifier === AUTO_INCREMENT_IDENTIFIER) message.identifier = next();
|
|
14
|
+
}
|
|
15
|
+
if (message instanceof CompositeMessage || message instanceof ElementMessage) for (const child of message.children) walk(child);
|
|
16
|
+
if (message instanceof ChoiceMessage) for (const branch of message.branches) {
|
|
17
|
+
if (branch.identifier === AUTO_INCREMENT_IDENTIFIER) branch.identifier = next();
|
|
18
|
+
walk(branch.value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
walk(message);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Collect the identifiers already assigned before this pass runs, so generated
|
|
25
|
+
* sequence numbers never shadow an explicit one (e.g. an element tagged `0`).
|
|
26
|
+
*
|
|
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
|
+
*/
|
|
33
|
+
function collectAssignedIdentifiers(message, equivalent) {
|
|
34
|
+
const tags = /* @__PURE__ */ new Map();
|
|
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
|
+
}
|
|
40
|
+
function walk(message) {
|
|
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
|
+
if (message instanceof CompositeMessage || message instanceof ElementMessage) for (const child of message.children) walk(child);
|
|
44
|
+
if (message instanceof ChoiceMessage) for (const branch of message.branches) walk(branch.value);
|
|
12
45
|
}
|
|
46
|
+
walk(message);
|
|
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.keys()]);
|
|
13
49
|
}
|
|
14
50
|
//#endregion
|
|
15
51
|
//#region src/features/messages/types.ts
|
|
@@ -87,6 +123,7 @@ function convertMessageToIcu(message) {
|
|
|
87
123
|
case message instanceof LiteralMessage: return String(message.text);
|
|
88
124
|
case message instanceof ArgumentMessage: return `{${String(message.identifier)}}`;
|
|
89
125
|
case message instanceof ElementMessage: {
|
|
126
|
+
if (message.children.length === 0) return `<${String(message.identifier)}/>`;
|
|
90
127
|
const children = message.children.map((m) => internalConvertMessageToIcu(m)).join("");
|
|
91
128
|
return `<${String(message.identifier)}>${children}</${String(message.identifier)}>`;
|
|
92
129
|
}
|