@hyperfixi/core 2.0.0 → 2.1.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/dist/api/hyperscript-api.d.ts +2 -0
- package/dist/ast-utils/index.d.ts +1 -1
- package/dist/ast-utils/index.js +11 -1
- package/dist/ast-utils/index.mjs +11 -1
- package/dist/ast-utils/interchange/index.d.ts +1 -1
- package/dist/ast-utils/interchange/lsp.d.ts +4 -1
- package/dist/behaviors/index.js +13 -5
- package/dist/behaviors/index.mjs +13 -5
- package/dist/bundle-generator/index.js +9 -0
- package/dist/bundle-generator/index.mjs +9 -0
- package/dist/chunks/{bridge-I6ceoWxV.js → bridge-CZfeDyEz.js} +2 -2
- package/dist/chunks/browser-modular-CwTpxqdt.js +2 -0
- package/dist/chunks/feature-eventsource-B5F2-H1r.js +2 -0
- package/dist/chunks/feature-sockets-ClOH7vk7.js +2 -0
- package/dist/chunks/feature-webworker-3bAp0ac9.js +2 -0
- package/dist/commands/index.js +27 -6
- package/dist/commands/index.mjs +27 -6
- package/dist/debug/debug-controller.d.ts +62 -0
- package/dist/debug/index.d.ts +5 -0
- package/dist/expressions/index.js +16 -52
- package/dist/expressions/index.mjs +16 -52
- package/dist/hyperfixi-classic-i18n.js +1 -1
- package/dist/hyperfixi-hx.js +1 -1
- package/dist/hyperfixi-hybrid-complete.js +1 -1
- package/dist/hyperfixi-minimal.js +1 -1
- package/dist/hyperfixi-multilingual.js +1 -1
- package/dist/hyperfixi-standard.js +1 -1
- package/dist/hyperfixi.js +1 -1
- package/dist/hyperfixi.mjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +10112 -6941
- package/dist/index.min.js +1 -1
- package/dist/index.mjs +10111 -6942
- package/dist/lokascript-browser-classic-i18n.js +1 -1
- package/dist/lokascript-browser-minimal.js +1 -1
- package/dist/lokascript-browser-standard.js +1 -1
- package/dist/lokascript-browser.js +1 -1
- package/dist/lokascript-hybrid-complete.js +1 -1
- package/dist/lokascript-hybrid-hx.js +1 -1
- package/dist/lokascript-multilingual.js +1 -1
- package/dist/metadata.d.ts +4 -4
- package/dist/metadata.js +4 -4
- package/dist/metadata.mjs +4 -4
- package/dist/parser/full-parser.js +12 -31
- package/dist/parser/full-parser.mjs +12 -31
- package/dist/parser/hybrid/index.js +35 -2
- package/dist/parser/hybrid/index.mjs +35 -2
- package/dist/parser/hybrid/parser-core.d.ts +1 -0
- package/dist/parser/hybrid/parser-core.js +35 -2
- package/dist/parser/hybrid/parser-core.mjs +35 -2
- package/dist/parser/hybrid/tokenizer.js +5 -0
- package/dist/parser/hybrid/tokenizer.mjs +5 -0
- package/dist/parser/hybrid-parser.js +35 -2
- package/dist/parser/hybrid-parser.mjs +35 -2
- package/dist/registry/index.js +16 -52
- package/dist/registry/index.mjs +16 -52
- package/dist/runtime/runtime-base.d.ts +1 -0
- package/package.json +5 -5
- package/dist/chunks/browser-modular-Dv6PAV3c.js +0 -2
- package/dist/chunks/feature-eventsource-DWb514fy.js +0 -2
- package/dist/chunks/feature-sockets-3PFuvCVY.js +0 -2
- package/dist/chunks/feature-webworker-DTm_eh-E.js +0 -2
package/dist/metadata.d.ts
CHANGED
|
@@ -79,14 +79,14 @@ export declare const ecosystem: {
|
|
|
79
79
|
readonly npm: "https://www.npmjs.com/package/@hyperfixi/vite-plugin";
|
|
80
80
|
};
|
|
81
81
|
readonly patternsReference: {
|
|
82
|
-
readonly name: "@
|
|
82
|
+
readonly name: "@hyperfixi/patterns-reference";
|
|
83
83
|
readonly description: "Pattern database with 212 LLM examples";
|
|
84
|
-
readonly npm: "https://www.npmjs.com/package/@
|
|
84
|
+
readonly npm: "https://www.npmjs.com/package/@hyperfixi/patterns-reference";
|
|
85
85
|
};
|
|
86
86
|
readonly mcpServer: {
|
|
87
|
-
readonly name: "@
|
|
87
|
+
readonly name: "@hyperfixi/mcp-server";
|
|
88
88
|
readonly description: "Model Context Protocol server for AI assistants";
|
|
89
|
-
readonly npm: "https://www.npmjs.com/package/@
|
|
89
|
+
readonly npm: "https://www.npmjs.com/package/@hyperfixi/mcp-server";
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
92
|
export declare const supportedLanguages: readonly [{
|
package/dist/metadata.js
CHANGED
|
@@ -329,14 +329,14 @@ const ecosystem = {
|
|
|
329
329
|
npm: 'https://www.npmjs.com/package/@hyperfixi/vite-plugin',
|
|
330
330
|
},
|
|
331
331
|
patternsReference: {
|
|
332
|
-
name: '@
|
|
332
|
+
name: '@hyperfixi/patterns-reference',
|
|
333
333
|
description: 'Pattern database with 212 LLM examples',
|
|
334
|
-
npm: 'https://www.npmjs.com/package/@
|
|
334
|
+
npm: 'https://www.npmjs.com/package/@hyperfixi/patterns-reference',
|
|
335
335
|
},
|
|
336
336
|
mcpServer: {
|
|
337
|
-
name: '@
|
|
337
|
+
name: '@hyperfixi/mcp-server',
|
|
338
338
|
description: 'Model Context Protocol server for AI assistants',
|
|
339
|
-
npm: 'https://www.npmjs.com/package/@
|
|
339
|
+
npm: 'https://www.npmjs.com/package/@hyperfixi/mcp-server',
|
|
340
340
|
},
|
|
341
341
|
};
|
|
342
342
|
const supportedLanguages = [
|
package/dist/metadata.mjs
CHANGED
|
@@ -327,14 +327,14 @@ const ecosystem = {
|
|
|
327
327
|
npm: 'https://www.npmjs.com/package/@hyperfixi/vite-plugin',
|
|
328
328
|
},
|
|
329
329
|
patternsReference: {
|
|
330
|
-
name: '@
|
|
330
|
+
name: '@hyperfixi/patterns-reference',
|
|
331
331
|
description: 'Pattern database with 212 LLM examples',
|
|
332
|
-
npm: 'https://www.npmjs.com/package/@
|
|
332
|
+
npm: 'https://www.npmjs.com/package/@hyperfixi/patterns-reference',
|
|
333
333
|
},
|
|
334
334
|
mcpServer: {
|
|
335
|
-
name: '@
|
|
335
|
+
name: '@hyperfixi/mcp-server',
|
|
336
336
|
description: 'Model Context Protocol server for AI assistants',
|
|
337
|
-
npm: 'https://www.npmjs.com/package/@
|
|
337
|
+
npm: 'https://www.npmjs.com/package/@hyperfixi/mcp-server',
|
|
338
338
|
},
|
|
339
339
|
};
|
|
340
340
|
const supportedLanguages = [
|
|
@@ -4744,6 +4744,17 @@ class Parser {
|
|
|
4744
4744
|
if (token.value === 'the') {
|
|
4745
4745
|
return this.parseTheXofY();
|
|
4746
4746
|
}
|
|
4747
|
+
if (token.value === 'values' && this.check('of')) {
|
|
4748
|
+
this.advance();
|
|
4749
|
+
const target = this.parsePrimary();
|
|
4750
|
+
return {
|
|
4751
|
+
type: 'propertyOfExpression',
|
|
4752
|
+
property: { type: 'identifier', name: 'values' },
|
|
4753
|
+
target,
|
|
4754
|
+
line: token.line,
|
|
4755
|
+
column: token.column,
|
|
4756
|
+
};
|
|
4757
|
+
}
|
|
4747
4758
|
return this.createIdentifier(token.value);
|
|
4748
4759
|
}
|
|
4749
4760
|
if (this.match('$')) {
|
|
@@ -5549,36 +5560,7 @@ class Parser {
|
|
|
5549
5560
|
}
|
|
5550
5561
|
}
|
|
5551
5562
|
}
|
|
5552
|
-
const handlerCommands =
|
|
5553
|
-
while (!this.isAtEnd() && !this.check('end')) {
|
|
5554
|
-
if (this.checkIsCommand() || this.isCommand(this.peek().value)) {
|
|
5555
|
-
this.advance();
|
|
5556
|
-
const savedError = this.error;
|
|
5557
|
-
try {
|
|
5558
|
-
const cmd = this.parseCommand();
|
|
5559
|
-
if (this.error && this.error !== savedError) {
|
|
5560
|
-
this.error = savedError;
|
|
5561
|
-
}
|
|
5562
|
-
handlerCommands.push(cmd);
|
|
5563
|
-
while (!this.isAtEnd() &&
|
|
5564
|
-
!this.check('end') &&
|
|
5565
|
-
!this.checkIsCommand() &&
|
|
5566
|
-
!this.isCommand(this.peek().value)) {
|
|
5567
|
-
this.advance();
|
|
5568
|
-
}
|
|
5569
|
-
}
|
|
5570
|
-
catch (error) {
|
|
5571
|
-
this.error = savedError;
|
|
5572
|
-
break;
|
|
5573
|
-
}
|
|
5574
|
-
}
|
|
5575
|
-
else {
|
|
5576
|
-
if (!this.check('end')) {
|
|
5577
|
-
this.addError(`Unexpected token in event handler: ${this.peek().value}`);
|
|
5578
|
-
}
|
|
5579
|
-
break;
|
|
5580
|
-
}
|
|
5581
|
-
}
|
|
5563
|
+
const handlerCommands = this.parseCommandListUntilEnd();
|
|
5582
5564
|
const handlerNode = {
|
|
5583
5565
|
type: 'eventHandler',
|
|
5584
5566
|
event: eventName,
|
|
@@ -5591,7 +5573,6 @@ class Parser {
|
|
|
5591
5573
|
column: handlerPos.column,
|
|
5592
5574
|
};
|
|
5593
5575
|
eventHandlers.push(handlerNode);
|
|
5594
|
-
this.consume('end', "Expected 'end' after event handler body");
|
|
5595
5576
|
}
|
|
5596
5577
|
else if (this.match('init')) {
|
|
5597
5578
|
const initCommands = this.parseCommandBlock(['end']);
|
|
@@ -4742,6 +4742,17 @@ class Parser {
|
|
|
4742
4742
|
if (token.value === 'the') {
|
|
4743
4743
|
return this.parseTheXofY();
|
|
4744
4744
|
}
|
|
4745
|
+
if (token.value === 'values' && this.check('of')) {
|
|
4746
|
+
this.advance();
|
|
4747
|
+
const target = this.parsePrimary();
|
|
4748
|
+
return {
|
|
4749
|
+
type: 'propertyOfExpression',
|
|
4750
|
+
property: { type: 'identifier', name: 'values' },
|
|
4751
|
+
target,
|
|
4752
|
+
line: token.line,
|
|
4753
|
+
column: token.column,
|
|
4754
|
+
};
|
|
4755
|
+
}
|
|
4745
4756
|
return this.createIdentifier(token.value);
|
|
4746
4757
|
}
|
|
4747
4758
|
if (this.match('$')) {
|
|
@@ -5547,36 +5558,7 @@ class Parser {
|
|
|
5547
5558
|
}
|
|
5548
5559
|
}
|
|
5549
5560
|
}
|
|
5550
|
-
const handlerCommands =
|
|
5551
|
-
while (!this.isAtEnd() && !this.check('end')) {
|
|
5552
|
-
if (this.checkIsCommand() || this.isCommand(this.peek().value)) {
|
|
5553
|
-
this.advance();
|
|
5554
|
-
const savedError = this.error;
|
|
5555
|
-
try {
|
|
5556
|
-
const cmd = this.parseCommand();
|
|
5557
|
-
if (this.error && this.error !== savedError) {
|
|
5558
|
-
this.error = savedError;
|
|
5559
|
-
}
|
|
5560
|
-
handlerCommands.push(cmd);
|
|
5561
|
-
while (!this.isAtEnd() &&
|
|
5562
|
-
!this.check('end') &&
|
|
5563
|
-
!this.checkIsCommand() &&
|
|
5564
|
-
!this.isCommand(this.peek().value)) {
|
|
5565
|
-
this.advance();
|
|
5566
|
-
}
|
|
5567
|
-
}
|
|
5568
|
-
catch (error) {
|
|
5569
|
-
this.error = savedError;
|
|
5570
|
-
break;
|
|
5571
|
-
}
|
|
5572
|
-
}
|
|
5573
|
-
else {
|
|
5574
|
-
if (!this.check('end')) {
|
|
5575
|
-
this.addError(`Unexpected token in event handler: ${this.peek().value}`);
|
|
5576
|
-
}
|
|
5577
|
-
break;
|
|
5578
|
-
}
|
|
5579
|
-
}
|
|
5561
|
+
const handlerCommands = this.parseCommandListUntilEnd();
|
|
5580
5562
|
const handlerNode = {
|
|
5581
5563
|
type: 'eventHandler',
|
|
5582
5564
|
event: eventName,
|
|
@@ -5589,7 +5571,6 @@ class Parser {
|
|
|
5589
5571
|
column: handlerPos.column,
|
|
5590
5572
|
};
|
|
5591
5573
|
eventHandlers.push(handlerNode);
|
|
5592
|
-
this.consume('end', "Expected 'end' after event handler body");
|
|
5593
5574
|
}
|
|
5594
5575
|
else if (this.match('init')) {
|
|
5595
5576
|
const initCommands = this.parseCommandBlock(['end']);
|
|
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
|
|
|
78
78
|
'init',
|
|
79
79
|
'every',
|
|
80
80
|
'by',
|
|
81
|
+
'halt',
|
|
82
|
+
'via',
|
|
83
|
+
'values',
|
|
84
|
+
'default',
|
|
85
|
+
'event',
|
|
81
86
|
]);
|
|
82
87
|
function tokenize(code) {
|
|
83
88
|
const tokens = [];
|
|
@@ -403,6 +408,7 @@ class HybridParser {
|
|
|
403
408
|
go: () => this.parseGo(),
|
|
404
409
|
return: () => this.parseReturn(),
|
|
405
410
|
transition: () => this.parseTransition(),
|
|
411
|
+
halt: () => this.parseHalt(),
|
|
406
412
|
};
|
|
407
413
|
const normalized = normalizeCommand(this.peek().value);
|
|
408
414
|
if (cmdMap[normalized]) {
|
|
@@ -470,11 +476,17 @@ class HybridParser {
|
|
|
470
476
|
const url = this.parseExpression();
|
|
471
477
|
let responseType = { type: 'literal', value: 'text' };
|
|
472
478
|
let options;
|
|
479
|
+
let method;
|
|
473
480
|
if (this.match('{')) {
|
|
474
481
|
this.pos--;
|
|
475
482
|
options = this.parseExpression();
|
|
476
483
|
}
|
|
477
|
-
for (let i = 0; i <
|
|
484
|
+
for (let i = 0; i < 3; i++) {
|
|
485
|
+
if (this.match('via') && !method) {
|
|
486
|
+
this.advance();
|
|
487
|
+
method = this.parseExpression();
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
478
490
|
if (this.match('as')) {
|
|
479
491
|
this.advance();
|
|
480
492
|
if (this.match('a') || this.match('an'))
|
|
@@ -492,7 +504,11 @@ class HybridParser {
|
|
|
492
504
|
if (this.match('then'))
|
|
493
505
|
this.advance();
|
|
494
506
|
const body = this.parseCommandSequence();
|
|
495
|
-
return {
|
|
507
|
+
return {
|
|
508
|
+
type: 'fetch',
|
|
509
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
510
|
+
body,
|
|
511
|
+
};
|
|
496
512
|
}
|
|
497
513
|
parseToggle() {
|
|
498
514
|
this.expect('toggle');
|
|
@@ -683,6 +699,14 @@ class HybridParser {
|
|
|
683
699
|
}
|
|
684
700
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
685
701
|
}
|
|
702
|
+
parseHalt() {
|
|
703
|
+
this.expect('halt');
|
|
704
|
+
if (this.match('the'))
|
|
705
|
+
this.advance();
|
|
706
|
+
if (this.match('event', 'default'))
|
|
707
|
+
this.advance();
|
|
708
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
709
|
+
}
|
|
686
710
|
parseTransition() {
|
|
687
711
|
this.expect('transition');
|
|
688
712
|
let target;
|
|
@@ -959,6 +983,15 @@ class HybridParser {
|
|
|
959
983
|
const target = this.parsePositionalTarget();
|
|
960
984
|
return { type: 'positional', position, target };
|
|
961
985
|
}
|
|
986
|
+
if (this.match('values')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
if (this.match('of')) {
|
|
989
|
+
this.advance();
|
|
990
|
+
const target = this.parseExpression();
|
|
991
|
+
return { type: 'valuesOf', target };
|
|
992
|
+
}
|
|
993
|
+
return { type: 'identifier', value: token.value };
|
|
994
|
+
}
|
|
962
995
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
963
996
|
this.advance();
|
|
964
997
|
return { type: 'identifier', value: token.value };
|
|
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
|
|
|
76
76
|
'init',
|
|
77
77
|
'every',
|
|
78
78
|
'by',
|
|
79
|
+
'halt',
|
|
80
|
+
'via',
|
|
81
|
+
'values',
|
|
82
|
+
'default',
|
|
83
|
+
'event',
|
|
79
84
|
]);
|
|
80
85
|
function tokenize(code) {
|
|
81
86
|
const tokens = [];
|
|
@@ -401,6 +406,7 @@ class HybridParser {
|
|
|
401
406
|
go: () => this.parseGo(),
|
|
402
407
|
return: () => this.parseReturn(),
|
|
403
408
|
transition: () => this.parseTransition(),
|
|
409
|
+
halt: () => this.parseHalt(),
|
|
404
410
|
};
|
|
405
411
|
const normalized = normalizeCommand(this.peek().value);
|
|
406
412
|
if (cmdMap[normalized]) {
|
|
@@ -468,11 +474,17 @@ class HybridParser {
|
|
|
468
474
|
const url = this.parseExpression();
|
|
469
475
|
let responseType = { type: 'literal', value: 'text' };
|
|
470
476
|
let options;
|
|
477
|
+
let method;
|
|
471
478
|
if (this.match('{')) {
|
|
472
479
|
this.pos--;
|
|
473
480
|
options = this.parseExpression();
|
|
474
481
|
}
|
|
475
|
-
for (let i = 0; i <
|
|
482
|
+
for (let i = 0; i < 3; i++) {
|
|
483
|
+
if (this.match('via') && !method) {
|
|
484
|
+
this.advance();
|
|
485
|
+
method = this.parseExpression();
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
476
488
|
if (this.match('as')) {
|
|
477
489
|
this.advance();
|
|
478
490
|
if (this.match('a') || this.match('an'))
|
|
@@ -490,7 +502,11 @@ class HybridParser {
|
|
|
490
502
|
if (this.match('then'))
|
|
491
503
|
this.advance();
|
|
492
504
|
const body = this.parseCommandSequence();
|
|
493
|
-
return {
|
|
505
|
+
return {
|
|
506
|
+
type: 'fetch',
|
|
507
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
508
|
+
body,
|
|
509
|
+
};
|
|
494
510
|
}
|
|
495
511
|
parseToggle() {
|
|
496
512
|
this.expect('toggle');
|
|
@@ -681,6 +697,14 @@ class HybridParser {
|
|
|
681
697
|
}
|
|
682
698
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
683
699
|
}
|
|
700
|
+
parseHalt() {
|
|
701
|
+
this.expect('halt');
|
|
702
|
+
if (this.match('the'))
|
|
703
|
+
this.advance();
|
|
704
|
+
if (this.match('event', 'default'))
|
|
705
|
+
this.advance();
|
|
706
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
707
|
+
}
|
|
684
708
|
parseTransition() {
|
|
685
709
|
this.expect('transition');
|
|
686
710
|
let target;
|
|
@@ -957,6 +981,15 @@ class HybridParser {
|
|
|
957
981
|
const target = this.parsePositionalTarget();
|
|
958
982
|
return { type: 'positional', position, target };
|
|
959
983
|
}
|
|
984
|
+
if (this.match('values')) {
|
|
985
|
+
this.advance();
|
|
986
|
+
if (this.match('of')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
const target = this.parseExpression();
|
|
989
|
+
return { type: 'valuesOf', target };
|
|
990
|
+
}
|
|
991
|
+
return { type: 'identifier', value: token.value };
|
|
992
|
+
}
|
|
960
993
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
961
994
|
this.advance();
|
|
962
995
|
return { type: 'identifier', value: token.value };
|
|
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
|
|
|
78
78
|
'init',
|
|
79
79
|
'every',
|
|
80
80
|
'by',
|
|
81
|
+
'halt',
|
|
82
|
+
'via',
|
|
83
|
+
'values',
|
|
84
|
+
'default',
|
|
85
|
+
'event',
|
|
81
86
|
]);
|
|
82
87
|
function tokenize(code) {
|
|
83
88
|
const tokens = [];
|
|
@@ -397,6 +402,7 @@ class HybridParser {
|
|
|
397
402
|
go: () => this.parseGo(),
|
|
398
403
|
return: () => this.parseReturn(),
|
|
399
404
|
transition: () => this.parseTransition(),
|
|
405
|
+
halt: () => this.parseHalt(),
|
|
400
406
|
};
|
|
401
407
|
const normalized = normalizeCommand(this.peek().value);
|
|
402
408
|
if (cmdMap[normalized]) {
|
|
@@ -464,11 +470,17 @@ class HybridParser {
|
|
|
464
470
|
const url = this.parseExpression();
|
|
465
471
|
let responseType = { type: 'literal', value: 'text' };
|
|
466
472
|
let options;
|
|
473
|
+
let method;
|
|
467
474
|
if (this.match('{')) {
|
|
468
475
|
this.pos--;
|
|
469
476
|
options = this.parseExpression();
|
|
470
477
|
}
|
|
471
|
-
for (let i = 0; i <
|
|
478
|
+
for (let i = 0; i < 3; i++) {
|
|
479
|
+
if (this.match('via') && !method) {
|
|
480
|
+
this.advance();
|
|
481
|
+
method = this.parseExpression();
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
472
484
|
if (this.match('as')) {
|
|
473
485
|
this.advance();
|
|
474
486
|
if (this.match('a') || this.match('an'))
|
|
@@ -486,7 +498,11 @@ class HybridParser {
|
|
|
486
498
|
if (this.match('then'))
|
|
487
499
|
this.advance();
|
|
488
500
|
const body = this.parseCommandSequence();
|
|
489
|
-
return {
|
|
501
|
+
return {
|
|
502
|
+
type: 'fetch',
|
|
503
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
504
|
+
body,
|
|
505
|
+
};
|
|
490
506
|
}
|
|
491
507
|
parseToggle() {
|
|
492
508
|
this.expect('toggle');
|
|
@@ -677,6 +693,14 @@ class HybridParser {
|
|
|
677
693
|
}
|
|
678
694
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
679
695
|
}
|
|
696
|
+
parseHalt() {
|
|
697
|
+
this.expect('halt');
|
|
698
|
+
if (this.match('the'))
|
|
699
|
+
this.advance();
|
|
700
|
+
if (this.match('event', 'default'))
|
|
701
|
+
this.advance();
|
|
702
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
703
|
+
}
|
|
680
704
|
parseTransition() {
|
|
681
705
|
this.expect('transition');
|
|
682
706
|
let target;
|
|
@@ -953,6 +977,15 @@ class HybridParser {
|
|
|
953
977
|
const target = this.parsePositionalTarget();
|
|
954
978
|
return { type: 'positional', position, target };
|
|
955
979
|
}
|
|
980
|
+
if (this.match('values')) {
|
|
981
|
+
this.advance();
|
|
982
|
+
if (this.match('of')) {
|
|
983
|
+
this.advance();
|
|
984
|
+
const target = this.parseExpression();
|
|
985
|
+
return { type: 'valuesOf', target };
|
|
986
|
+
}
|
|
987
|
+
return { type: 'identifier', value: token.value };
|
|
988
|
+
}
|
|
956
989
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
957
990
|
this.advance();
|
|
958
991
|
return { type: 'identifier', value: token.value };
|
|
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
|
|
|
76
76
|
'init',
|
|
77
77
|
'every',
|
|
78
78
|
'by',
|
|
79
|
+
'halt',
|
|
80
|
+
'via',
|
|
81
|
+
'values',
|
|
82
|
+
'default',
|
|
83
|
+
'event',
|
|
79
84
|
]);
|
|
80
85
|
function tokenize(code) {
|
|
81
86
|
const tokens = [];
|
|
@@ -395,6 +400,7 @@ class HybridParser {
|
|
|
395
400
|
go: () => this.parseGo(),
|
|
396
401
|
return: () => this.parseReturn(),
|
|
397
402
|
transition: () => this.parseTransition(),
|
|
403
|
+
halt: () => this.parseHalt(),
|
|
398
404
|
};
|
|
399
405
|
const normalized = normalizeCommand(this.peek().value);
|
|
400
406
|
if (cmdMap[normalized]) {
|
|
@@ -462,11 +468,17 @@ class HybridParser {
|
|
|
462
468
|
const url = this.parseExpression();
|
|
463
469
|
let responseType = { type: 'literal', value: 'text' };
|
|
464
470
|
let options;
|
|
471
|
+
let method;
|
|
465
472
|
if (this.match('{')) {
|
|
466
473
|
this.pos--;
|
|
467
474
|
options = this.parseExpression();
|
|
468
475
|
}
|
|
469
|
-
for (let i = 0; i <
|
|
476
|
+
for (let i = 0; i < 3; i++) {
|
|
477
|
+
if (this.match('via') && !method) {
|
|
478
|
+
this.advance();
|
|
479
|
+
method = this.parseExpression();
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
470
482
|
if (this.match('as')) {
|
|
471
483
|
this.advance();
|
|
472
484
|
if (this.match('a') || this.match('an'))
|
|
@@ -484,7 +496,11 @@ class HybridParser {
|
|
|
484
496
|
if (this.match('then'))
|
|
485
497
|
this.advance();
|
|
486
498
|
const body = this.parseCommandSequence();
|
|
487
|
-
return {
|
|
499
|
+
return {
|
|
500
|
+
type: 'fetch',
|
|
501
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
502
|
+
body,
|
|
503
|
+
};
|
|
488
504
|
}
|
|
489
505
|
parseToggle() {
|
|
490
506
|
this.expect('toggle');
|
|
@@ -675,6 +691,14 @@ class HybridParser {
|
|
|
675
691
|
}
|
|
676
692
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
677
693
|
}
|
|
694
|
+
parseHalt() {
|
|
695
|
+
this.expect('halt');
|
|
696
|
+
if (this.match('the'))
|
|
697
|
+
this.advance();
|
|
698
|
+
if (this.match('event', 'default'))
|
|
699
|
+
this.advance();
|
|
700
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
701
|
+
}
|
|
678
702
|
parseTransition() {
|
|
679
703
|
this.expect('transition');
|
|
680
704
|
let target;
|
|
@@ -951,6 +975,15 @@ class HybridParser {
|
|
|
951
975
|
const target = this.parsePositionalTarget();
|
|
952
976
|
return { type: 'positional', position, target };
|
|
953
977
|
}
|
|
978
|
+
if (this.match('values')) {
|
|
979
|
+
this.advance();
|
|
980
|
+
if (this.match('of')) {
|
|
981
|
+
this.advance();
|
|
982
|
+
const target = this.parseExpression();
|
|
983
|
+
return { type: 'valuesOf', target };
|
|
984
|
+
}
|
|
985
|
+
return { type: 'identifier', value: token.value };
|
|
986
|
+
}
|
|
954
987
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
955
988
|
this.advance();
|
|
956
989
|
return { type: 'identifier', value: token.value };
|
|
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
|
|
|
78
78
|
'init',
|
|
79
79
|
'every',
|
|
80
80
|
'by',
|
|
81
|
+
'halt',
|
|
82
|
+
'via',
|
|
83
|
+
'values',
|
|
84
|
+
'default',
|
|
85
|
+
'event',
|
|
81
86
|
]);
|
|
82
87
|
function tokenize(code) {
|
|
83
88
|
const tokens = [];
|
|
@@ -403,6 +408,7 @@ class HybridParser {
|
|
|
403
408
|
go: () => this.parseGo(),
|
|
404
409
|
return: () => this.parseReturn(),
|
|
405
410
|
transition: () => this.parseTransition(),
|
|
411
|
+
halt: () => this.parseHalt(),
|
|
406
412
|
};
|
|
407
413
|
const normalized = normalizeCommand(this.peek().value);
|
|
408
414
|
if (cmdMap[normalized]) {
|
|
@@ -470,11 +476,17 @@ class HybridParser {
|
|
|
470
476
|
const url = this.parseExpression();
|
|
471
477
|
let responseType = { type: 'literal', value: 'text' };
|
|
472
478
|
let options;
|
|
479
|
+
let method;
|
|
473
480
|
if (this.match('{')) {
|
|
474
481
|
this.pos--;
|
|
475
482
|
options = this.parseExpression();
|
|
476
483
|
}
|
|
477
|
-
for (let i = 0; i <
|
|
484
|
+
for (let i = 0; i < 3; i++) {
|
|
485
|
+
if (this.match('via') && !method) {
|
|
486
|
+
this.advance();
|
|
487
|
+
method = this.parseExpression();
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
478
490
|
if (this.match('as')) {
|
|
479
491
|
this.advance();
|
|
480
492
|
if (this.match('a') || this.match('an'))
|
|
@@ -492,7 +504,11 @@ class HybridParser {
|
|
|
492
504
|
if (this.match('then'))
|
|
493
505
|
this.advance();
|
|
494
506
|
const body = this.parseCommandSequence();
|
|
495
|
-
return {
|
|
507
|
+
return {
|
|
508
|
+
type: 'fetch',
|
|
509
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
510
|
+
body,
|
|
511
|
+
};
|
|
496
512
|
}
|
|
497
513
|
parseToggle() {
|
|
498
514
|
this.expect('toggle');
|
|
@@ -683,6 +699,14 @@ class HybridParser {
|
|
|
683
699
|
}
|
|
684
700
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
685
701
|
}
|
|
702
|
+
parseHalt() {
|
|
703
|
+
this.expect('halt');
|
|
704
|
+
if (this.match('the'))
|
|
705
|
+
this.advance();
|
|
706
|
+
if (this.match('event', 'default'))
|
|
707
|
+
this.advance();
|
|
708
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
709
|
+
}
|
|
686
710
|
parseTransition() {
|
|
687
711
|
this.expect('transition');
|
|
688
712
|
let target;
|
|
@@ -959,6 +983,15 @@ class HybridParser {
|
|
|
959
983
|
const target = this.parsePositionalTarget();
|
|
960
984
|
return { type: 'positional', position, target };
|
|
961
985
|
}
|
|
986
|
+
if (this.match('values')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
if (this.match('of')) {
|
|
989
|
+
this.advance();
|
|
990
|
+
const target = this.parseExpression();
|
|
991
|
+
return { type: 'valuesOf', target };
|
|
992
|
+
}
|
|
993
|
+
return { type: 'identifier', value: token.value };
|
|
994
|
+
}
|
|
962
995
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
963
996
|
this.advance();
|
|
964
997
|
return { type: 'identifier', value: token.value };
|