@reventlessdev/reventless-gwt 1.0.0-alpha.74

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 (172) hide show
  1. package/CHANGELOG.md +698 -0
  2. package/LICENSE +202 -0
  3. package/bin/reventless-dev.mjs +21 -0
  4. package/package.json +54 -0
  5. package/rescript.json +36 -0
  6. package/src/.gwtignore +10 -0
  7. package/src/Automation_GWT.res +207 -0
  8. package/src/Automation_GWT.res.mjs +160 -0
  9. package/src/Behavior_GWT.res +603 -0
  10. package/src/Behavior_GWT.res.mjs +426 -0
  11. package/src/Bind.res +29 -0
  12. package/src/Bind.res.mjs +22 -0
  13. package/src/BuildClassifier.res +137 -0
  14. package/src/BuildClassifier.res.mjs +136 -0
  15. package/src/Cancellation.res +31 -0
  16. package/src/Cancellation.res.mjs +45 -0
  17. package/src/ChildProcess.res +84 -0
  18. package/src/ChildProcess.res.mjs +92 -0
  19. package/src/Cli.res +671 -0
  20. package/src/Cli.res.mjs +754 -0
  21. package/src/Collector.res +201 -0
  22. package/src/Collector.res.mjs +215 -0
  23. package/src/ComponentMeta.res +104 -0
  24. package/src/ComponentMeta.res.mjs +120 -0
  25. package/src/ComponentScan.res +103 -0
  26. package/src/ComponentScan.res.mjs +105 -0
  27. package/src/Delegate_GWT.res +303 -0
  28. package/src/Delegate_GWT.res.mjs +372 -0
  29. package/src/Diff.res +91 -0
  30. package/src/Diff.res.mjs +98 -0
  31. package/src/Discovery.res +105 -0
  32. package/src/Discovery.res.mjs +103 -0
  33. package/src/DomainDeadCode.res +93 -0
  34. package/src/DomainDeadCode.res.mjs +69 -0
  35. package/src/DomainGraph.res +0 -0
  36. package/src/DomainGraph.res.mjs +0 -0
  37. package/src/EventMapping_GWT.res +29 -0
  38. package/src/EventMapping_GWT.res.mjs +44 -0
  39. package/src/Filter.res +36 -0
  40. package/src/Filter.res.mjs +40 -0
  41. package/src/Flow_GWT.res +664 -0
  42. package/src/Flow_GWT.res.mjs +604 -0
  43. package/src/FormatterHuman.res +138 -0
  44. package/src/FormatterHuman.res.mjs +122 -0
  45. package/src/FormatterJson.res +257 -0
  46. package/src/FormatterJson.res.mjs +320 -0
  47. package/src/FormatterJunit.res +93 -0
  48. package/src/FormatterJunit.res.mjs +90 -0
  49. package/src/FormatterTap.res +139 -0
  50. package/src/FormatterTap.res.mjs +149 -0
  51. package/src/FormatterVsCode.res +362 -0
  52. package/src/FormatterVsCode.res.mjs +564 -0
  53. package/src/Hint.res +119 -0
  54. package/src/Hint.res.mjs +124 -0
  55. package/src/InboundTranslation_GWT.res +83 -0
  56. package/src/InboundTranslation_GWT.res.mjs +94 -0
  57. package/src/JestBind.res +70 -0
  58. package/src/JestBind.res.mjs +63 -0
  59. package/src/Loader.res +24 -0
  60. package/src/Loader.res.mjs +23 -0
  61. package/src/LocalHost.res +135 -0
  62. package/src/LocalHost.res.mjs +127 -0
  63. package/src/Mapping_GWT.res +474 -0
  64. package/src/Mapping_GWT.res.mjs +322 -0
  65. package/src/MultiSourceProjection_GWT.res +316 -0
  66. package/src/MultiSourceProjection_GWT.res.mjs +354 -0
  67. package/src/OutboundTranslation_GWT.res +238 -0
  68. package/src/OutboundTranslation_GWT.res.mjs +186 -0
  69. package/src/Outcome.res +161 -0
  70. package/src/Outcome.res.mjs +140 -0
  71. package/src/PackageScan.res +80 -0
  72. package/src/PackageScan.res.mjs +81 -0
  73. package/src/PlatformRunner.res +160 -0
  74. package/src/PlatformRunner.res.mjs +155 -0
  75. package/src/PlatformScan.res +138 -0
  76. package/src/PlatformScan.res.mjs +131 -0
  77. package/src/ProcessManager.res +91 -0
  78. package/src/ProcessManager.res.mjs +80 -0
  79. package/src/Projection_GWT.res +312 -0
  80. package/src/Projection_GWT.res.mjs +332 -0
  81. package/src/Query_GWT.res +379 -0
  82. package/src/Query_GWT.res.mjs +367 -0
  83. package/src/RenderRescript.res +125 -0
  84. package/src/RenderRescript.res.mjs +141 -0
  85. package/src/RunnerTypes.res +68 -0
  86. package/src/RunnerTypes.res.mjs +60 -0
  87. package/src/SideEffect_GWT.res +157 -0
  88. package/src/SideEffect_GWT.res.mjs +113 -0
  89. package/src/StateChange/ExternalAddCategorySlice.res +25 -0
  90. package/src/StateChange/ExternalAddCategorySlice.res.mjs +34 -0
  91. package/src/StateChange/ExternalAddCategorySlice_Behavior.res +19 -0
  92. package/src/StateChange/ExternalAddCategorySlice_Behavior.res.mjs +46 -0
  93. package/src/StateChange/WithFixtures.res +22 -0
  94. package/src/StateChange/WithFixtures.res.mjs +31 -0
  95. package/src/StateChange/WithFixtures_Behavior.res +17 -0
  96. package/src/StateChange/WithFixtures_Behavior.res.mjs +37 -0
  97. package/src/StateChange/WithManualOpen.res +23 -0
  98. package/src/StateChange/WithManualOpen.res.mjs +31 -0
  99. package/src/StateChange/WithManualOpen_Behavior.res +17 -0
  100. package/src/StateChange/WithManualOpen_Behavior.res.mjs +37 -0
  101. package/src/StubRuntime.res +53 -0
  102. package/src/StubRuntime.res.mjs +54 -0
  103. package/src/TestFixtures.res +16 -0
  104. package/src/TestFixtures.res.mjs +34 -0
  105. package/src/Watch.res +92 -0
  106. package/src/Watch.res.mjs +83 -0
  107. package/src/WatcherProbe.res +48 -0
  108. package/src/WatcherProbe.res.mjs +46 -0
  109. package/tests/AutomationGwtTest.res +71 -0
  110. package/tests/AutomationGwtTest.res.mjs +189 -0
  111. package/tests/BuildClassifierTest.res +94 -0
  112. package/tests/BuildClassifierTest.res.mjs +132 -0
  113. package/tests/ComponentMetaTest.res +52 -0
  114. package/tests/ComponentMetaTest.res.mjs +57 -0
  115. package/tests/DelegateGwtTest.res +487 -0
  116. package/tests/DelegateGwtTest.res.mjs +891 -0
  117. package/tests/DiscoveryTest.res +42 -0
  118. package/tests/DiscoveryTest.res.mjs +43 -0
  119. package/tests/DomainDeadCodeTest.res +116 -0
  120. package/tests/DomainDeadCodeTest.res.mjs +155 -0
  121. package/tests/DomainGraphTest.res +365 -0
  122. package/tests/DomainGraphTest.res.mjs +413 -0
  123. package/tests/FlowAggregateGwtTest.res +169 -0
  124. package/tests/FlowAggregateGwtTest.res.mjs +269 -0
  125. package/tests/FlowCrossPluginGwtTest.res +340 -0
  126. package/tests/FlowCrossPluginGwtTest.res.mjs +798 -0
  127. package/tests/FlowGwtTest.res +222 -0
  128. package/tests/FlowGwtTest.res.mjs +432 -0
  129. package/tests/FormatterVsCodeMessageTest.res +41 -0
  130. package/tests/FormatterVsCodeMessageTest.res.mjs +42 -0
  131. package/tests/InboundTranslationGwtTest.res +34 -0
  132. package/tests/InboundTranslationGwtTest.res.mjs +98 -0
  133. package/tests/LocalHostIntegration.res +70 -0
  134. package/tests/LocalHostIntegration.res.mjs +64 -0
  135. package/tests/LocalHostTest.res +71 -0
  136. package/tests/LocalHostTest.res.mjs +63 -0
  137. package/tests/MappingGwtTest.res +348 -0
  138. package/tests/MappingGwtTest.res.mjs +592 -0
  139. package/tests/OutboundTranslationGwtTest.res +59 -0
  140. package/tests/OutboundTranslationGwtTest.res.mjs +138 -0
  141. package/tests/PlatformRunnerTest.res +66 -0
  142. package/tests/PlatformRunnerTest.res.mjs +85 -0
  143. package/tests/PlatformScanTest.res +61 -0
  144. package/tests/PlatformScanTest.res.mjs +56 -0
  145. package/tests/QueryGwtTest.res +161 -0
  146. package/tests/QueryGwtTest.res.mjs +314 -0
  147. package/tests/QueryResolverGwtTest.res +71 -0
  148. package/tests/QueryResolverGwtTest.res.mjs +136 -0
  149. package/tests/RunnerUnitTest.res +219 -0
  150. package/tests/RunnerUnitTest.res.mjs +244 -0
  151. package/tests/SideEffect/FakeOrderNotification.res +23 -0
  152. package/tests/SideEffect/FakeOrderNotification.res.mjs +36 -0
  153. package/tests/SideEffect/FakeOrderNotificationGwtTest.res +35 -0
  154. package/tests/SideEffect/FakeOrderNotificationGwtTest.res.mjs +73 -0
  155. package/tests/SideEffect/MockEmail.res +18 -0
  156. package/tests/SideEffect/MockEmail.res.mjs +47 -0
  157. package/tests/StateChange/ExternalAddCategorySlice_GWT.res +27 -0
  158. package/tests/StateChange/ExternalAddCategorySlice_GWT.res.mjs +70 -0
  159. package/tests/StateChange/WithFixtures_Fixtures.res +9 -0
  160. package/tests/StateChange/WithFixtures_Fixtures.res.mjs +20 -0
  161. package/tests/StateChange/WithFixtures_GWT.res +23 -0
  162. package/tests/StateChange/WithFixtures_GWT.res.mjs +56 -0
  163. package/tests/StateChange/WithManualOpen_Fixtures.res +7 -0
  164. package/tests/StateChange/WithManualOpen_Fixtures.res.mjs +20 -0
  165. package/tests/StateChange/WithManualOpen_GWT.res +17 -0
  166. package/tests/StateChange/WithManualOpen_GWT.res.mjs +56 -0
  167. package/tests/StateChangeSliceGwtTest.res +160 -0
  168. package/tests/StateChangeSliceGwtTest.res.mjs +280 -0
  169. package/tests/StateViewSliceGwtTest.res +64 -0
  170. package/tests/StateViewSliceGwtTest.res.mjs +161 -0
  171. package/tests/WatchDebounceTest.res +78 -0
  172. package/tests/WatchDebounceTest.res.mjs +97 -0
