@hyperfixi/core 2.6.0 → 2.7.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.
Files changed (54) hide show
  1. package/dist/api/hyperscript-api.d.ts +6 -0
  2. package/dist/ast-utils/index.js +8 -8
  3. package/dist/ast-utils/index.mjs +8 -8
  4. package/dist/bundle-generator/index.js +12 -4
  5. package/dist/bundle-generator/index.mjs +12 -4
  6. package/dist/chunks/{bridge-fFLEvCQs.js → bridge-lZbOVRDD.js} +2 -2
  7. package/dist/chunks/browser-modular-DegkWQ8d.js +2 -0
  8. package/dist/chunks/{index-BRgVy8nY.js → index-i_j9Z-1e.js} +2 -2
  9. package/dist/commands/data/set.d.ts +1 -0
  10. package/dist/commands/index.js +156 -47
  11. package/dist/commands/index.mjs +156 -47
  12. package/dist/core/context.d.ts +4 -0
  13. package/dist/dom/attribute-processor.d.ts +1 -0
  14. package/dist/hyperfixi-browser-classic-i18n.js +1 -1
  15. package/dist/hyperfixi-browser-minimal.js +1 -1
  16. package/dist/hyperfixi-browser-standard.js +1 -1
  17. package/dist/hyperfixi-browser.js +1 -1
  18. package/dist/hyperfixi-classic-i18n.js +1 -1
  19. package/dist/hyperfixi-hx-v4.js +1 -1
  20. package/dist/hyperfixi-hx.js +1 -1
  21. package/dist/hyperfixi-hybrid-complete.js +1 -1
  22. package/dist/hyperfixi-hybrid-hx.js +1 -1
  23. package/dist/hyperfixi-lite-plus.js +1 -1
  24. package/dist/hyperfixi-lite.js +1 -1
  25. package/dist/hyperfixi-minimal.js +1 -1
  26. package/dist/hyperfixi-multilingual.js +1 -1
  27. package/dist/hyperfixi-standard.js +1 -1
  28. package/dist/hyperfixi.js +1 -1
  29. package/dist/hyperfixi.mjs +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js +694 -459
  32. package/dist/index.min.js +1 -1
  33. package/dist/index.mjs +691 -460
  34. package/dist/lokascript-browser-classic-i18n.js +1 -1
  35. package/dist/lokascript-browser-minimal.js +1 -1
  36. package/dist/lokascript-browser-standard.js +1 -1
  37. package/dist/lokascript-browser.js +1 -1
  38. package/dist/lokascript-hybrid-complete.js +1 -1
  39. package/dist/lokascript-hybrid-hx.js +1 -1
  40. package/dist/lokascript-lite-plus.js +1 -1
  41. package/dist/lokascript-lite.js +1 -1
  42. package/dist/lokascript-multilingual.js +1 -1
  43. package/dist/parser/full-parser.js +70 -35
  44. package/dist/parser/full-parser.mjs +70 -35
  45. package/dist/parser/parser-types.d.ts +1 -1
  46. package/dist/parser/parser.d.ts +2 -0
  47. package/dist/parser/regex-parser.js +23 -14
  48. package/dist/parser/regex-parser.mjs +23 -14
  49. package/dist/registry/index.js +178 -45
  50. package/dist/registry/index.mjs +178 -45
  51. package/dist/types/core-context.d.ts +1 -0
  52. package/package.json +6 -6
  53. package/dist/chunks/browser-modular-BK3IOo93.js +0 -2
  54. package/dist/compatibility/browser-bundle.d.ts +0 -164
