@hyperfixi/core 2.3.1 → 2.4.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 (194) hide show
  1. package/dist/api/dom-processor.d.ts +8 -4
  2. package/dist/api/hyperscript-api.d.ts +5 -1
  3. package/dist/ast-utils/index.js +25320 -94
  4. package/dist/ast-utils/index.mjs +25320 -94
  5. package/dist/ast-utils/interchange/types.d.ts +7 -1
  6. package/dist/behaviors/index.js +54 -100
  7. package/dist/behaviors/index.mjs +54 -100
  8. package/dist/bundle-generator/index.js +19 -2
  9. package/dist/bundle-generator/index.mjs +19 -2
  10. package/dist/bundle-generator/parser-templates.d.ts +1 -1
  11. package/dist/bundle-generator/template-capabilities.d.ts +1 -1
  12. package/dist/chunks/bridge-C4d3blZX.js +2 -0
  13. package/dist/chunks/browser-modular-BwIRlrTM.js +2 -0
  14. package/dist/chunks/feature-eventsource-BpZvPy_K.js +2 -0
  15. package/dist/chunks/{feature-sockets-ClOH7vk7.js → feature-sockets-CrYvjZ4j.js} +2 -2
  16. package/dist/chunks/feature-webworker-BSYguEIW.js +2 -0
  17. package/dist/chunks/index-Beno_SBy.js +2 -0
  18. package/dist/commands/advanced/async.d.ts +6 -2
  19. package/dist/commands/advanced/js.d.ts +1 -1
  20. package/dist/commands/animation/start-view-transition.d.ts +24 -0
  21. package/dist/commands/async/fetch.d.ts +6 -1
  22. package/dist/commands/control-flow/repeat.d.ts +2 -0
  23. package/dist/commands/data/clear.d.ts +23 -0
  24. package/dist/commands/data/set.d.ts +6 -0
  25. package/dist/commands/dom/close.d.ts +19 -0
  26. package/dist/commands/dom/empty.d.ts +19 -0
  27. package/dist/commands/dom/open.d.ts +21 -0
  28. package/dist/commands/dom/reset.d.ts +19 -0
  29. package/dist/commands/dom/select.d.ts +19 -0
  30. package/dist/commands/dom/swap.d.ts +7 -4
  31. package/dist/commands/events/trigger.d.ts +1 -1
  32. package/dist/commands/execution/blur.d.ts +19 -0
  33. package/dist/commands/execution/call.d.ts +1 -2
  34. package/dist/commands/execution/focus.d.ts +19 -0
  35. package/dist/commands/helpers/element-resolution.d.ts +2 -2
  36. package/dist/commands/helpers/event-waiting.d.ts +1 -1
  37. package/dist/commands/helpers/numeric-target-parser.d.ts +7 -0
  38. package/dist/commands/index.d.ts +34 -2
  39. package/dist/commands/index.js +19352 -4845
  40. package/dist/commands/index.mjs +19320 -4846
  41. package/dist/commands/navigation/go.d.ts +3 -0
  42. package/dist/commands/navigation/scroll-to.d.ts +26 -0
  43. package/dist/commands/utility/beep.d.ts +2 -2
  44. package/dist/commands/utility/breakpoint.d.ts +19 -0
  45. package/dist/commands/utility/pick.d.ts +11 -2
  46. package/dist/compatibility/browser-bundle-modular.d.ts +2 -2
  47. package/dist/compatibility/browser-bundle-multilingual.d.ts +1 -1
  48. package/dist/compatibility/browser-bundle-semantic-complete.d.ts +3 -3
  49. package/dist/compatibility/browser-bundle.d.ts +13 -6
  50. package/dist/compatibility/browser-modular.d.ts +1 -3
  51. package/dist/core/expression-evaluator.d.ts +4 -4
  52. package/dist/core/expression-registry.d.ts +8 -0
  53. package/dist/expressions/bundles/common-expressions.d.ts +2 -2
  54. package/dist/expressions/bundles/core-expressions.d.ts +2 -2
  55. package/dist/expressions/bundles/full-expressions.d.ts +2 -2
  56. package/dist/expressions/bundles/index.d.ts +3 -3
  57. package/dist/expressions/collection/index.d.ts +35 -0
  58. package/dist/expressions/conversion/impl/index.d.ts +1 -1
  59. package/dist/expressions/index.d.ts +4 -3
  60. package/dist/expressions/index.js +1117 -1590
  61. package/dist/expressions/index.mjs +1113 -1586
  62. package/dist/expressions/logical/index.d.ts +2 -0
  63. package/dist/expressions/mathematical/index.d.ts +11 -0
  64. package/dist/expressions/shared/index.d.ts +1 -1
  65. package/dist/expressions/shared/number-utils.d.ts +1 -0
  66. package/dist/htmx/htmx-attribute-processor.d.ts +37 -1
  67. package/dist/htmx/htmx-translator.d.ts +2 -0
  68. package/dist/htmx/i18n-hooks.d.ts +15 -0
  69. package/dist/htmx/i18n-orchestrator.d.ts +15 -0
  70. package/dist/htmx/lang-resolver.d.ts +3 -0
  71. package/dist/htmx/sse.d.ts +60 -0
  72. package/dist/htmx/ws.d.ts +59 -0
  73. package/dist/hyperfixi-browser-classic-i18n.js +2 -0
  74. package/dist/hyperfixi-browser-minimal.js +1 -0
  75. package/dist/hyperfixi-browser-standard.js +2 -0
  76. package/dist/hyperfixi-browser.js +2 -0
  77. package/dist/hyperfixi-classic-i18n.js +1 -1
  78. package/dist/hyperfixi-hx-v4.js +1 -0
  79. package/dist/hyperfixi-hx.js +1 -1
  80. package/dist/hyperfixi-hybrid-complete.js +1 -1
  81. package/dist/hyperfixi-hybrid-hx.js +1 -0
  82. package/dist/hyperfixi-minimal.js +1 -1
  83. package/dist/hyperfixi-multilingual.js +1 -1
  84. package/dist/hyperfixi-standard.js +1 -1
  85. package/dist/hyperfixi.js +1 -1
  86. package/dist/hyperfixi.mjs +1 -1
  87. package/dist/index.d.ts +2 -0
  88. package/dist/index.js +43591 -45060
  89. package/dist/index.min.js +1 -1
  90. package/dist/index.mjs +43588 -45061
  91. package/dist/lib/index.d.ts +2 -2
  92. package/dist/lib/morph-adapter.d.ts +0 -13
  93. package/dist/lib/swap-executor.d.ts +0 -10
  94. package/dist/lib/view-transitions.d.ts +1 -30
  95. package/dist/lokascript-browser-classic-i18n.js +1 -1
  96. package/dist/lokascript-browser-minimal.js +1 -1
  97. package/dist/lokascript-browser-standard.js +1 -1
  98. package/dist/lokascript-browser.js +1 -1
  99. package/dist/lokascript-hybrid-complete.js +1 -1
  100. package/dist/lokascript-hybrid-hx.js +1 -1
  101. package/dist/lokascript-multilingual.js +1 -1
  102. package/dist/lsp-metadata.d.ts +9 -4
  103. package/dist/lsp-metadata.js +187 -3
  104. package/dist/lsp-metadata.mjs +185 -4
  105. package/dist/metadata.d.ts +1 -1
  106. package/dist/metadata.js +3 -3
  107. package/dist/metadata.mjs +3 -3
  108. package/dist/multilingual/bridge.d.ts +1 -1
  109. package/dist/multilingual/index.js +79 -22
  110. package/dist/multilingual/index.mjs +79 -22
  111. package/dist/parser/command-parsers/animation-commands.d.ts +1 -0
  112. package/dist/parser/command-parsers/utility-commands.d.ts +1 -0
  113. package/dist/parser/extensions.d.ts +51 -0
  114. package/dist/parser/full-parser.js +1224 -899
  115. package/dist/parser/full-parser.mjs +1224 -899
  116. package/dist/parser/helpers/ast-helpers.d.ts +1 -0
  117. package/dist/parser/helpers/parsing-helpers.d.ts +4 -0
  118. package/dist/parser/parser-types.d.ts +8 -28
  119. package/dist/parser/parser.d.ts +3 -7
  120. package/dist/parser/pratt-parser.d.ts +0 -3
  121. package/dist/parser/runtime.d.ts +4 -0
  122. package/dist/parser/semantic-integration.d.ts +17 -0
  123. package/dist/parser/types.d.ts +7 -1
  124. package/dist/reference/index.js +91 -0
  125. package/dist/reference/index.mjs +91 -0
  126. package/dist/registry/index.js +12866 -5876
  127. package/dist/registry/index.mjs +12866 -5876
  128. package/dist/registry/universal-types.d.ts +2 -1
  129. package/dist/runtime/command-adapter.d.ts +23 -16
  130. package/dist/runtime/plugin.d.ts +14 -0
  131. package/dist/runtime/runtime-base.d.ts +32 -7
  132. package/dist/runtime/runtime-factory.d.ts +3 -3
  133. package/dist/runtime/runtime.d.ts +2 -2
  134. package/dist/test-setup.d.ts +1 -0
  135. package/dist/types/base-types.d.ts +3 -0
  136. package/dist/types/feature-types.d.ts +1 -1
  137. package/dist/types/index.d.ts +2 -2
  138. package/package.json +26 -20
  139. package/vocab/htmx/ar.js +60 -0
  140. package/vocab/htmx/bn.js +49 -0
  141. package/vocab/htmx/de.js +60 -0
  142. package/vocab/htmx/en.js +21 -0
  143. package/vocab/htmx/es.js +60 -0
  144. package/vocab/htmx/fr.js +59 -0
  145. package/vocab/htmx/he.js +40 -0
  146. package/vocab/htmx/hi.js +60 -0
  147. package/vocab/htmx/id.js +57 -0
  148. package/vocab/htmx/it.js +58 -0
  149. package/vocab/htmx/ja.js +60 -0
  150. package/vocab/htmx/ko.js +60 -0
  151. package/vocab/htmx/ms.js +35 -0
  152. package/vocab/htmx/pl.js +60 -0
  153. package/vocab/htmx/pt.js +60 -0
  154. package/vocab/htmx/qu.js +60 -0
  155. package/vocab/htmx/ru.js +60 -0
  156. package/vocab/htmx/sw.js +59 -0
  157. package/vocab/htmx/th.js +49 -0
  158. package/vocab/htmx/tl.js +33 -0
  159. package/vocab/htmx/tr.js +60 -0
  160. package/vocab/htmx/uk.js +60 -0
  161. package/vocab/htmx/vi.js +51 -0
  162. package/vocab/htmx/zh.js +60 -0
  163. package/dist/bundles/test-minimal.d.ts +0 -3
  164. package/dist/bundles/test-standard.d.ts +0 -3
  165. package/dist/chunks/bridge-Clbh_xAj.js +0 -2
  166. package/dist/chunks/browser-modular-DIOxQqhV.js +0 -2
  167. package/dist/chunks/feature-eventsource-B5F2-H1r.js +0 -2
  168. package/dist/chunks/feature-webworker-3bAp0ac9.js +0 -2
  169. package/dist/chunks/index-DcxoRUBe.js +0 -2
  170. package/dist/compatibility/browser-bundle-minimal.d.ts +0 -8
  171. package/dist/compatibility/browser-bundle-standard.d.ts +0 -8
  172. package/dist/compatibility/hyperscript-tests/test-adapter.d.ts +0 -13
  173. package/dist/core/base-expression-evaluator.d.ts +0 -74
  174. package/dist/core/binary-expression-evaluator.d.ts +0 -7
  175. package/dist/core/call-expression-evaluator.d.ts +0 -7
  176. package/dist/core/configurable-expression-evaluator.d.ts +0 -5
  177. package/dist/core/lazy-expression-evaluator.d.ts +0 -22
  178. package/dist/core/parser.d.ts +0 -21
  179. package/dist/core/selector-evaluator.d.ts +0 -15
  180. package/dist/core/template-literal-evaluator.d.ts +0 -5
  181. package/dist/expressions/comparison/index.d.ts +0 -80
  182. package/dist/expressions/comparison/utils.d.ts +0 -2
  183. package/dist/expressions/conversion/impl/bridge.d.ts +0 -117
  184. package/dist/expressions/logical/impl/pattern-matching.d.ts +0 -58
  185. package/dist/expressions/positional/impl/bridge.d.ts +0 -95
  186. package/dist/expressions/property/index.d.ts +0 -55
  187. package/dist/expressions/references/impl/bridge.d.ts +0 -54
  188. package/dist/extensions/index.d.ts +0 -3
  189. package/dist/extensions/tailwind.d.ts +0 -22
  190. package/dist/mod.d.ts +0 -63
  191. package/dist/parser/expression-parser.d.ts +0 -6
  192. package/dist/runtime/runtime-experimental.d.ts +0 -18
  193. package/dist/scripts/code-generator.d.ts +0 -64
  194. package/dist/scripts/generate-missing-commands.d.ts +0 -4
