@lokascript/framework 2.7.2 → 2.9.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/CHANGELOG.md +393 -0
- package/dist/api/create-dsl.d.ts +93 -1
- package/dist/api/create-dsl.d.ts.map +1 -1
- package/dist/api/domain-registry.d.ts +5 -3
- package/dist/api/domain-registry.d.ts.map +1 -1
- package/dist/api/index.js +238 -20
- package/dist/api/index.js.map +1 -1
- package/dist/core/index.js +67 -7
- package/dist/core/index.js.map +1 -1
- package/dist/core/tokenization/base-tokenizer.d.ts +39 -3
- package/dist/core/tokenization/base-tokenizer.d.ts.map +1 -1
- package/dist/core/tokenization/extractors.d.ts +6 -0
- package/dist/core/tokenization/extractors.d.ts.map +1 -1
- package/dist/core/tokenization/index.js +67 -7
- package/dist/core/tokenization/index.js.map +1 -1
- package/dist/core/tokenization/token-utils.d.ts +15 -0
- package/dist/core/tokenization/token-utils.d.ts.map +1 -1
- package/dist/generation/index.js +75 -48
- package/dist/generation/index.js.map +1 -1
- package/dist/generation/pattern-generator.d.ts +8 -1
- package/dist/generation/pattern-generator.d.ts.map +1 -1
- package/dist/generation/renderer.d.ts +53 -1
- package/dist/generation/renderer.d.ts.map +1 -1
- package/dist/index.cjs +349 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +345 -118
- package/dist/index.js.map +1 -1
- package/dist/interfaces/value-extractor.d.ts +5 -0
- package/dist/interfaces/value-extractor.d.ts.map +1 -1
- package/dist/multilingual/index.js +66 -7
- package/dist/multilingual/index.js.map +1 -1
- package/dist/testing/index.js +4 -12
- package/dist/testing/index.js.map +1 -1
- package/package.json +4 -3
- package/src/api/create-dsl.test.ts +11 -0
- package/src/api/create-dsl.ts +278 -9
- package/src/api/domain-registry.ts +15 -10
- package/src/api/extensions.test.ts +322 -0
- package/src/core/tokenization/base-tokenizer.ts +78 -9
- package/src/core/tokenization/colon-qualifier.test.ts +129 -0
- package/src/core/tokenization/css-selector-extractor.test.ts +67 -0
- package/src/core/tokenization/extractors.ts +6 -0
- package/src/core/tokenization/token-utils.ts +18 -0
- package/src/generation/domain-renderer.test.ts +172 -0
- package/src/generation/pattern-generator.test.ts +102 -0
- package/src/generation/pattern-generator.ts +32 -20
- package/src/generation/renderer.test.ts +243 -4
- package/src/generation/renderer.ts +188 -45
- package/src/index.ts +9 -1
- package/src/interfaces/value-extractor.ts +50 -0
- package/src/ir/protocol-json.test.ts +21 -0
- package/src/ir/references.test.ts +5 -2
- package/src/prompts/prompt-generator.ts +4 -1
package/dist/api/index.js
CHANGED
|
@@ -1282,10 +1282,12 @@ function buildTokens(schema, profile, keyword, alternatives) {
|
|
|
1282
1282
|
addRoleWithMarker(tokens, role, profile);
|
|
1283
1283
|
}
|
|
1284
1284
|
} else if (profile.wordOrder === "SOV") {
|
|
1285
|
+
const preVerb = [];
|
|
1286
|
+
const postVerb = [];
|
|
1285
1287
|
for (const role of sortedRoles) {
|
|
1286
|
-
addRoleWithMarker(
|
|
1288
|
+
addRoleWithMarker(role.sovSlot === "postVerb" ? postVerb : preVerb, role, profile);
|
|
1287
1289
|
}
|
|
1288
|
-
tokens.push(keywordToken);
|
|
1290
|
+
tokens.push(...preVerb, keywordToken, ...postVerb);
|
|
1289
1291
|
} else if (profile.wordOrder === "VSO") {
|
|
1290
1292
|
tokens.push(keywordToken);
|
|
1291
1293
|
for (const role of sortedRoles) {
|
|
@@ -1368,28 +1370,130 @@ function buildExtractionRules(schema, profile) {
|
|
|
1368
1370
|
return rules;
|
|
1369
1371
|
}
|
|
1370
1372
|
function buildFormatString(schema, profile, keyword) {
|
|
1371
|
-
const
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
for (const role of
|
|
1373
|
+
const isSOV = profile.wordOrder === "SOV";
|
|
1374
|
+
const preVerb = [];
|
|
1375
|
+
const postVerb = [];
|
|
1376
|
+
const sortedRoles = sortRolesByWordOrder(schema.roles, profile.wordOrder);
|
|
1377
|
+
for (const role of sortedRoles) {
|
|
1376
1378
|
const marker = getMarkerForRole(role, profile);
|
|
1377
1379
|
const roleName = `{${role.role}}`;
|
|
1380
|
+
const bucket = isSOV && role.sovSlot === "postVerb" ? postVerb : preVerb;
|
|
1378
1381
|
if (marker) {
|
|
1379
1382
|
const markerInfo = profile.roleMarkers?.[role.role];
|
|
1380
1383
|
if (markerInfo?.position === "after") {
|
|
1381
|
-
|
|
1384
|
+
bucket.push(`${roleName} ${marker}`);
|
|
1382
1385
|
} else {
|
|
1383
|
-
|
|
1386
|
+
bucket.push(`${marker} ${roleName}`);
|
|
1384
1387
|
}
|
|
1385
1388
|
} else {
|
|
1386
|
-
|
|
1389
|
+
bucket.push(roleName);
|
|
1387
1390
|
}
|
|
1388
1391
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1392
|
+
return (isSOV ? [...preVerb, keyword, ...postVerb] : [keyword, ...preVerb, ...postVerb]).join(
|
|
1393
|
+
" "
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// src/generation/renderer.ts
|
|
1398
|
+
function lookupKeyword(keywords, action, language) {
|
|
1399
|
+
return keywords[action]?.[language] ?? action;
|
|
1400
|
+
}
|
|
1401
|
+
function buildPhrase(...parts) {
|
|
1402
|
+
return parts.filter(Boolean).join(" ");
|
|
1403
|
+
}
|
|
1404
|
+
function buildTablesFromProfiles(schemas, profiles) {
|
|
1405
|
+
const keywords = {};
|
|
1406
|
+
const markers = {};
|
|
1407
|
+
for (const profile of profiles) {
|
|
1408
|
+
for (const [action, kw] of Object.entries(profile.keywords)) {
|
|
1409
|
+
if (!keywords[action]) keywords[action] = {};
|
|
1410
|
+
keywords[action][profile.code] = kw.primary;
|
|
1411
|
+
}
|
|
1391
1412
|
}
|
|
1392
|
-
|
|
1413
|
+
for (const schema of schemas) {
|
|
1414
|
+
for (const role of schema.roles) {
|
|
1415
|
+
if (role.markerOverride) {
|
|
1416
|
+
const markerKey = role.role;
|
|
1417
|
+
if (!markers[markerKey]) markers[markerKey] = {};
|
|
1418
|
+
for (const [lang, markerText] of Object.entries(role.markerOverride)) {
|
|
1419
|
+
markers[markerKey][lang] = markerText;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
for (const profile of profiles) {
|
|
1425
|
+
if (profile.roleMarkers) {
|
|
1426
|
+
for (const [markerKey, markerDef] of Object.entries(profile.roleMarkers)) {
|
|
1427
|
+
if (!markers[markerKey]) markers[markerKey] = {};
|
|
1428
|
+
markers[markerKey][profile.code] = markerDef.primary;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
return { keywords, markers };
|
|
1433
|
+
}
|
|
1434
|
+
function detectWordOrders(profiles) {
|
|
1435
|
+
const sovLanguages = /* @__PURE__ */ new Set();
|
|
1436
|
+
const vsoLanguages = /* @__PURE__ */ new Set();
|
|
1437
|
+
for (const profile of profiles) {
|
|
1438
|
+
if (profile.wordOrder === "SOV") sovLanguages.add(profile.code);
|
|
1439
|
+
if (profile.wordOrder === "VSO") vsoLanguages.add(profile.code);
|
|
1440
|
+
}
|
|
1441
|
+
return { sovLanguages, vsoLanguages };
|
|
1442
|
+
}
|
|
1443
|
+
function createDomainRenderer(config) {
|
|
1444
|
+
const { schemas, profiles, overrides } = config;
|
|
1445
|
+
let tables;
|
|
1446
|
+
return (node, language) => {
|
|
1447
|
+
const override = overrides?.[node.action];
|
|
1448
|
+
if (override) return override(node, language);
|
|
1449
|
+
tables ?? (tables = buildRenderTables(schemas, profiles));
|
|
1450
|
+
return renderFromSchema(node, language, tables);
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
function buildRenderTables(schemas, profiles) {
|
|
1454
|
+
const { keywords, markers } = buildTablesFromProfiles(schemas, profiles);
|
|
1455
|
+
const { sovLanguages } = detectWordOrders(profiles);
|
|
1456
|
+
const markerPositions = {};
|
|
1457
|
+
for (const profile of profiles) {
|
|
1458
|
+
for (const [role, markerDef] of Object.entries(profile.roleMarkers ?? {})) {
|
|
1459
|
+
if (!markerDef.position) continue;
|
|
1460
|
+
markerPositions[role] ?? (markerPositions[role] = {});
|
|
1461
|
+
markerPositions[role][profile.code] = markerDef.position;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
const schemaMap = /* @__PURE__ */ new Map();
|
|
1465
|
+
for (const s of schemas) schemaMap.set(s.action, s);
|
|
1466
|
+
return { keywords, markers, markerPositions, sovLanguages, schemaMap };
|
|
1467
|
+
}
|
|
1468
|
+
function renderFromSchema(node, language, tables) {
|
|
1469
|
+
const schema = tables.schemaMap.get(node.action);
|
|
1470
|
+
if (!schema) return null;
|
|
1471
|
+
const keyword = lookupKeyword(tables.keywords, node.action, language);
|
|
1472
|
+
const isSOV = tables.sovLanguages.has(language);
|
|
1473
|
+
const ordered = sortRolesByWordOrder([...schema.roles], isSOV ? "SOV" : "SVO");
|
|
1474
|
+
const preVerb = [];
|
|
1475
|
+
const postVerb = [];
|
|
1476
|
+
for (const role of ordered) {
|
|
1477
|
+
let value = extractRoleValue(node, role.role);
|
|
1478
|
+
if (!value && role.default !== void 0) {
|
|
1479
|
+
value = String(extractValue(role.default));
|
|
1480
|
+
}
|
|
1481
|
+
if (!value) continue;
|
|
1482
|
+
if (role.quoteMultiword && /\s/.test(value) && !/^(["']).*\1$/.test(value)) {
|
|
1483
|
+
value = `"${value}"`;
|
|
1484
|
+
}
|
|
1485
|
+
const markerText = role.renderOverride?.[language] ?? role.markerOverride?.[language] ?? role.renderOverride?.["*"] ?? tables.markers[role.role]?.[language];
|
|
1486
|
+
const markerPosition = role.markerPositionOverride?.[language] ?? role.markerPosition ?? tables.markerPositions[role.role]?.[language] ?? (isSOV ? "after" : "before");
|
|
1487
|
+
const bucket = isSOV && role.sovSlot === "postVerb" ? postVerb : preVerb;
|
|
1488
|
+
if (markerText && markerPosition === "before") {
|
|
1489
|
+
bucket.push(markerText, value);
|
|
1490
|
+
} else if (markerText) {
|
|
1491
|
+
bucket.push(value, markerText);
|
|
1492
|
+
} else {
|
|
1493
|
+
bucket.push(value);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
return isSOV ? buildPhrase(...preVerb, keyword, ...postVerb) : buildPhrase(keyword, ...preVerb, ...postVerb);
|
|
1393
1497
|
}
|
|
1394
1498
|
|
|
1395
1499
|
// src/grammar/types.ts
|
|
@@ -1621,10 +1725,17 @@ import { renderExplicit, renderDocument } from "@lokascript/intent";
|
|
|
1621
1725
|
|
|
1622
1726
|
// src/api/create-dsl.ts
|
|
1623
1727
|
var DSLRegistry = class {
|
|
1624
|
-
|
|
1728
|
+
/**
|
|
1729
|
+
* @param partiallyTranslatedActions Actions permitted to lack a keyword in
|
|
1730
|
+
* some configured languages — extension commands, which may be added for a
|
|
1731
|
+
* subset of the DSL's languages. A built-in command missing a keyword stays
|
|
1732
|
+
* an error, since that is a domain-authoring mistake.
|
|
1733
|
+
*/
|
|
1734
|
+
constructor(config, partiallyTranslatedActions = /* @__PURE__ */ new Set()) {
|
|
1625
1735
|
this.patterns = /* @__PURE__ */ new Map();
|
|
1626
1736
|
this.tokenizers = /* @__PURE__ */ new Map();
|
|
1627
1737
|
this.schemas = config.schemas;
|
|
1738
|
+
this.partiallyTranslatedActions = partiallyTranslatedActions;
|
|
1628
1739
|
for (const lang of config.languages) {
|
|
1629
1740
|
this.registerLanguage(lang);
|
|
1630
1741
|
}
|
|
@@ -1633,6 +1744,9 @@ var DSLRegistry = class {
|
|
|
1633
1744
|
this.tokenizers.set(lang.code, lang.tokenizer);
|
|
1634
1745
|
const patterns = [];
|
|
1635
1746
|
for (const schema of this.schemas) {
|
|
1747
|
+
if (this.partiallyTranslatedActions.has(schema.action) && !lang.patternProfile.keywords[schema.action]) {
|
|
1748
|
+
continue;
|
|
1749
|
+
}
|
|
1636
1750
|
const pattern = generatePattern(schema, lang.patternProfile);
|
|
1637
1751
|
patterns.push(pattern);
|
|
1638
1752
|
}
|
|
@@ -1649,13 +1763,25 @@ var DSLRegistry = class {
|
|
|
1649
1763
|
}
|
|
1650
1764
|
};
|
|
1651
1765
|
var MultilingualDSLImpl = class {
|
|
1652
|
-
constructor(config, registry, transformer) {
|
|
1766
|
+
constructor(config, registry, transformer, profileProvider) {
|
|
1653
1767
|
this.registry = registry;
|
|
1654
1768
|
this.matcher = new PatternMatcher();
|
|
1655
1769
|
this.transformer = transformer;
|
|
1770
|
+
this.profileProvider = profileProvider;
|
|
1656
1771
|
if (config.codeGenerator) {
|
|
1657
1772
|
this.codeGenerator = config.codeGenerator;
|
|
1658
1773
|
}
|
|
1774
|
+
if (config.renderer) {
|
|
1775
|
+
this.domainRenderer = config.renderer;
|
|
1776
|
+
}
|
|
1777
|
+
this.extensionRenderers = /* @__PURE__ */ new Map();
|
|
1778
|
+
for (const extension of config.extensions ?? []) {
|
|
1779
|
+
if (extension.render) this.extensionRenderers.set(extension.schema.action, extension.render);
|
|
1780
|
+
}
|
|
1781
|
+
this.schemaFallbackRenderer = createDomainRenderer({
|
|
1782
|
+
schemas: config.schemas,
|
|
1783
|
+
profiles: config.languages.map((l) => l.patternProfile)
|
|
1784
|
+
});
|
|
1659
1785
|
const schemaMap = new Map(config.schemas.map((s) => [s.action, s]));
|
|
1660
1786
|
this.schemaLookup = {
|
|
1661
1787
|
getSchema: (action) => schemaMap.get(action)
|
|
@@ -1717,6 +1843,13 @@ var MultilingualDSLImpl = class {
|
|
|
1717
1843
|
}
|
|
1718
1844
|
translate(input, fromLanguage, toLanguage) {
|
|
1719
1845
|
if (isExplicitSyntax(input)) return input;
|
|
1846
|
+
for (const language of [fromLanguage, toLanguage]) {
|
|
1847
|
+
if (!this.profileProvider.getProfile(language)) {
|
|
1848
|
+
throw new Error(
|
|
1849
|
+
`translate() requires a grammar profile for language "${language}", but none is configured. Set 'grammarProfile' on the LanguageConfig for "${language}" in createMultilingualDSL() (parse/validate/compile do not need it), or inject a custom 'profileProvider'.`
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1720
1853
|
return this.transformer.transform(input, fromLanguage, toLanguage);
|
|
1721
1854
|
}
|
|
1722
1855
|
compile(input, language) {
|
|
@@ -1745,6 +1878,18 @@ var MultilingualDSLImpl = class {
|
|
|
1745
1878
|
};
|
|
1746
1879
|
}
|
|
1747
1880
|
}
|
|
1881
|
+
render(node, language) {
|
|
1882
|
+
const extensionRenderer = this.extensionRenderers.get(node.action);
|
|
1883
|
+
if (extensionRenderer) {
|
|
1884
|
+
const rendered = extensionRenderer(node, language);
|
|
1885
|
+
if (rendered != null) return rendered;
|
|
1886
|
+
}
|
|
1887
|
+
if (this.domainRenderer) {
|
|
1888
|
+
const rendered = this.domainRenderer(node, language);
|
|
1889
|
+
if (rendered != null) return rendered;
|
|
1890
|
+
}
|
|
1891
|
+
return this.schemaFallbackRenderer(node, language);
|
|
1892
|
+
}
|
|
1748
1893
|
getSupportedLanguages() {
|
|
1749
1894
|
return this.registry.getSupportedLanguages();
|
|
1750
1895
|
}
|
|
@@ -1769,15 +1914,80 @@ function createDefaultProfileProvider(config) {
|
|
|
1769
1914
|
}
|
|
1770
1915
|
return new InMemoryProfileProvider(profiles);
|
|
1771
1916
|
}
|
|
1917
|
+
function applyExtensions(config) {
|
|
1918
|
+
const extensions = config.extensions;
|
|
1919
|
+
if (!extensions || extensions.length === 0) return config;
|
|
1920
|
+
const configuredLanguages = new Set(config.languages.map((l) => l.code));
|
|
1921
|
+
const actions = new Set(config.schemas.map((s) => s.action));
|
|
1922
|
+
for (const extension of extensions) {
|
|
1923
|
+
const { action } = extension.schema;
|
|
1924
|
+
if (actions.has(action)) {
|
|
1925
|
+
throw new Error(
|
|
1926
|
+
`Extension command "${action}" collides with a command this DSL already defines. Pick a different action name.`
|
|
1927
|
+
);
|
|
1928
|
+
}
|
|
1929
|
+
actions.add(action);
|
|
1930
|
+
for (const code of Object.keys(extension.vocabulary)) {
|
|
1931
|
+
if (!configuredLanguages.has(code)) {
|
|
1932
|
+
throw new Error(
|
|
1933
|
+
`Extension command "${action}" supplies vocabulary for language "${code}", which is not configured on this DSL. Configured languages: ${[...configuredLanguages].join(", ")}.`
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
const schemas = [...config.schemas, ...extensions.map((e) => e.schema)];
|
|
1939
|
+
const languages = config.languages.map((lang) => {
|
|
1940
|
+
const keywords = { ...lang.patternProfile.keywords };
|
|
1941
|
+
let roleMarkers = lang.patternProfile.roleMarkers;
|
|
1942
|
+
for (const extension of extensions) {
|
|
1943
|
+
const vocabulary = extension.vocabulary[lang.code];
|
|
1944
|
+
if (!vocabulary) continue;
|
|
1945
|
+
keywords[extension.schema.action] = { ...vocabulary.keyword };
|
|
1946
|
+
if (vocabulary.roleMarkers) {
|
|
1947
|
+
roleMarkers = { ...roleMarkers, ...vocabulary.roleMarkers };
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
return {
|
|
1951
|
+
...lang,
|
|
1952
|
+
patternProfile: {
|
|
1953
|
+
...lang.patternProfile,
|
|
1954
|
+
keywords,
|
|
1955
|
+
...roleMarkers !== void 0 && { roleMarkers }
|
|
1956
|
+
}
|
|
1957
|
+
};
|
|
1958
|
+
});
|
|
1959
|
+
const extensionGenerators = new Map(
|
|
1960
|
+
extensions.filter((e) => e.generate).map((e) => [e.schema.action, e.generate])
|
|
1961
|
+
);
|
|
1962
|
+
const baseGenerator = config.codeGenerator;
|
|
1963
|
+
const codeGenerator = extensionGenerators.size > 0 ? {
|
|
1964
|
+
generate(node) {
|
|
1965
|
+
const generate = extensionGenerators.get(node.action);
|
|
1966
|
+
if (generate) return generate(node);
|
|
1967
|
+
if (!baseGenerator) {
|
|
1968
|
+
throw new Error(`No code generator for action "${node.action}"`);
|
|
1969
|
+
}
|
|
1970
|
+
return baseGenerator.generate(node);
|
|
1971
|
+
}
|
|
1972
|
+
} : baseGenerator;
|
|
1973
|
+
return {
|
|
1974
|
+
...config,
|
|
1975
|
+
schemas,
|
|
1976
|
+
languages,
|
|
1977
|
+
...codeGenerator !== void 0 && { codeGenerator }
|
|
1978
|
+
};
|
|
1979
|
+
}
|
|
1772
1980
|
function createMultilingualDSL(config) {
|
|
1773
|
-
const
|
|
1774
|
-
const
|
|
1981
|
+
const effectiveConfig = applyExtensions(config);
|
|
1982
|
+
const extensionActions = new Set((config.extensions ?? []).map((e) => e.schema.action));
|
|
1983
|
+
const dictionary = effectiveConfig.dictionary ?? createDefaultDictionary(effectiveConfig);
|
|
1984
|
+
const profileProvider = effectiveConfig.profileProvider ?? createDefaultProfileProvider(effectiveConfig);
|
|
1775
1985
|
const transformer = new GrammarTransformer({
|
|
1776
1986
|
dictionary,
|
|
1777
1987
|
profileProvider
|
|
1778
1988
|
});
|
|
1779
|
-
const registry = new DSLRegistry(
|
|
1780
|
-
return new MultilingualDSLImpl(
|
|
1989
|
+
const registry = new DSLRegistry(effectiveConfig, extensionActions);
|
|
1990
|
+
return new MultilingualDSLImpl(effectiveConfig, registry, transformer, profileProvider);
|
|
1781
1991
|
}
|
|
1782
1992
|
|
|
1783
1993
|
// src/prompts/prompt-generator.ts
|
|
@@ -1855,7 +2065,9 @@ function buildProtocolSection() {
|
|
|
1855
2065
|
3. No spaces around the colon in role:value pairs
|
|
1856
2066
|
4. Strings with spaces must be quoted: \`patient:"hello world"\`
|
|
1857
2067
|
5. Selectors start with \`#\`, \`.\`, \`[\`, \`@\`, or \`*\`
|
|
1858
|
-
6.
|
|
2068
|
+
6. A selector containing a space, a combinator (\`>\` \`+\` \`~\`), or a comma must use a selector literal: \`patient:<ul > li/>\`, \`patient:<.a, .b/>\`
|
|
2069
|
+
7. Inside a structural role (\`body\`, \`then\`, \`else\`, \`condition\`, \`loop-body\`, \`variable\`, \`catch\`, \`finally\`) a \`[...]\` value is always a nested command. Write an attribute selector there as \`condition:<[data-active]/>\`
|
|
2070
|
+
8. Output must be valid bracket syntax: \`[action role:value ...]\``;
|
|
1859
2071
|
return {
|
|
1860
2072
|
id: "protocol",
|
|
1861
2073
|
title: "LSE Protocol",
|
|
@@ -1868,6 +2080,7 @@ function buildValueTypeSection() {
|
|
|
1868
2080
|
|
|
1869
2081
|
| Type | Syntax | Example |
|
|
1870
2082
|
|------|--------|---------|
|
|
2083
|
+
| Selector literal | Delimited by \`<\` and \`/>\` | \`<ul > li/>\`, \`<.a, .b/>\`, \`<[data-id]/>\` |
|
|
1871
2084
|
| Selector | Starts with \`#\` \`.\` \`[\` \`@\` \`*\` | \`#button\`, \`.active\`, \`[data-id]\` |
|
|
1872
2085
|
| String | Quoted with \`"\` or \`'\` | \`"hello world"\`, \`'json'\` |
|
|
1873
2086
|
| Boolean | Exact: \`true\` / \`false\` | \`visible:true\` |
|
|
@@ -2736,6 +2949,11 @@ var DomainRegistry = class {
|
|
|
2736
2949
|
rendered = typeof renderer === "function" ? renderer(node, to) : renderer.render(node, to);
|
|
2737
2950
|
} catch {
|
|
2738
2951
|
}
|
|
2952
|
+
} else if (dsl.render) {
|
|
2953
|
+
try {
|
|
2954
|
+
rendered = dsl.render(node, to);
|
|
2955
|
+
} catch {
|
|
2956
|
+
}
|
|
2739
2957
|
}
|
|
2740
2958
|
const roles = {};
|
|
2741
2959
|
for (const [key, value] of node.roles) {
|