@reventlessdev/reventless-gwt 1.0.0-alpha.142 → 1.0.0-alpha.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +7 -6
- package/rescript.json +1 -0
- package/src/LocalHost.res +15 -19
- package/tests/LocalHostIntegration.res +5 -9
- package/tests/LocalHostIntegration.res.mjs +1 -1
- package/tests/LocalHostTest.res +21 -26
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 1.0.0-alpha.143 (2026-07-31)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @reventlessdev/reventless-gwt
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# 1.0.0-alpha.142 (2026-07-30)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @reventlessdev/reventless-gwt
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-gwt",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.143",
|
|
4
4
|
"description": "Given-When-Then DSLs and test harness for Reventless slice testing",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"sury": "11.0.0-alpha.4",
|
|
17
|
-
"@reventlessdev/
|
|
18
|
-
"@reventlessdev/rescript-
|
|
19
|
-
"@reventlessdev/rescript-
|
|
20
|
-
"@reventlessdev/reventless-
|
|
21
|
-
"@reventlessdev/reventless-
|
|
17
|
+
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
18
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
19
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.0",
|
|
20
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.196",
|
|
21
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.114",
|
|
22
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.89"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"rescript": "12.3.0",
|
package/rescript.json
CHANGED
package/src/LocalHost.res
CHANGED
|
@@ -13,16 +13,6 @@
|
|
|
13
13
|
// path via dynamic import, so a missing local platform is a caller concern, not a
|
|
14
14
|
// compile-time coupling.
|
|
15
15
|
|
|
16
|
-
@module("node:url") external pathToFileURL: string => {"href": string} = "pathToFileURL"
|
|
17
|
-
@module("node:fs") external existsSync: string => bool = "existsSync"
|
|
18
|
-
@module("node:fs") external readFileSync: (string, string) => string = "readFileSync"
|
|
19
|
-
@module("node:path") external join: (string, string) => string = "join"
|
|
20
|
-
@module("node:path") external dirname: string => string = "dirname"
|
|
21
|
-
|
|
22
|
-
type nodeRequire
|
|
23
|
-
@module("node:module") external createRequire: string => nodeRequire = "createRequire"
|
|
24
|
-
@send external requireResolve: (nodeRequire, string) => string = "resolve"
|
|
25
|
-
|
|
26
16
|
let dynamicImport: string => promise<'a> = %raw(`(u) => import(u)`)
|
|
27
17
|
|
|
28
18
|
// Monotonic cache-buster so repeated loads in one process (a watch session
|
|
@@ -35,7 +25,7 @@ let dynamicImport: string => promise<'a> = %raw(`(u) => import(u)`)
|
|
|
35
25
|
let counter = ref(0)
|
|
36
26
|
let bustedUrl = (absolutePath: string): string => {
|
|
37
27
|
counter := counter.contents + 1
|
|
38
|
-
pathToFileURL(absolutePath)["href"] ++ "?t=" ++ Int.toString(counter.contents)
|
|
28
|
+
NodeUrl.pathToFileURL(absolutePath)["href"] ++ "?t=" ++ Int.toString(counter.contents)
|
|
39
29
|
}
|
|
40
30
|
|
|
41
31
|
type pluginRef = {name: string, modulePath: string, packageDir: string}
|
|
@@ -65,7 +55,7 @@ let strField = (json, key) =>
|
|
|
65
55
|
json->JSON.Decode.object->Option.flatMap(d => d->Dict.get(key))->Option.flatMap(JSON.Decode.string)
|
|
66
56
|
|
|
67
57
|
let readJson = path =>
|
|
68
|
-
try Some(readFileSync(path
|
|
58
|
+
try Some(NodeFs.readFileSync(path)->JSON.parseOrThrow) catch {
|
|
69
59
|
| _ => None
|
|
70
60
|
}
|
|
71
61
|
|
|
@@ -73,11 +63,14 @@ let readJson = path =>
|
|
|
73
63
|
// The precedence itself lives in `Reventless.PluginName.resolve`; this only
|
|
74
64
|
// reads the two raw fields with the local node bindings.
|
|
75
65
|
let derivePluginName = (~pluginSrcDir: string): string => {
|
|
76
|
-
let pluginJson = join(pluginSrcDir, "plugin.json")
|
|
66
|
+
let pluginJson = NodePath.join([pluginSrcDir, "plugin.json"])
|
|
77
67
|
let pluginJsonName =
|
|
78
|
-
existsSync(pluginJson)
|
|
68
|
+
NodeFs.existsSync(pluginJson)
|
|
69
|
+
? readJson(pluginJson)->Option.flatMap(j => strField(j, "name"))
|
|
70
|
+
: None
|
|
79
71
|
let packageJsonName =
|
|
80
|
-
readJson(join(dirname(pluginSrcDir), "package.json"))
|
|
72
|
+
readJson(NodePath.join([NodePath.dirname(pluginSrcDir), "package.json"]))
|
|
73
|
+
->Option.flatMap(j => strField(j, "name"))
|
|
81
74
|
Reventless.PluginName.resolve(~pluginJsonName, ~packageJsonName)
|
|
82
75
|
}
|
|
83
76
|
|
|
@@ -85,9 +78,9 @@ let derivePluginName = (~pluginSrcDir: string): string => {
|
|
|
85
78
|
// compiled composition root and pair each with its framework plugin name.
|
|
86
79
|
let discover = (~packageDirs: array<string>): array<pluginRef> =>
|
|
87
80
|
packageDirs->Array.filterMap(dir => {
|
|
88
|
-
let srcDir = join(dir, "src")
|
|
89
|
-
let modulePath = join(srcDir, "Plugin.res.mjs")
|
|
90
|
-
existsSync(modulePath)
|
|
81
|
+
let srcDir = NodePath.join([dir, "src"])
|
|
82
|
+
let modulePath = NodePath.join([srcDir, "Plugin.res.mjs"])
|
|
83
|
+
NodeFs.existsSync(modulePath)
|
|
91
84
|
? Some({name: derivePluginName(~pluginSrcDir=srcDir), modulePath, packageDir: dir})
|
|
92
85
|
: None
|
|
93
86
|
})
|
|
@@ -99,7 +92,10 @@ let discover = (~packageDirs: array<string>): array<pluginRef> =>
|
|
|
99
92
|
// there — callers then skip platform-dependent features (dead-code / graph).
|
|
100
93
|
let localPlatformSpecifier = "@reventlessdev/reventless-local/src/Platform.res.mjs"
|
|
101
94
|
let resolveLocalPlatform = (~fromPackageDir: string): option<string> =>
|
|
102
|
-
try Some(
|
|
95
|
+
try Some(
|
|
96
|
+
NodeModule.createRequire(NodePath.join([fromPackageDir, "package.json"]))
|
|
97
|
+
->NodeModule.requireResolve(localPlatformSpecifier),
|
|
98
|
+
) catch {
|
|
103
99
|
| _ => None
|
|
104
100
|
}
|
|
105
101
|
|
|
@@ -18,15 +18,11 @@
|
|
|
18
18
|
@module("node:assert/strict") external deepEqual: ('a, 'a) => unit = "deepEqual"
|
|
19
19
|
@module("node:assert/strict") external ok: (bool, ~message: string=?) => unit = "ok"
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
let repoRoot = join([here, "..", "..", ".."]) // reventless-gwt/test → repo root
|
|
27
|
-
let catalogDir = join([repoRoot, "examples", "online-shop-aggregates", "catalog"])
|
|
28
|
-
let orderingDir = join([repoRoot, "examples", "online-shop-aggregates", "ordering"])
|
|
29
|
-
let platformPath = join([repoRoot, "reventless", "reventless-local", "src", "Platform.res.mjs"])
|
|
21
|
+
let here = NodePath.dirname(NodeUrl.fileURLToPath(%raw(`import.meta.url`)))
|
|
22
|
+
let repoRoot = NodePath.join([here, "..", "..", ".."]) // reventless-gwt/test → repo root
|
|
23
|
+
let catalogDir = NodePath.join([repoRoot, "examples", "online-shop-aggregates", "catalog"])
|
|
24
|
+
let orderingDir = NodePath.join([repoRoot, "examples", "online-shop-aggregates", "ordering"])
|
|
25
|
+
let platformPath = NodePath.join([repoRoot, "reventless", "local", "src", "Platform.res.mjs"])
|
|
30
26
|
|
|
31
27
|
let structureFor = (g: LocalHost.graph, name) =>
|
|
32
28
|
g.structures->Array.find(((n, _)) => n == name)->Option.map(((_, s)) => s)
|
|
@@ -15,7 +15,7 @@ let catalogDir = Nodepath.join(repoRoot, "examples", "online-shop-aggregates", "
|
|
|
15
15
|
|
|
16
16
|
let orderingDir = Nodepath.join(repoRoot, "examples", "online-shop-aggregates", "ordering");
|
|
17
17
|
|
|
18
|
-
let platformPath = Nodepath.join(repoRoot, "reventless", "
|
|
18
|
+
let platformPath = Nodepath.join(repoRoot, "reventless", "local", "src", "Platform.res.mjs");
|
|
19
19
|
|
|
20
20
|
function structureFor(g, name) {
|
|
21
21
|
return Stdlib_Option.map(g.structures.find(param => param[0] === name), param => param[1]);
|
package/tests/LocalHostTest.res
CHANGED
|
@@ -10,16 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
open JestGlobals
|
|
12
12
|
|
|
13
|
-
@module("node:os") external tmpdir: unit => string = "tmpdir"
|
|
14
|
-
@module("node:path") external join: (string, string) => string = "join"
|
|
15
|
-
|
|
16
|
-
type mkdirOpts = {recursive: bool}
|
|
17
|
-
@module("node:fs/promises")
|
|
18
|
-
external mkdir: (string, mkdirOpts) => promise<Nullable.t<string>> = "mkdir"
|
|
19
|
-
@module("node:fs/promises") external writeFile: (string, string) => promise<unit> = "writeFile"
|
|
20
|
-
type rmOpts = {recursive: bool, force: bool}
|
|
21
|
-
@module("node:fs/promises") external rm: (string, rmOpts) => promise<unit> = "rm"
|
|
22
|
-
|
|
23
13
|
describe("LocalHost.packageNameToPluginName", () => {
|
|
24
14
|
testPromise("PascalCases scoped / dashed / underscored package names", async () => {
|
|
25
15
|
expect(LocalHost.packageNameToPluginName("@scope/my-catalog"))->toBe("MyCatalog")
|
|
@@ -34,27 +24,32 @@ describe("LocalHost name derivation + discovery", () => {
|
|
|
34
24
|
testPromise(
|
|
35
25
|
"derivePluginName prefers plugin.json then PascalCase(package.json); discover skips non-plugins",
|
|
36
26
|
async () => {
|
|
37
|
-
let root = join(tmpdir(), "reventless-localhost-test")
|
|
38
|
-
let _ = await rm(root, {recursive: true, force: true})
|
|
27
|
+
let root = NodePath.join([NodeOs.tmpdir(), "reventless-localhost-test"])
|
|
28
|
+
let _ = await NodeFs.Promises.rm(root, {recursive: true, force: true})
|
|
39
29
|
|
|
40
30
|
// a: explicit plugin.json name + a compiled composition root.
|
|
41
|
-
let a = join(root, "a")
|
|
42
|
-
let aSrc = join(a, "src")
|
|
43
|
-
let _ = await mkdir(aSrc, {recursive: true})
|
|
44
|
-
let _ =
|
|
45
|
-
|
|
46
|
-
let _ =
|
|
31
|
+
let a = NodePath.join([root, "a"])
|
|
32
|
+
let aSrc = NodePath.join([a, "src"])
|
|
33
|
+
let _ = await NodeFs.Promises.mkdir(aSrc, {recursive: true})
|
|
34
|
+
let _ =
|
|
35
|
+
await NodeFs.Promises.writeFile(NodePath.join([a, "package.json"]), `{"name":"@x/a-pkg"}`)
|
|
36
|
+
let _ =
|
|
37
|
+
await NodeFs.Promises.writeFile(NodePath.join([aSrc, "plugin.json"]), `{"name":"Catalog"}`)
|
|
38
|
+
let _ = await NodeFs.Promises.writeFile(NodePath.join([aSrc, "Plugin.res.mjs"]), "")
|
|
47
39
|
|
|
48
40
|
// b: no plugin.json → name falls back to PascalCase(package.json name).
|
|
49
|
-
let b = join(root, "b")
|
|
50
|
-
let bSrc = join(b, "src")
|
|
51
|
-
let _ = await mkdir(bSrc, {recursive: true})
|
|
52
|
-
let _ = await writeFile(
|
|
53
|
-
|
|
41
|
+
let b = NodePath.join([root, "b"])
|
|
42
|
+
let bSrc = NodePath.join([b, "src"])
|
|
43
|
+
let _ = await NodeFs.Promises.mkdir(bSrc, {recursive: true})
|
|
44
|
+
let _ = await NodeFs.Promises.writeFile(
|
|
45
|
+
NodePath.join([b, "package.json"]),
|
|
46
|
+
`{"name":"@scope/my-ordering"}`,
|
|
47
|
+
)
|
|
48
|
+
let _ = await NodeFs.Promises.writeFile(NodePath.join([bSrc, "Plugin.res.mjs"]), "")
|
|
54
49
|
|
|
55
50
|
// c: has src/ but no Plugin.res.mjs → discover must skip it.
|
|
56
|
-
let c = join(root, "c")
|
|
57
|
-
let _ = await mkdir(join(c, "src"), {recursive: true})
|
|
51
|
+
let c = NodePath.join([root, "c"])
|
|
52
|
+
let _ = await NodeFs.Promises.mkdir(NodePath.join([c, "src"]), {recursive: true})
|
|
58
53
|
|
|
59
54
|
expect(LocalHost.derivePluginName(~pluginSrcDir=aSrc))->toBe("Catalog")
|
|
60
55
|
expect(LocalHost.derivePluginName(~pluginSrcDir=bSrc))->toBe("MyOrdering")
|
|
@@ -65,7 +60,7 @@ describe("LocalHost name derivation + discovery", () => {
|
|
|
65
60
|
expect(first.modulePath->String.endsWith("Plugin.res.mjs"))->toBe(true)
|
|
66
61
|
expect(first.packageDir)->toBe(a)
|
|
67
62
|
|
|
68
|
-
let _ = await rm(root, {recursive: true, force: true})
|
|
63
|
+
let _ = await NodeFs.Promises.rm(root, {recursive: true, force: true})
|
|
69
64
|
},
|
|
70
65
|
)
|
|
71
66
|
})
|