@@ -1,4 +1,4 @@
1
- export type InterchangeNode = EventNode | CommandNode | LiteralNode | IdentifierNode | SelectorNode | VariableNode | BinaryNode | UnaryNode | MemberNode | PossessiveNode | CallNode | IfNode | RepeatNode | ForEachNode | WhileNode | PositionalNode;
1
+ export type InterchangeNode = EventNode | CommandNode | LiteralNode | IdentifierNode | SelectorNode | VariableNode | BinaryNode | UnaryNode | MemberNode | PossessiveNode | CallNode | IfNode | RepeatNode | ForEachNode | WhileNode | PositionalNode | ErrorNode;
2
2
  export interface BaseNode {
3
3
  readonly type: string;
4
4
  readonly start?: number;
@@ -56,6 +56,11 @@ export interface PositionalNode extends BaseNode {
56
56
  readonly position: 'first' | 'last' | 'next' | 'previous' | 'closest' | 'parent' | 'random';
57
57
  readonly target?: InterchangeNode;
58
58
  }
59
+ export interface ErrorNode extends BaseNode {
60
+ readonly type: 'error';
61
+ readonly message: string;
62
+ readonly token?: string;
63
+ }
59
64
  export interface CommandNode extends BaseNode {
60
65
  readonly type: 'command';
61
66
  readonly name: string;
@@ -63,6 +68,7 @@ export interface CommandNode extends BaseNode {
63
68
  readonly target?: InterchangeNode;
64
69
  readonly modifiers?: Record<string, unknown>;
65
70
  readonly roles?: Readonly<Record<string, InterchangeNode>>;
71
+ readonly partial?: boolean;
66
72
  }
67
73
  export interface EventNode extends BaseNode {
68
74
  readonly type: 'event';
@@ -550,31 +550,14 @@ function longestIncreasingSubsequence(sequence) {
550
550
 
551
551
  //# debugId=3F4BCB911DEC843864756E2164756E21
552
552
 
553
- const morphlexMorph = morph;
554
- const morphlexMorphInner = morphInner;
555
553
  function toMorphlexOptions(options) {
556
- if (!options) {
557
- return { preserveChanges: true };
558
- }
559
- return {
560
- preserveChanges: options.preserveChanges ?? true,
561
- beforeNodeVisited: options.beforeNodeVisited,
562
- afterNodeVisited: options.afterNodeVisited,
563
- beforeNodeAdded: options.beforeNodeAdded
564
- ? (node) => options.beforeNodeAdded(node.parentNode, node, null)
565
- : undefined,
566
- afterNodeAdded: options.afterNodeAdded,
567
- beforeNodeRemoved: options.beforeNodeRemoved,
568
- afterNodeRemoved: options.afterNodeRemoved,
569
- };
554
+ return { preserveChanges: options?.preserveChanges ?? true };
570
555
  }
571
- const morphlexEngine = {
556
+ const morphAdapter = {
572
557
  morph(target, content, options) {
573
- const morphlexOpts = toMorphlexOptions(options);
574
- morphlexMorph(target, content, morphlexOpts);
558
+ morph(target, content, toMorphlexOptions(options));
575
559
  },
576
560
  morphInner(target, content, options) {
577
- const morphlexOpts = toMorphlexOptions(options);
578
561
  let contentEl;
579
562
  if (typeof content === 'string') {
580
563
  const wrapper = document.createElement(target.tagName);
@@ -584,71 +567,56 @@ const morphlexEngine = {
584
567
  else {
585
568
  contentEl = content;
586
569
  }
587
- morphlexMorphInner(target, contentEl, morphlexOpts);
588
- },
589
- };
590
- let currentEngine = morphlexEngine;
591
- const morphAdapter = {
592
- morph(target, content, options) {
593
- currentEngine.morph(target, content, options);
594
- },
595
- morphInner(target, content, options) {
596
- currentEngine.morphInner(target, content, options);
570
+ morphInner(target, contentEl, toMorphlexOptions(options));
597
571
  },
598
572
  };
599
573
 
600
- function isViewTransitionsSupported() {
601
- return (typeof document !== 'undefined' && typeof document.startViewTransition === 'function');
574
+ function getStartViewTransition() {
575
+ if (typeof document === 'undefined')
576
+ return undefined;
577
+ return document
578
+ .startViewTransition;
602
579
  }
603
- let config = {
604
- enabled: isViewTransitionsSupported(),
605
- defaultTimeout: 5000};
606
- let transitionQueue = [];
607
- let isProcessingQueue = false;
608
- async function processQueue() {
609
- if (isProcessingQueue || transitionQueue.length === 0) {
610
- return;
611
- }
612
- isProcessingQueue = true;
613
- while (transitionQueue.length > 0) {
614
- const item = transitionQueue.shift();
615
- try {
616
- await executeTransition(item.callback, item.options);
617
- item.resolve();
618
- }
619
- catch (error) {
620
- item.reject(error);
621
- }
622
- }
623
- isProcessingQueue = false;
580
+ function isViewTransitionsSupported() {
581
+ return typeof getStartViewTransition() === 'function';
624
582
  }
625
- async function executeTransition(callback, options) {
626
- const { skipTransition = false, timeout = config.defaultTimeout } = options;
627
- if (!config.enabled || !isViewTransitionsSupported() || skipTransition) {
583
+ const queue = [];
584
+ let processing = false;
585
+ async function runOne(callback) {
586
+ const start = getStartViewTransition();
587
+ if (!start) {
628
588
  await callback();
629
589
  return;
630
590
  }
631
- const transition = document.startViewTransition(async () => {
591
+ const transition = start(async () => {
632
592
  await callback();
633
593
  });
634
- const timeoutPromise = new Promise((_, reject) => {
635
- setTimeout(() => reject(new Error('View transition timed out')), timeout);
636
- });
594
+ await transition.finished;
595
+ }
596
+ async function drain() {
597
+ if (processing)
598
+ return;
599
+ processing = true;
637
600
  try {
638
- await Promise.race([transition.finished, timeoutPromise]);
601
+ while (queue.length > 0) {
602
+ const item = queue.shift();
603
+ try {
604
+ await runOne(item.callback);
605
+ item.resolve();
606
+ }
607
+ catch (error) {
608
+ item.reject(error);
609
+ }
610
+ }
639
611
  }
640
- catch (error) {
612
+ finally {
613
+ processing = false;
641
614
  }
642
615
  }
643
- function withViewTransition(callback, options = {}) {
616
+ function withViewTransition(callback) {
644
617
  return new Promise((resolve, reject) => {
645
- transitionQueue.push({
646
- callback,
647
- options,
648
- resolve,
649
- reject,
650
- });
651
- processQueue().catch(reject);
618
+ queue.push({ callback, resolve, reject });
619
+ drain().catch(reject);
652
620
  });
653
621
  }
654
622
 
@@ -662,18 +630,6 @@ function isHTMLElement(value) {
662
630
  'classList' in value);
663
631
  }
664
632
 
665
- function isDevMode() {
666
- if (typeof window !== 'undefined' && window.__HYPERFIXI_PROD__) {
667
- return false;
668
- }
669
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {
670
- return false;
671
- }
672
- return true;
673
- }
674
- ({
675
- enabled: isDevMode()});
676
-
677
633
  function executeSwap(target, content, strategy, morphOptions) {
678
634
  const contentStr = content !== null && !isHTMLElement(content) ? content : '';
679
635
  const contentEl = isHTMLElement(content) ? content : null;
@@ -769,6 +725,20 @@ function executeSwap(target, content, strategy, morphOptions) {
769
725
  throw new Error(`[HyperFixi] swap: unknown strategy "${strategy}"`);
770
726
  }
771
727
  }
728
+ async function executeSwapWithTransition(targets, content, strategy, options = {}) {
729
+ const { morphOptions, useViewTransition = false } = options;
730
+ const performSwap = () => {
731
+ for (const target of targets) {
732
+ executeSwap(target, content, strategy, morphOptions);
733
+ }
734
+ };
735
+ if (useViewTransition && isViewTransitionsSupported()) {
736
+ await withViewTransition(performSwap);
737
+ }
738
+ else {
739
+ performSwap();
740
+ }
741
+ }
772
742
 
773
743
  function createCustomEvent(eventName, detail, options = {}) {
774
744
  return new CustomEvent(eventName, {
@@ -829,15 +799,7 @@ function createHistorySwap(config) {
829
799
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
830
800
  }
831
801
  const html = await response.text();
832
- const performSwap = () => {
833
- executeSwap(targetElement, html, strategy);
834
- };
835
- if (useViewTransition && isViewTransitionsSupported()) {
836
- await withViewTransition(performSwap);
837
- }
838
- else {
839
- performSwap();
840
- }
802
+ await executeSwapWithTransition([targetElement], html, strategy, { useViewTransition });
841
803
  targetElement.classList.remove('hx-swapping');
842
804
  if (onAfterSwap) {
843
805
  await onAfterSwap(url, html);
@@ -990,15 +952,7 @@ function createBoosted(config) {
990
952
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
991
953
  }
992
954
  const html = await response.text();
993
- const performSwap = () => {
994
- executeSwap(targetElement, html, strategy);
995
- };
996
- if (useViewTransition && isViewTransitionsSupported()) {
997
- await withViewTransition(performSwap);
998
- }
999
- else {
1000
- performSwap();
1001
- }
955
+ await executeSwapWithTransition([targetElement], html, strategy, { useViewTransition });
1002
956
  targetElement.classList.remove('hx-swapping');
1003
957
  container.classList.remove('hx-boosting');
1004
958
  if (pushUrl && method === 'GET') {
@@ -548,31 +548,14 @@ function longestIncreasingSubsequence(sequence) {
548
548
 
549
549
  //# debugId=3F4BCB911DEC843864756E2164756E21
550
550
 
551
- const morphlexMorph = morph;
552
- const morphlexMorphInner = morphInner;
553
551
  function toMorphlexOptions(options) {
554
- if (!options) {
555
- return { preserveChanges: true };
556
- }
557
- return {
558
- preserveChanges: options.preserveChanges ?? true,
559
- beforeNodeVisited: options.beforeNodeVisited,
560
- afterNodeVisited: options.afterNodeVisited,
561
- beforeNodeAdded: options.beforeNodeAdded
562
- ? (node) => options.beforeNodeAdded(node.parentNode, node, null)
563
- : undefined,
564
- afterNodeAdded: options.afterNodeAdded,
565
- beforeNodeRemoved: options.beforeNodeRemoved,
566
- afterNodeRemoved: options.afterNodeRemoved,
567
- };
552
+ return { preserveChanges: options?.preserveChanges ?? true };
568
553
  }
569
- const morphlexEngine = {
554
+ const morphAdapter = {
570
555
  morph(target, content, options) {
571
- const morphlexOpts = toMorphlexOptions(options);
572
- morphlexMorph(target, content, morphlexOpts);
556
+ morph(target, content, toMorphlexOptions(options));
573
557
  },
574
558
  morphInner(target, content, options) {
575
- const morphlexOpts = toMorphlexOptions(options);
576
559
  let contentEl;
577
560
  if (typeof content === 'string') {
578
561
  const wrapper = document.createElement(target.tagName);
@@ -582,71 +565,56 @@ const morphlexEngine = {
582
565
  else {
583
566
  contentEl = content;
584
567
  }
585
- morphlexMorphInner(target, contentEl, morphlexOpts);
586
- },
587
- };
588
- let currentEngine = morphlexEngine;
589
- const morphAdapter = {
590
- morph(target, content, options) {
591
- currentEngine.morph(target, content, options);
592
- },
593
- morphInner(target, content, options) {
594
- currentEngine.morphInner(target, content, options);
568
+ morphInner(target, contentEl, toMorphlexOptions(options));
595
569
  },
596
570
  };
597
571
 
598
- function isViewTransitionsSupported() {
599
- return (typeof document !== 'undefined' && typeof document.startViewTransition === 'function');
572
+ function getStartViewTransition() {
573
+ if (typeof document === 'undefined')
574
+ return undefined;
575
+ return document
576
+ .startViewTransition;
600
577
  }
601
- let config = {
602
- enabled: isViewTransitionsSupported(),
603
- defaultTimeout: 5000};
604
- let transitionQueue = [];
605
- let isProcessingQueue = false;
606
- async function processQueue() {
607
- if (isProcessingQueue || transitionQueue.length === 0) {
608
- return;
609
- }
610
- isProcessingQueue = true;
611
- while (transitionQueue.length > 0) {
612
- const item = transitionQueue.shift();
613
- try {
614
- await executeTransition(item.callback, item.options);
615
- item.resolve();
616
- }
617
- catch (error) {
618
- item.reject(error);
619
- }
620
- }
621
- isProcessingQueue = false;
578
+ function isViewTransitionsSupported() {
579
+ return typeof getStartViewTransition() === 'function';
622
580
  }
623
- async function executeTransition(callback, options) {
624
- const { skipTransition = false, timeout = config.defaultTimeout } = options;
625
- if (!config.enabled || !isViewTransitionsSupported() || skipTransition) {
581
+ const queue = [];
582
+ let processing = false;
583
+ async function runOne(callback) {
584
+ const start = getStartViewTransition();
585
+ if (!start) {
626
586
  await callback();
627
587
  return;
628
588
  }
629
- const transition = document.startViewTransition(async () => {
589
+ const transition = start(async () => {
630
590
  await callback();
631
591
  });
632
- const timeoutPromise = new Promise((_, reject) => {
633
- setTimeout(() => reject(new Error('View transition timed out')), timeout);
634
- });
592
+ await transition.finished;
593
+ }
594
+ async function drain() {
595
+ if (processing)
596
+ return;
597
+ processing = true;
635
598
  try {
636
- await Promise.race([transition.finished, timeoutPromise]);
599
+ while (queue.length > 0) {
600
+ const item = queue.shift();
601
+ try {
602
+ await runOne(item.callback);
603
+ item.resolve();
604
+ }
605
+ catch (error) {
606
+ item.reject(error);
607
+ }
608
+ }
637
609
  }
638
- catch (error) {
610
+ finally {
611
+ processing = false;
639
612
  }
640
613
  }
641
- function withViewTransition(callback, options = {}) {
614
+ function withViewTransition(callback) {
642
615
  return new Promise((resolve, reject) => {
643
- transitionQueue.push({
644
- callback,
645
- options,
646
- resolve,
647
- reject,
648
- });
649
- processQueue().catch(reject);
616
+ queue.push({ callback, resolve, reject });
617
+ drain().catch(reject);
650
618
  });
651
619
  }
652
620
 
@@ -660,18 +628,6 @@ function isHTMLElement(value) {
660
628
  'classList' in value);
661
629
  }
662
630
 
663
- function isDevMode() {
664
- if (typeof window !== 'undefined' && window.__HYPERFIXI_PROD__) {
665
- return false;
666
- }
667
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {
668
- return false;
669
- }
670
- return true;
671
- }
672
- ({
673
- enabled: isDevMode()});
674
-
675
631
  function executeSwap(target, content, strategy, morphOptions) {
676
632
  const contentStr = content !== null && !isHTMLElement(content) ? content : '';
677
633
  const contentEl = isHTMLElement(content) ? content : null;
@@ -767,6 +723,20 @@ function executeSwap(target, content, strategy, morphOptions) {
767
723
  throw new Error(`[HyperFixi] swap: unknown strategy "${strategy}"`);
768
724
  }
769
725
  }
726
+ async function executeSwapWithTransition(targets, content, strategy, options = {}) {
727
+ const { morphOptions, useViewTransition = false } = options;
728
+ const performSwap = () => {
729
+ for (const target of targets) {
730
+ executeSwap(target, content, strategy, morphOptions);
731
+ }
732
+ };
733
+ if (useViewTransition && isViewTransitionsSupported()) {
734
+ await withViewTransition(performSwap);
735
+ }
736
+ else {
737
+ performSwap();
738
+ }
739
+ }
770
740
 
771
741
  function createCustomEvent(eventName, detail, options = {}) {
772
742
  return new CustomEvent(eventName, {
@@ -827,15 +797,7 @@ function createHistorySwap(config) {
827
797
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
828
798
  }
829
799
  const html = await response.text();
830
- const performSwap = () => {
831
- executeSwap(targetElement, html, strategy);
832
- };
833
- if (useViewTransition && isViewTransitionsSupported()) {
834
- await withViewTransition(performSwap);
835
- }
836
- else {
837
- performSwap();
838
- }
800
+ await executeSwapWithTransition([targetElement], html, strategy, { useViewTransition });
839
801
  targetElement.classList.remove('hx-swapping');
840
802
  if (onAfterSwap) {
841
803
  await onAfterSwap(url, html);
@@ -988,15 +950,7 @@ function createBoosted(config) {
988
950
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
989
951
  }
990
952
  const html = await response.text();
991
- const performSwap = () => {
992
- executeSwap(targetElement, html, strategy);
993
- };
994
- if (useViewTransition && isViewTransitionsSupported()) {
995
- await withViewTransition(performSwap);
996
- }
997
- else {
998
- performSwap();
999
- }
953
+ await executeSwapWithTransition([targetElement], html, strategy, { useViewTransition });
1000
954
  targetElement.classList.remove('hx-swapping');
1001
955
  container.classList.remove('hx-boosting');
1002
956
  if (pushUrl && method === 'GET') {
@@ -315,6 +315,12 @@ const COMMAND_IMPLEMENTATIONS_TS = {
315
315
  for (const el of targets) (el as HTMLElement).blur();
316
316
  return targets;
317
317
  }`,
318
+ empty: `
319
+ case 'empty': {
320
+ const targets = await getTarget();
321
+ for (const el of targets) (el as HTMLElement).innerHTML = '';
322
+ return targets;
323
+ }`,
318
324
  return: `
319
325
  case 'return': {
320
326
  const value = cmd.args[0] ? await evaluate(cmd.args[0], ctx) : ctx.it;
@@ -1342,7 +1348,7 @@ const KEYWORDS = new Set([
1342
1348
  'repeat', 'times', 'for', 'each', 'while', 'until',
1343
1349
  'toggle', 'add', 'remove', 'put', 'set', 'get', 'call', 'return', 'append',
1344
1350
  'log', 'send', 'trigger', 'wait', 'settle', 'fetch', 'as',
1345
- 'show', 'hide', 'take', 'increment', 'decrement', 'focus', 'blur', 'go', 'transition', 'over',
1351
+ 'show', 'hide', 'take', 'increment', 'decrement', 'focus', 'blur', 'empty', 'go', 'transition', 'over',
1346
1352
  'the', 'a', 'an', 'my', 'its', 'me', 'it', 'you',
1347
1353
  'first', 'last', 'next', 'previous', 'closest', 'parent',
1348
1354
  'true', 'false', 'null', 'undefined',
@@ -1649,6 +1655,7 @@ class HybridParser {
1649
1655
  decrement: () => this.parseIncDec('decrement'),
1650
1656
  focus: () => this.parseFocusBlur('focus'),
1651
1657
  blur: () => this.parseFocusBlur('blur'),
1658
+ empty: () => this.parseEmpty(),
1652
1659
  go: () => this.parseGo(),
1653
1660
  return: () => this.parseReturn(),
1654
1661
  transition: () => this.parseTransition(),
@@ -1907,6 +1914,15 @@ class HybridParser {
1907
1914
  return { type: 'command', name, args: [], target };
1908
1915
  }
1909
1916
 
1917
+ parseEmpty() {
1918
+ this.expect('empty');
1919
+ let target;
1920
+ if (!this.isAtEnd() && !this.match('then', 'and', 'end', 'else')) {
1921
+ target = this.parseExpression();
1922
+ }
1923
+ return { type: 'command', name: 'empty', args: [], target };
1924
+ }
1925
+
1910
1926
  parseGo() {
1911
1927
  this.expect('go');
1912
1928
  if (this.match('to')) this.advance();
@@ -1986,7 +2002,7 @@ class HybridParser {
1986
2002
  }
1987
2003
 
1988
2004
  isCommandKeyword(token) {
1989
- const cmds = ['toggle', 'add', 'remove', 'set', 'put', 'log', 'send', 'wait', 'show', 'hide', 'increment', 'decrement', 'focus', 'blur', 'go'];
2005
+ const cmds = ['toggle', 'add', 'remove', 'set', 'put', 'log', 'send', 'wait', 'show', 'hide', 'increment', 'decrement', 'focus', 'blur', 'empty', 'go'];
1990
2006
  return cmds.includes(normalizeCommand(token.value));
1991
2007
  }
1992
2008
 
@@ -2245,6 +2261,7 @@ const AVAILABLE_COMMANDS = [
2245
2261
  'put',
2246
2262
  'append',
2247
2263
  'take',
2264
+ 'empty',
2248
2265
  'set',
2249
2266
  'get',
2250
2267
  'increment',
@@ -313,6 +313,12 @@ const COMMAND_IMPLEMENTATIONS_TS = {
313
313
  for (const el of targets) (el as HTMLElement).blur();
314
314
  return targets;
315
315
  }`,
316
+ empty: `
317
+ case 'empty': {
318
+ const targets = await getTarget();
319
+ for (const el of targets) (el as HTMLElement).innerHTML = '';
320
+ return targets;
321
+ }`,
316
322
  return: `
317
323
  case 'return': {
318
324
  const value = cmd.args[0] ? await evaluate(cmd.args[0], ctx) : ctx.it;
@@ -1340,7 +1346,7 @@ const KEYWORDS = new Set([
1340
1346
  'repeat', 'times', 'for', 'each', 'while', 'until',
1341
1347
  'toggle', 'add', 'remove', 'put', 'set', 'get', 'call', 'return', 'append',
1342
1348
  'log', 'send', 'trigger', 'wait', 'settle', 'fetch', 'as',
1343
- 'show', 'hide', 'take', 'increment', 'decrement', 'focus', 'blur', 'go', 'transition', 'over',
1349
+ 'show', 'hide', 'take', 'increment', 'decrement', 'focus', 'blur', 'empty', 'go', 'transition', 'over',
1344
1350
  'the', 'a', 'an', 'my', 'its', 'me', 'it', 'you',
1345
1351
  'first', 'last', 'next', 'previous', 'closest', 'parent',
1346
1352
  'true', 'false', 'null', 'undefined',
@@ -1647,6 +1653,7 @@ class HybridParser {
1647
1653
  decrement: () => this.parseIncDec('decrement'),
1648
1654
  focus: () => this.parseFocusBlur('focus'),
1649
1655
  blur: () => this.parseFocusBlur('blur'),
1656
+ empty: () => this.parseEmpty(),
1650
1657
  go: () => this.parseGo(),
1651
1658
  return: () => this.parseReturn(),
1652
1659
  transition: () => this.parseTransition(),
@@ -1905,6 +1912,15 @@ class HybridParser {
1905
1912
  return { type: 'command', name, args: [], target };
1906
1913
  }
1907
1914
 
1915
+ parseEmpty() {
1916
+ this.expect('empty');
1917
+ let target;
1918
+ if (!this.isAtEnd() && !this.match('then', 'and', 'end', 'else')) {
1919
+ target = this.parseExpression();
1920
+ }
1921
+ return { type: 'command', name: 'empty', args: [], target };
1922
+ }
1923
+
1908
1924
  parseGo() {
1909
1925
  this.expect('go');
1910
1926
  if (this.match('to')) this.advance();
@@ -1984,7 +2000,7 @@ class HybridParser {
1984
2000
  }
1985
2001
 
1986
2002
  isCommandKeyword(token) {
1987
- const cmds = ['toggle', 'add', 'remove', 'set', 'put', 'log', 'send', 'wait', 'show', 'hide', 'increment', 'decrement', 'focus', 'blur', 'go'];
2003
+ const cmds = ['toggle', 'add', 'remove', 'set', 'put', 'log', 'send', 'wait', 'show', 'hide', 'increment', 'decrement', 'focus', 'blur', 'empty', 'go'];
1988
2004
  return cmds.includes(normalizeCommand(token.value));
1989
2005
  }
1990
2006
 
@@ -2243,6 +2259,7 @@ const AVAILABLE_COMMANDS = [
2243
2259
  'put',
2244
2260
  'append',
2245
2261
  'take',
2262
+ 'empty',
2246
2263
  'set',
2247
2264
  'get',
2248
2265
  'increment',