@@ -1,2 +1,2 @@
1
- let t=null;async function n(){if(!t)try{t=await import("./browser-modular-BK3IOo93.js").then(function(t){return t.m})}catch{throw Error("@lokascript/framework is required for LSE support. Install it: npm install @lokascript/framework")}return t}function r(){if(t)return!0;try{return require.resolve("@lokascript/framework"),!0}catch{return!1}}async function a(t,r){return(await n()).parseExplicit(t,r)}async function o(t){return(await n()).isExplicitSyntax(t)}async function i(t){return(await n()).renderExplicit(t)}async function e(t){return(await n()).fromInterchangeNode(t)}async function c(t){return(await n()).toProtocolJSON(t)}async function u(t){return(await n()).fromProtocolJSON(t)}async function s(t){return(await n()).validateProtocolJSON(t)}async function f(t){return(await n()).toEnvelopeJSON(t)}async function l(t){return(await n()).fromEnvelopeJSON(t)}async function w(t){return(await n()).isEnvelope(t)}async function p(t){return(await n()).semanticNodeToRuntimeAST(t)}export{l as fromEnvelopeJSON,e as fromInterchangeNode,u as fromProtocolJSON,w as isEnvelope,o as isExplicitSyntax,r as isLSEAvailable,a as parseExplicit,i as renderExplicit,p as semanticNodeToRuntimeAST,f as toEnvelopeJSON,c as toProtocolJSON,s as validateProtocolJSON};
2
- //# sourceMappingURL=index-BRgVy8nY.js.map
1
+ let t=null;async function n(){if(!t)try{t=await import("./browser-modular-DegkWQ8d.js").then(function(t){return t.m})}catch{throw Error("@lokascript/framework is required for LSE support. Install it: npm install @lokascript/framework")}return t}function r(){if(t)return!0;try{return require.resolve("@lokascript/framework"),!0}catch{return!1}}async function a(t,r){return(await n()).parseExplicit(t,r)}async function o(t){return(await n()).isExplicitSyntax(t)}async function i(t){return(await n()).renderExplicit(t)}async function e(t){return(await n()).fromInterchangeNode(t)}async function c(t){return(await n()).toProtocolJSON(t)}async function u(t){return(await n()).fromProtocolJSON(t)}async function s(t){return(await n()).validateProtocolJSON(t)}async function f(t){return(await n()).toEnvelopeJSON(t)}async function l(t){return(await n()).fromEnvelopeJSON(t)}async function w(t){return(await n()).isEnvelope(t)}async function p(t){return(await n()).semanticNodeToRuntimeAST(t)}export{l as fromEnvelopeJSON,e as fromInterchangeNode,u as fromProtocolJSON,w as isEnvelope,o as isExplicitSyntax,r as isLSEAvailable,a as parseExplicit,i as renderExplicit,p as semanticNodeToRuntimeAST,f as toEnvelopeJSON,c as toProtocolJSON,s as validateProtocolJSON};
2
+ //# sourceMappingURL=index-i_j9Z-1e.js.map
@@ -7,6 +7,7 @@ export type SetCommandInput = {
7
7
  type: 'variable';
8
8
  name: string;
9
9
  value: unknown;
10
+ scope?: 'element' | 'global';
10
11
  } | {
11
12
  type: 'attribute';
12
13
  elements: HTMLElement[];
@@ -3748,6 +3748,36 @@ function setGlobal(context, name, value) {
3748
3748
  }
3749
3749
  }
3750
3750
 