@@ -0,0 +1,103 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Nodepath from "node:path";
4
+ import * as Promises from "node:fs/promises";
5
+
6
+ let ignoreNames = [
7
+ "node_modules",
8
+ ".git",
9
+ "dist",
10
+ "lib",
11
+ ".history"
12
+ ];
13
+
14
+ function shouldIgnore(name) {
15
+ return ignoreNames.includes(name);
16
+ }
17
+
18
+ let gwtIgnoreFile = ".gwtignore";
19
+
20
+ function isPruned(entries) {
21
+ return entries.some(e => e.name === gwtIgnoreFile);
22
+ }
23
+
24
+ function isGwtTestFile(name) {
25
+ if (name.endsWith("_GWT.res.mjs") || name.endsWith("GwtTest.res.mjs")) {
26
+ return true;
27
+ } else {
28
+ return name.endsWith("Gwt.res.mjs");
29
+ }
30
+ }
31
+
32
+ async function walk(dir, acc) {
33
+ let entries;
34
+ try {
35
+ entries = await Promises.readdir(dir, {
36
+ withFileTypes: true
37
+ });
38
+ } catch (exn) {
39
+ entries = [];
40
+ }
41
+ if (isPruned(entries)) {
42
+ return acc;
43
+ }
44
+ let found = acc;
45
+ for (let i = 0, i_finish = entries.length; i < i_finish; ++i) {
46
+ let entry = entries[i];
47
+ if (!ignoreNames.includes(entry.name)) {
48
+ let full = Nodepath.join(dir, entry.name);
49
+ if (entry.isDirectory()) {
50
+ let nested = await walk(full, []);
51
+ found = found.concat(nested);
52
+ } else if (entry.isFile() && isGwtTestFile(entry.name)) {
53
+ found = found.concat([full]);
54
+ }
55
+ }
56
+ }
57
+ return found;
58
+ }
59
+
60
+ async function discover(roots) {
61
+ let found = [];
62
+ for (let i = 0, i_finish = roots.length; i < i_finish; ++i) {
63
+ let root = roots[i];
64
+ let absolute = Nodepath.isAbsolute(root) ? root : Nodepath.resolve(root);
65
+ let isDir;
66
+ try {
67
+ let s = await Promises.stat(absolute);
68
+ isDir = s.isDirectory();
69
+ } catch (exn) {
70
+ isDir = false;
71
+ }
72
+ if (isDir) {
73
+ let collected = await walk(absolute, []);
74
+ found = found.concat(collected);
75
+ } else if (isGwtTestFile(absolute)) {
76
+ found = found.concat([absolute]);
77
+ }
78
+ }
79
+ let seen = {};
80
+ let unique = [];
81
+ found.forEach(path => {
82
+ let match = seen[path];
83
+ if (match !== undefined) {
84
+ return;
85
+ } else {
86
+ seen[path] = true;
87
+ unique.push(path);
88
+ return;
89
+ }
90
+ });
91
+ return unique;
92
+ }
93
+
94
+ export {
95
+ ignoreNames,
96
+ shouldIgnore,
97
+ gwtIgnoreFile,
98
+ isPruned,
99
+ isGwtTestFile,
100
+ walk,
101
+ discover,
102
+ }
103
+ /* node:path Not a pure module */
@@ -0,0 +1,93 @@
1
+ // Domain-level dead-code analysis (Phase 5). Pure reflection over the loaded
2
+ // pluginStructures (LocalHost.loadGraph): finds produced event
3
+ // types that no component consumes — the event-sourcing counterpart to reactive
4
+ // dead code, the domain layer the language LSP cannot see.
5
+ //
6
+ // An event is reachable when ANY of these hold:
7
+ // 1. Some component lists it in `consumedEventTypes` — the DCB-style link used by
8
+ // state-view slices, automation slices, outbound translations, and aggregate /
9
+ // state-change-slice consistency reads. Scanned across ALL plugins, so a
10
+ // cross-plugin consumer clears it.
11
+ // 2. The producing write-side has a non-empty `linkedViews`. Classic aggregate →
12
+ // read-model projections express the link on the PRODUCER side (the read model's
13
+ // `consumedEventTypes` is empty; it projects the aggregate's whole stream). This
14
+ // is event-opaque, so a write-side with at least one linked view is treated as
15
+ // fully consumed — see the precision caveat below.
16
+ // A produced event matched by neither of these is reported as an orphan, anchored on
17
+ // the producing write-side declaration.
18
+ //
19
+ // Precision caveat: because classic read models carry no per-event consumption, rule
20
+ // (2) is conservative — a write-side with a linked view is never flagged, even if a
21
+ // specific event it produces is projected by nothing. This avoids false positives at
22
+ // the cost of missing per-event orphans inside an otherwise-projected aggregate. DCB
23
+ // consumers (rule 1) keep full per-event precision.
24
+ //
25
+ // Scope (v1): orphan produced events only. "Extension points with zero extensions"
26
+ // and "read models nothing resolves against" need data `pluginStructure` does not
27
+ // carry (the EP declaration list / the id-resolver table) — deferred.
28
+
29
+ type finding = {
30
+ kind: string, // "OrphanEvent"
31
+ pluginName: string, // plugin owning the producer
32
+ componentName: string, // the producing aggregate / state-change slice
33
+ detail: string, // the orphaned event type
34
+ }
35
+
36
+ let analyze = (
37
+ ~structures: array<(string, Reventless.Plugin.pluginStructure)>,
38
+ ): array<finding> => {
39
+ // Every event type consumed anywhere becomes a key in `consumed`.
40
+ let consumed = Dict.make()
41
+ let mark = (evt: string) => consumed->Dict.set(evt, true)
42
+ structures->Array.forEach(((_, s)) => {
43
+ s.readModels->Array.forEach((q: Reventless.Plugin.queryableDef) =>
44
+ q.consumedEventTypes->Array.forEach(mark)
45
+ )
46
+ s.stateViewSlices->Array.forEach((q: Reventless.Plugin.queryableDef) =>
47
+ q.consumedEventTypes->Array.forEach(mark)
48
+ )
49
+ s.aggregates->Array.forEach((w: Reventless.Plugin.writableDef) =>
50
+ w.consumedEventTypes->Array.forEach(mark)
51
+ )
52
+ s.stateChangeSlices->Array.forEach((w: Reventless.Plugin.writableDef) =>
53
+ w.consumedEventTypes->Array.forEach(mark)
54
+ )
55
+ s.automationSlices->Array.forEach((a: Reventless.Plugin.automationSliceDef) =>
56
+ a.consumedEventTypes->Array.forEach(mark)
57
+ )
58
+ s.outboundTranslationSlices->Array.forEach((o: Reventless.Plugin.outboundTranslationSliceDef) =>
59
+ o.consumedEventTypes->Array.forEach(mark)
60
+ )
61
+ s.extensions->Array.forEach((e: Reventless.Plugin.extensionDef) =>
62
+ e.eventTypes->Array.forEach(mark)
63
+ )
64
+ })
65
+
66
+ // Produced events with no consumer, reported per producing write-side. A write-side
67
+ // with a linked view is treated as fully consumed (rule 2 above).
68
+ let findings = []
69
+ let scanProducers = (pluginName, writables: array<Reventless.Plugin.writableDef>) =>
70
+ writables->Array.forEach(w =>
71
+ if w.linkedViews->Array.length > 0 {
72
+ ()
73
+ } else {
74
+ w.producedEventTypes->Array.forEach(evt =>
75
+ switch consumed->Dict.get(evt) {
76
+ | Some(_) => ()
77
+ | None =>
78
+ findings->Array.push({
79
+ kind: "OrphanEvent",
80
+ pluginName,
81
+ componentName: w.name,
82
+ detail: evt,
83
+ })
84
+ }
85
+ )
86
+ }
87
+ )
88
+ structures->Array.forEach(((pluginName, s)) => {
89
+ scanProducers(pluginName, s.aggregates)
90
+ scanProducers(pluginName, s.stateChangeSlices)
91
+ })
92
+ findings
93
+ }
@@ -0,0 +1,69 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ function analyze(structures) {
5
+ let consumed = {};
6
+ let mark = evt => {
7
+ consumed[evt] = true;
8
+ };
9
+ structures.forEach(param => {
10
+ let s = param[1];
11
+ s.readModels.forEach(q => {
12
+ q.consumedEventTypes.forEach(mark);
13
+ });
14
+ s.stateViewSlices.forEach(q => {
15
+ q.consumedEventTypes.forEach(mark);
16
+ });
17
+ s.aggregates.forEach(w => {
18
+ w.consumedEventTypes.forEach(mark);
19
+ });
20
+ s.stateChangeSlices.forEach(w => {
21
+ w.consumedEventTypes.forEach(mark);
22
+ });
23
+ s.automationSlices.forEach(a => {
24
+ a.consumedEventTypes.forEach(mark);
25
+ });
26
+ s.outboundTranslationSlices.forEach(o => {
27
+ o.consumedEventTypes.forEach(mark);
28
+ });
29
+ s.extensions.forEach(e => {
30
+ e.eventTypes.forEach(mark);
31
+ });
32
+ });
33
+ let findings = [];
34
+ let scanProducers = (pluginName, writables) => {
35
+ writables.forEach(w => {
36
+ if (w.linkedViews.length !== 0) {
37
+ return;
38
+ } else {
39
+ w.producedEventTypes.forEach(evt => {
40
+ let match = consumed[evt];
41
+ if (match !== undefined) {
42
+ return;
43
+ } else {
44
+ findings.push({
45
+ kind: "OrphanEvent",
46
+ pluginName: pluginName,
47
+ componentName: w.name,
48
+ detail: evt
49
+ });
50
+ return;
51
+ }
52
+ });
53
+ return;
54
+ }
55
+ });
56
+ };
57
+ structures.forEach(param => {
58
+ let s = param[1];
59
+ let pluginName = param[0];
60
+ scanProducers(pluginName, s.aggregates);
61
+ scanProducers(pluginName, s.stateChangeSlices);
62
+ });
63
+ return findings;
64
+ }
65
+
66
+ export {
67
+ analyze,
68
+ }
69
+ /* No side effect */
Binary file
Binary file
@@ -0,0 +1,29 @@
1
+ open ReventlessCore
2
+
3
+ // Stage 5 — `EventMapping_GWT` is now a thin alias over `Mapping_GWT`
4
+ // specialised for the Aggregate → Aggregate case. New tests should use
5
+ // `Mapping_GWT.Make` directly with `Mapping_GWT.FromBehavior` adapters; this
6
+ // wrapper is retained for migration backward-compat with consumers that were
7
+ // already calling `EventMapping_GWT.Make(Source, SourceBehavior, Target,
8
+ // TargetBehavior, EventMapping)` before Stage 5 landed.
9
+
10
+ module Make = (
11
+ Source: Reventless.Aggregate.Spec,
12
+ SourceBehavior: Behavior.T with module Spec = Source,
13
+ Target: Reventless.Aggregate.Spec,
14
+ TargetBehavior: Behavior.T with module Spec = Target,
15
+ EventMapping: Reventless.EventMapping.T
16
+ with module Source = Source
17
+ and module Target = Target,
18
+ ) => {
19
+ module AdaptedSource = Mapping_GWT.FromBehavior(Source, SourceBehavior)
20
+ module AdaptedTarget = Mapping_GWT.FromBehavior(Target, TargetBehavior)
21
+
22
+ module BoundMapping = {
23
+ module Source = AdaptedSource
24
+ module Target = AdaptedTarget
25
+ let map = EventMapping.map
26
+ }
27
+
28
+ include Mapping_GWT.Make(BoundMapping)
29
+ }
@@ -0,0 +1,44 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Mapping_GWT$ReventlessGwt from "./Mapping_GWT.res.mjs";
4
+
5
+ function Make(Source) {
6
+ return SourceBehavior => (Target => (TargetBehavior => (EventMapping => {
7
+ let AdaptedSource = Mapping_GWT$ReventlessGwt.FromBehavior(Source)(SourceBehavior);
8
+ let AdaptedTarget = Mapping_GWT$ReventlessGwt.FromBehavior(Target)(TargetBehavior);
9
+ let map = EventMapping.map;
10
+ let BoundMapping = {
11
+ Source: undefined,
12
+ Target: undefined,
13
+ map: map
14
+ };
15
+ let include = Mapping_GWT$ReventlessGwt.Make({
16
+ Source: AdaptedSource,
17
+ Target: AdaptedTarget,
18
+ map: map
19
+ });
20
+ return {
21
+ AdaptedSource: AdaptedSource,
22
+ AdaptedTarget: AdaptedTarget,
23
+ BoundMapping: BoundMapping,
24
+ Source: include.Source,
25
+ Target: include.Target,
26
+ describe: include.describe,
27
+ test: include.test,
28
+ givenSourceEvents: include.givenSourceEvents,
29
+ andTargetEvents: include.andTargetEvents,
30
+ whenSourceCmd: include.whenSourceCmd,
31
+ thenTargetEvents: include.thenTargetEvents,
32
+ thenTargetEvent: include.thenTargetEvent,
33
+ thenNoTargetEvent: include.thenNoTargetEvent,
34
+ thenSourceError: include.thenSourceError,
35
+ thenTargetError: include.thenTargetError,
36
+ thenTargetEventsWithError: include.thenTargetEventsWithError
37
+ };
38
+ })));
39
+ }
40
+
41
+ export {
42
+ Make,
43
+ }
44
+ /* Mapping_GWT-ReventlessGwt Not a pure module */
package/src/Filter.res ADDED
@@ -0,0 +1,36 @@
1
+ // Source-level test filters: `only`, `skip`, `xtest`, `xdescribe`.
2
+ //
3
+ // Jest ships `describe.only` / `test.only` / `xtest` as properties/aliases
4
+ // on the globals; reventless-gwt exposes them as explicit helpers. When the
5
+ // CLI runner is active, they mutate `Collector` state; when Jest is driving,
6
+ // they forward to the Jest globals.
7
+
8
+ @val external jestXTest: (string, unit => unit) => unit = "xtest"
9
+ @val external jestXDescribe: (string, unit => unit) => unit = "xdescribe"
10
+
11
+ // Mark the next registered `test` / `testPromise` as skipped.
12
+ let skip = () => Collector.markSkipNext()
13
+
14
+ // Mark the next registered `test` / `testPromise` as the focus of the run.
15
+ // If at least one entry is flagged `Only`, only those entries execute.
16
+ let only = () => Collector.markOnlyNext()
17
+
18
+ // xtest: register a test but mark it as skipped.
19
+ let xtest = (~slice as _: option<string>=?, name: string, _body: unit => Outcome.outcome) =>
20
+ if Collector.isActive() {
21
+ Collector.markSkipNext()
22
+ Collector.push(name, () => Promise.resolve(Outcome.pass))
23
+ } else {
24
+ jestXTest(name, () => ())
25
+ }
26
+
27
+ // xdescribe: register a describe block with every nested test pre-marked
28
+ // skipped.
29
+ let xdescribe = (label: string, body: unit => unit) =>
30
+ if Collector.isActive() {
31
+ Collector.skipDepth := Collector.skipDepth.contents + 1
32
+ Collector.pushDescribe(label, body)
33
+ Collector.skipDepth := Collector.skipDepth.contents - 1
34
+ } else {
35
+ jestXDescribe(label, body)
36
+ }
@@ -0,0 +1,40 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
4
+ import * as Collector$ReventlessGwt from "./Collector.res.mjs";
5
+
6
+ function skip() {
7
+ Collector$ReventlessGwt.markSkipNext();
8
+ }
9
+
10
+ function only() {
11
+ Collector$ReventlessGwt.markOnlyNext();
12
+ }
13
+
14
+ function xtest(param, name, _body) {
15
+ if (Collector$ReventlessGwt.isActive()) {
16
+ Collector$ReventlessGwt.markSkipNext();
17
+ return Collector$ReventlessGwt.push(undefined, undefined, name, () => Promise.resolve(Outcome$ReventlessGwt.pass));
18
+ } else {
19
+ globalThis.xtest(name, () => {});
20
+ return;
21
+ }
22
+ }
23
+
24
+ function xdescribe(label, body) {
25
+ if (Collector$ReventlessGwt.isActive()) {
26
+ Collector$ReventlessGwt.skipDepth.contents = Collector$ReventlessGwt.skipDepth.contents + 1 | 0;
27
+ Collector$ReventlessGwt.pushDescribe(label, body);
28
+ Collector$ReventlessGwt.skipDepth.contents = Collector$ReventlessGwt.skipDepth.contents - 1 | 0;
29
+ } else {
30
+ globalThis.xdescribe(label, body);
31
+ }
32
+ }
33
+
34
+ export {
35
+ skip,
36
+ only,
37
+ xtest,
38
+ xdescribe,
39
+ }
40
+ /* No side effect */