3751
+ const elementScopes = new WeakMap();
3752
+ function getElementScopeMap(element) {
3753
+ let map = elementScopes.get(element);
3754
+ if (!map) {
3755
+ map = new Map();
3756
+ elementScopes.set(element, map);
3757
+ }
3758
+ return map;
3759
+ }
3760
+ function resolveScopeOwner(context) {
3761
+ const owner = context.owner;
3762
+ if (owner)
3763
+ return owner;
3764
+ return context.me instanceof Element ? context.me : null;
3765
+ }
3766
+ function getElementVar(context, name) {
3767
+ const owner = resolveScopeOwner(context);
3768
+ if (!owner)
3769
+ return undefined;
3770
+ notifyLocalRead(name, context);
3771
+ return getElementScopeMap(owner).get(name);
3772
+ }
3773
+ function setElementVar(context, name, value) {
3774
+ const owner = resolveScopeOwner(context);
3775
+ if (!owner)
3776
+ return;
3777
+ getElementScopeMap(owner).set(name, value);
3778
+ notifyLocalWrite(name, value, context);
3779
+ }
3780
+
3751
3781
  function convertToNumber(value) {
3752
3782
  if (value === null || value === undefined) {
3753
3783
  return 0;
@@ -3780,6 +3810,9 @@ function convertToNumber(value) {
3780
3810
  return 0;
3781
3811
  }
3782
3812
  function getVariableValue(name, context, preferredScope) {
3813
+ if (preferredScope === 'element') {
3814
+ return getElementVar(context, name);
3815
+ }
3783
3816
  if (preferredScope === 'global' && context.globals && context.globals.has(name)) {
3784
3817
  return context.globals.get(name);
3785
3818
  }
@@ -3806,6 +3839,10 @@ function getVariableValue(name, context, preferredScope) {
3806
3839
  return undefined;
3807
3840
  }
3808
3841
  function setVariableValue(name, value, context, preferredScope) {
3842
+ if (preferredScope === 'element') {
3843
+ setElementVar(context, name, value);
3844
+ return;
3845
+ }
3809
3846
  if (preferredScope === 'global') {
3810
3847
  setGlobal(context, name, value);
3811
3848
  if (typeof window !== 'undefined') {
@@ -3899,6 +3936,9 @@ function getCurrentNumericValue(target, property, scope, context) {
3899
3936
  }
3900
3937
  }
3901
3938
  if (typeof target === 'string') {
3939
+ if (scope === 'element') {
3940
+ return convertToNumber(getVariableValue(target, context, 'element'));
3941
+ }
3902
3942
  if (scope === 'global') {
3903
3943
  const value = getVariableValue(target, context, 'global');
3904
3944
  return convertToNumber(value);
@@ -3943,6 +3983,10 @@ function setTargetValue(target, property, scope, newValue, context) {
3943
3983
  return;
3944
3984
  }
3945
3985
  if (typeof target === 'string') {
3986
+ if (scope === 'element') {
3987
+ setVariableValue(target, newValue, context, 'element');
3988
+ return;
3989
+ }
3946
3990
  if (scope === 'global') {
3947
3991
  setVariableValue(target, newValue, context, 'global');
3948
3992
  return;
@@ -9181,7 +9225,7 @@ function parseColonVariable(ctx) {
9181
9225
  return {
9182
9226
  type: 'identifier',
9183
9227
  name: varToken.value,
9184
- scope: 'local',
9228
+ scope: 'element',
9185
9229
  start: varToken.start - 1,
9186
9230
  end: varToken.end,
9187
9231
  };
@@ -9233,7 +9277,7 @@ function parseTargetFallback(ctx) {
9233
9277
  expression: {
9234
9278
  type: 'identifier',
9235
9279
  name: varToken.value,
9236
- scope: 'local',
9280
+ scope: 'element',
9237
9281
  start: varToken.start,
9238
9282
  end: varToken.end,
9239
9283
  },
@@ -9314,6 +9358,11 @@ function parseSetCommand(ctx, identifierNode) {
9314
9358
  }
9315
9359
  ctx.advance();
9316
9360
  const value = ctx.parseExpression() ?? ctx.parsePrimary();
9361
+ let scopeTarget;
9362
+ if (ctx.check(KEYWORDS$1.ON) && tokenLooksLikeElementTarget(ctx.peekAt(1))) {
9363
+ ctx.advance();
9364
+ scopeTarget = parseOneArgument(ctx);
9365
+ }
9317
9366
  const finalArgs = [];
9318
9367
  if (targetExpression) {
9319
9368
  finalArgs.push(targetExpression);
@@ -9325,11 +9374,22 @@ function parseSetCommand(ctx, identifierNode) {
9325
9374
  if (value) {
9326
9375
  finalArgs.push(value);
9327
9376
  }
9328
- return CommandNodeBuilder.fromIdentifier(identifierNode)
9329
- .withArgs(...finalArgs)
9330
- .endingAt(ctx.getPosition())
9331
- .build();
9377
+ const builder = CommandNodeBuilder.fromIdentifier(identifierNode).withArgs(...finalArgs);
9378
+ if (scopeTarget) {
9379
+ builder.withModifier('on', scopeTarget);
9380
+ }
9381
+ return builder.endingAt(ctx.getPosition()).build();
9332
9382
  }
9383
+ function tokenLooksLikeElementTarget(token) {
9384
+ if (!token)
9385
+ return false;
9386
+ if (token.kind === 'selector')
9387
+ return true;
9388
+ if (token.value.startsWith('<'))
9389
+ return true;
9390
+ return ELEMENT_PRONOUNS.has(token.value);
9391
+ }
9392
+ const ELEMENT_PRONOUNS = new Set(['me', 'my', 'it', 'its', 'you', 'your', 'yourself']);
9333
9393
  function parseIncrementDecrementCommand(ctx, commandToken) {
9334
9394
  const commandName = commandToken.value;
9335
9395
  const isIncrement = commandName === 'increment';
@@ -9375,6 +9435,7 @@ function parseIncrementDecrementCommand(ctx, commandToken) {
9375
9435
  column: commandToken.column,
9376
9436
  };
9377
9437
  const binaryExpr = createBinaryExpression(operator, target, amount, pos);
9438
+ binaryExpr.coerceNumeric = true;
9378
9439
  const toIdentifier = createIdentifier(KEYWORDS$1.TO, pos);
9379
9440
  const args = [targetWithScope, toIdentifier, binaryExpr];
9380
9441
  return CommandNodeBuilder.from(commandToken)
@@ -9993,6 +10054,18 @@ class Parser {
9993
10054
  this.advance();
9994
10055
  continue;
9995
10056
  }
10057
+ if (this.check('then')) {
10058
+ const next = this.peekAt(1);
10059
+ const startsFeature = next !== null &&
10060
+ (next.value === 'init' ||
10061
+ next.value === 'on' ||
10062
+ next.value === 'def' ||
10063
+ getRegisteredFeature(next.value) !== undefined);
10064
+ if (startsFeature) {
10065
+ this.advance();
10066
+ continue;
10067
+ }
10068
+ }
9996
10069
  if (this.check('init')) {
9997
10070
  this.advance();
9998
10071
  const initBlock = this.parseTopLevelInitBlock();
@@ -10793,7 +10866,7 @@ class Parser {
10793
10866
  return {
10794
10867
  type: 'identifier',
10795
10868
  name: varToken.value,
10796
- scope: 'local',
10869
+ scope: 'element',
10797
10870
  start: varToken.start - 1,
10798
10871
  end: varToken.end,
10799
10872
  line: varToken.line,
@@ -11420,6 +11493,33 @@ class Parser {
11420
11493
  return null;
11421
11494
  }
11422
11495
  }
11496
+ parseTemporalKeywordModifiers(modifiers) {
11497
+ if (!this.check('debounced') && !this.check('throttled')) {
11498
+ return;
11499
+ }
11500
+ const modToken = this.advance();
11501
+ const modName = modToken.value.toLowerCase();
11502
+ const modifierKey = modName === 'debounced' ? 'debounce' : 'throttle';
11503
+ if (this.match('at')) {
11504
+ if (this.checkTimeExpression()) {
11505
+ const timeToken = this.advance();
11506
+ const delayMs = parseTimeToMs(timeToken.value);
11507
+ modifiers[modifierKey] = delayMs;
11508
+ debug.parse(`🔧 parseEventHandler: Parsed '${modName} at ${timeToken.value}' (${delayMs}ms)`);
11509
+ }
11510
+ else if (this.matchNumber()) {
11511
+ const delayMs = parseInt(this.previous().value, 10);
11512
+ modifiers[modifierKey] = delayMs;
11513
+ debug.parse(`🔧 parseEventHandler: Parsed '${modName} at ${delayMs}'`);
11514
+ }
11515
+ else {
11516
+ this.addError(`Expected time expression after '${modName} at', got: ${this.peek().value}`);
11517
+ }
11518
+ }
11519
+ else {
11520
+ this.addError(`Expected 'at' after '${modName}'`);
11521
+ }
11522
+ }
11423
11523
  parseEventHandler() {
11424
11524
  debug.parse(`🔧 parseEventHandler: ENTRY - parsing event handler`);
11425
11525
  const eventNames = [];
@@ -11507,30 +11607,7 @@ class Parser {
11507
11607
  debug.parse(`🔧 parseEventHandler: Warning - unknown modifier '.${modName}'`);
11508
11608
  }
11509
11609
  }
11510
- if (this.check('debounced') || this.check('throttled')) {
11511
- const modToken = this.advance();
11512
- const modName = modToken.value.toLowerCase();
11513
- const modifierKey = modName === 'debounced' ? 'debounce' : 'throttle';
11514
- if (this.match('at')) {
11515
- if (this.checkTimeExpression()) {
11516
- const timeToken = this.advance();
11517
- const delayMs = parseTimeToMs(timeToken.value);
11518
- modifiers[modifierKey] = delayMs;
11519
- debug.parse(`🔧 parseEventHandler: Parsed '${modName} at ${timeToken.value}' (${delayMs}ms)`);
11520
- }
11521
- else if (this.matchNumber()) {
11522
- const delayMs = parseInt(this.previous().value, 10);
11523
- modifiers[modifierKey] = delayMs;
11524
- debug.parse(`🔧 parseEventHandler: Parsed '${modName} at ${delayMs}'`);
11525
- }
11526
- else {
11527
- this.addError(`Expected time expression after '${modName} at', got: ${this.peek().value}`);
11528
- }
11529
- }
11530
- else {
11531
- this.addError(`Expected 'at' after '${modName}'`);
11532
- }
11533
- }
11610
+ this.parseTemporalKeywordModifiers(modifiers);
11534
11611
  if (firstOnceAlias) {
11535
11612
  modifiers.once = true;
11536
11613
  }
@@ -11547,6 +11624,7 @@ class Parser {
11547
11624
  const targetToken = this.advance();
11548
11625
  target = targetToken.value;
11549
11626
  debug.parse(`🔧 parseEventHandler: Parsed 'from' target: ${target} (kind: ${targetToken.kind})`);
11627
+ this.parseTemporalKeywordModifiers(modifiers);
11550
11628
  }
11551
11629
  let attributeName;
11552
11630
  if (this.match('of')) {
@@ -12517,6 +12595,10 @@ class Parser {
12517
12595
  }
12518
12596
  return this.tokens[this.current];
12519
12597
  }
12598
+ peekAt(offset) {
12599
+ const index = this.current + offset;
12600
+ return index >= 0 && index < this.tokens.length ? this.tokens[index] : null;
12601
+ }
12520
12602
  previous() {
12521
12603
  return this.tokens[this.current - 1];
12522
12604
  }
@@ -12721,10 +12803,7 @@ class Parser {
12721
12803
  restorePosition: (pos) => {
12722
12804
  parser.current = pos;
12723
12805
  },
12724
- peekAt: (offset) => {
12725
- const index = parser.current + offset;
12726
- return index >= 0 && index < parser.tokens.length ? parser.tokens[index] : null;
12727
- },
12806
+ peekAt: (offset) => parser.peekAt(offset),
12728
12807
  getInputSlice: (start, end) => {
12729
12808
  if (!this.originalInput)
12730
12809
  return '';
@@ -12868,7 +12947,7 @@ function evaluateExpressionSync(node, context) {
12868
12947
  case 'selector':
12869
12948
  return evaluateSelectorSync(n, context);
12870
12949
  case 'identifier':
12871
- return resolveIdentifierSync(n.name, context);
12950
+ return resolveIdentifierSync(n.name, context, n.scope);
12872
12951
  case 'contextReference':
12873
12952
  return resolveContextReferenceSync(n.contextType, context);
12874
12953
  case 'arrayLiteral':
@@ -12904,7 +12983,7 @@ function evaluateExpressionSync(node, context) {
12904
12983
  throw new NotSyncEvaluable(n?.type ?? 'unknown');
12905
12984
  }
12906
12985
  }
12907
- function resolveIdentifierSync(name, context) {
12986
+ function resolveIdentifierSync(name, context, scope) {
12908
12987
  if (name === 'me' || name === 'my' || name === 'I')
12909
12988
  return context.me;
12910
12989
  if (name === 'you' || name === 'your' || name === 'yourself')
@@ -12915,6 +12994,8 @@ function resolveIdentifierSync(name, context) {
12915
12994
  return typeof window !== 'undefined' ? window : globalThis;
12916
12995
  if (name === 'document')
12917
12996
  return typeof document !== 'undefined' ? document : undefined;
12997
+ if (scope === 'element')
12998
+ return getElementVar(context, name);
12918
12999
  if (context.locals?.has(name))
12919
13000
  return context.locals.get(name);
12920
13001
  if (context.globals?.has(name))
@@ -13044,6 +13125,9 @@ async function evaluateIdentifier(node, context) {
13044
13125
  notifyGlobalRead(name, context);
13045
13126
  return context.globals.get(name);
13046
13127
  }
13128
+ if (node.scope === 'element') {
13129
+ return getElementVar(context, name);
13130
+ }
13047
13131
  if (context.locals && context.locals.has(name)) {
13048
13132
  notifyLocalRead(name, context);
13049
13133
  return context.locals.get(name);
@@ -13079,6 +13163,9 @@ async function evaluateBinaryExpression(node, context) {
13079
13163
  else if (leftNode.scope === 'global') {
13080
13164
  setGlobal(context, name, value);
13081
13165
  }
13166
+ else if (leftNode.scope === 'element') {
13167
+ setElementVar(context, name, value);
13168
+ }
13082
13169
  else {
13083
13170
  if (!context.locals)
13084
13171
  context.locals = new Map();
@@ -13160,14 +13247,26 @@ async function evaluateBinaryExpression(node, context) {
13160
13247
  const L = node.ignoringCase ? applyCI(left) : left;
13161
13248
  const R = node.ignoringCase ? applyCI(right) : right;
13162
13249
  switch (operator) {
13163
- case '+':
13164
- if (typeof left === 'string' || typeof right === 'string') {
13165
- return String(left ?? '') + String(right ?? '');
13166
- }
13167
- if (Array.isArray(left)) {
13168
- return Array.isArray(right) ? [...left, ...right] : [...left, right];
13169
- }
13170
- return unwrapTypedResult(await getExpr(context, 'addition').evaluate(context, { left, right }));
13250
+ case '+': {
13251
+ let addLeft = left;
13252
+ let addRight = right;
13253
+ if (node.coerceNumeric) {
13254
+ if (typeof addLeft === 'string')
13255
+ addLeft = convertToNumber(addLeft);
13256
+ if (typeof addRight === 'string')
13257
+ addRight = convertToNumber(addRight);
13258
+ }
13259
+ if (typeof addLeft === 'string' || typeof addRight === 'string') {
13260
+ return String(addLeft ?? '') + String(addRight ?? '');
13261
+ }
13262
+ if (Array.isArray(addLeft)) {
13263
+ return Array.isArray(addRight) ? [...addLeft, ...addRight] : [...addLeft, addRight];
13264
+ }
13265
+ return unwrapTypedResult(await getExpr(context, 'addition').evaluate(context, {
13266
+ left: addLeft,
13267
+ right: addRight,
13268
+ }));
13269
+ }
13171
13270
  case '-':
13172
13271
  return unwrapTypedResult(await getExpr(context, 'subtraction').evaluate(context, { left, right }));
13173
13272
  case '*':
@@ -16678,6 +16777,7 @@ let SetCommand = (() => {
16678
16777
  }
16679
16778
  const firstArg = raw.args[0];
16680
16779
  const argName = (firstArg?.name || firstArg?.value);
16780
+ const argScope = firstArg?.scope;
16681
16781
  const firstArgType = firstArg?.type;
16682
16782
  if (firstArgType) {
16683
16783
  const writer = getRegisteredNodeWriter(firstArgType);
@@ -16771,12 +16871,21 @@ let SetCommand = (() => {
16771
16871
  throw new Error(`set command target must be a string or object literal${hint}`);
16772
16872
  }
16773
16873
  const value = await this.extractValue(raw, evaluator, context);
16774
- return { type: 'variable', name: firstValue, value };
16874
+ const scope = argScope === 'element' || argScope === 'global' ? argScope : undefined;
16875
+ return { type: 'variable', name: firstValue, value, scope };
16775
16876
  }
16776
16877
  async execute(input, context) {
16777
16878
  switch (input.type) {
16778
16879
  case 'variable':
16779
- setVariableValue(input.name, input.value, context);
16880
+ if (input.scope === 'element') {
16881
+ setElementVar(context, input.name, input.value);
16882
+ }
16883
+ else if (input.scope === 'global') {
16884
+ setVariableValue(input.name, input.value, context, 'global');
16885
+ }
16886
+ else {
16887
+ setVariableValue(input.name, input.value, context);
16888
+ }
16780
16889
  if (input.name === 'result' || input.name === 'it') {
16781
16890
  Object.assign(context, { [input.name]: input.value });
16782
16891
  }