Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7c5a6ab
Migrated FFI to ES modules via 'lebab'
JordanMartinez Mar 22, 2022
ff22b78
Replaced 'export var' with 'export const'
JordanMartinez Mar 22, 2022
6282baf
Removed '"use strict";' in FFI files
JordanMartinez Mar 22, 2022
ab56663
Update to CI to use 'unstable' purescript
JordanMartinez Mar 22, 2022
818bccd
Add CI test: verify 'bower.json' file works via pulp
JordanMartinez Mar 22, 2022
bb64123
Ignore spago-based tests (temporarily)
JordanMartinez Mar 22, 2022
369c9c0
Update Bower dependencies to master or main
JordanMartinez Mar 22, 2022
0d9f9e2
Update packages.dhall to 'prepare-0.15' package set
JordanMartinez Mar 22, 2022
d3981cd
Removed unneeded 'psci-support' package
JordanMartinez Mar 22, 2022
9b5f9fa
Update psa to 0.8.2
JordanMartinez Mar 22, 2022
5cc59de
Fix type var shadowing
JordanMartinez Mar 23, 2022
72650e6
Update eslint to ES6
JordanMartinez Mar 23, 2022
34272b6
Fix linting issue
JordanMartinez Mar 23, 2022
7ef18ae
Move psci-support to dev dep
JordanMartinez Mar 23, 2022
37681db
Replace _ajax with driver arg
JordanMartinez Mar 29, 2022
ad30bb9
Drop tests
JordanMartinez Mar 29, 2022
f42ab4a
Export Xhr and AffjaxDriver types
JordanMartinez Mar 29, 2022
1153e04
Add affjax driver to each request
JordanMartinez Mar 29, 2022
599aafe
Fix imports
JordanMartinez Mar 29, 2022
97a3614
Port driver code to own module
JordanMartinez Mar 29, 2022
c77b622
Export AffjaxDriver type
JordanMartinez Mar 29, 2022
3d51eed
Redefine AffjaxDriver as foreign data type
JordanMartinez Mar 29, 2022
06f8612
Drop Fn2 type import
JordanMartinez Mar 29, 2022
2351b1a
Fix formatting issues
JordanMartinez Mar 29, 2022
e62e276
Add changelog entry
JordanMartinez Mar 31, 2022
69d69b9
Drop Xhr type
JordanMartinez Mar 31, 2022
537e7ca
Move driver back into affjax
JordanMartinez Mar 31, 2022
26ef843
Fix imports
JordanMartinez Mar 31, 2022
dd50a2c
Fix usages of `F` alias
JordanMartinez Mar 31, 2022
61da61e
Instruct new envs to re-export Affjax things
JordanMartinez Mar 31, 2022
c7221dc
Clarify how to fix broken code
JordanMartinez Mar 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"env": { "commonjs": true },
"extends": "eslint:recommended",
"parserOptions": { "ecmaVersion": 5 },
"parserOptions": { "ecmaVersion": 6, "sourceType": "module" },
"rules": {
"block-scoped-var": "error",
"consistent-return": "error",
Expand Down
14 changes: 12 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
- name: Set up PureScript toolchain
uses: purescript-contrib/setup-purescript@main
with:
purescript: "unstable"
purs-tidy: "latest"

- name: Cache PureScript dependencies
Expand Down Expand Up @@ -49,8 +50,17 @@ jobs:
- name: Build the project
run: npm run build

- name: Run tests
run: npm run test
# - name: Run tests
# run: npm run test

- name: Check formatting
run: purs-tidy check src test

- name: Verify Bower & Pulp
run: |
npm install bower pulp@16.0.0-0
npx bower install
npx pulp build -- --censor-lib --strict
if [ -d "test" ]; then
npx pulp test
fi
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ Notable changes to this project are documented in this file. The format is based
## [Unreleased]

Breaking changes:
- Update project and deps to PureScript v0.15.0 (#171 by @JordanMartinez)
- Update all request functions to take a driver arg (#171 by @JordanMartinez)

Affjax works on the Node.js and browser environments by relying on a `require`
statement within a function. Depending on the environment detected,
either `XHR` or `XmlHttpRequest` is used. Since ES modules do not allow
one to call `import` within a function in a _synchronous_ way,
we cannot continue to use this approach.

Rather, all request-related functions (e.g. `request`, `get`, etc.) now take
as their first argument an `AffjaxDriver` value. Different environments
will pass in their implementation for that driver and re-export
the functionality defined in `affjax`.

To fix your code, depend on the corresponding library below and update the imported
module from `Affjax` to `Affjax.Node`/`Affjax.Web`:
- If on Node.js, use [`purescript-affjax-node`](https://github.com/purescript-contrib/purescript-affjax-node/).
- If on the brower, use [`purescript-affjax-web`](https://github.com/purescript-contrib/purescript-affjax-web/).

New features:

Expand Down
56 changes: 29 additions & 27 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,34 @@
"package.json"
],
"dependencies": {
"purescript-aff": "^v6.0.0",
"purescript-argonaut-core": "^v6.0.0",
"purescript-arraybuffer-types": "^v3.0.0",
"purescript-arrays": "^v6.0.0",
"purescript-console": "^v5.0.0",
"purescript-control": "^v5.0.0",
"purescript-datetime": "^v5.0.0",
"purescript-effect": "^v3.0.0",
"purescript-either": "^v5.0.0",
"purescript-exceptions": "^v5.0.0",
"purescript-foldable-traversable": "^v5.0.0",
"purescript-foreign": "^v6.0.0",
"purescript-foreign-object": "^v3.0.0",
"purescript-form-urlencoded": "^v6.0.0",
"purescript-functions": "^v5.0.0",
"purescript-http-methods": "^v5.0.0",
"purescript-lists": "^v6.0.0",
"purescript-maybe": "^v5.0.0",
"purescript-media-types": "^v5.0.0",
"purescript-newtype": "^v4.0.0",
"purescript-nullable": "^v5.0.0",
"purescript-prelude": "^v5.0.0",
"purescript-psci-support": "^v5.0.0",
"purescript-transformers": "^v5.0.0",
"purescript-web-dom": "^v5.0.0",
"purescript-web-file": "^v3.0.0",
"purescript-web-xhr": "^v4.0.0"
"purescript-aff": "main",
"purescript-argonaut-core": "main",
"purescript-arraybuffer-types": "main",
"purescript-arrays": "master",
"purescript-console": "master",
"purescript-control": "master",
"purescript-datetime": "master",
"purescript-effect": "master",
"purescript-either": "master",
"purescript-exceptions": "master",
"purescript-foldable-traversable": "master",
"purescript-foreign": "master",
"purescript-foreign-object": "master",
"purescript-form-urlencoded": "main",
"purescript-functions": "master",
"purescript-http-methods": "main",
"purescript-lists": "master",
"purescript-maybe": "master",
"purescript-media-types": "main",
"purescript-newtype": "master",
"purescript-nullable": "main",
"purescript-prelude": "master",
"purescript-transformers": "master",
"purescript-web-dom": "master",
"purescript-web-file": "master",
"purescript-web-xhr": "master"
},
"devDependencies": {
"purescript-psci-support": "master"
}
}
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
{
"private": true,
"scripts": {
"build": "eslint src && spago build --purs-args '--censor-lib --strict'",
"test": "spago test --no-install"
"build": "eslint src && spago build --purs-args '--censor-lib --strict'"
},
"devDependencies": {
"body-parser": "^1.19.0",
"eslint": "^7.10.0",
"express": "^4.17.1",
"purescript-psa": "^0.8.0",
"purescript-psa": "^0.8.2",
"xhr2": "^0.2.0"
}
}
2 changes: 1 addition & 1 deletion packages.dhall
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.14.3-20210722/packages.dhall sha256:1ceb43aa59436bf5601bac45f6f3781c4e1f0e4c2b8458105b018e5ed8c30f8c
https://raw.githubusercontent.com/purescript/package-sets/prepare-0.15/src/packages.dhall

in upstream
3 changes: 1 addition & 2 deletions spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@
, "newtype"
, "nullable"
, "prelude"
, "psci-support"
, "transformers"
, "web-dom"
, "web-file"
, "web-xhr"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
, sources = [ "src/**/*.purs" ]
}
134 changes: 45 additions & 89 deletions src/Affjax.js
Original file line number Diff line number Diff line change
@@ -1,96 +1,52 @@
/* global XMLHttpRequest */
/* global process */
"use strict";

exports._ajax = function () {
var platformSpecific = { };
if (typeof module !== "undefined" && module.require && !(typeof process !== "undefined" && process.versions["electron"])) {
// We are on node.js
platformSpecific.newXHR = function () {
var XHR = module.require("xhr2");
return new XHR();
};

platformSpecific.fixupUrl = function (url, xhr) {
if (xhr.nodejsBaseUrl === null) {
var urllib = module.require("url");
var u = urllib.parse(url);
u.protocol = u.protocol || "http:";
u.hostname = u.hostname || "localhost";
return urllib.format(u);
} else {
return url || "/";
export function _ajax(platformSpecificDriver, timeoutErrorMessageIdent, requestFailedMessageIdent, mkHeader, options) {
return function (errback, callback) {
var xhr = platformSpecificDriver.newXHR();
var fixedUrl = platformSpecificDriver.fixupUrl(options.url, xhr);
xhr.open(options.method || "GET", fixedUrl, true, options.username, options.password);
if (options.headers) {
try {
// eslint-disable-next-line no-eq-null,eqeqeq
for (var i = 0, header; (header = options.headers[i]) != null; i++) {
xhr.setRequestHeader(header.field, header.value);
}
} catch (e) {
errback(e);
}
}
var onerror = function (msgIdent) {
return function () {
errback(new Error(msgIdent));
};
};

platformSpecific.getResponse = function (xhr) {
return xhr.response;
};
} else {
// We are in the browser
platformSpecific.newXHR = function () {
return new XMLHttpRequest();
};

platformSpecific.fixupUrl = function (url) {
return url || "/";
};

platformSpecific.getResponse = function (xhr) {
return xhr.response;
xhr.onerror = onerror(requestFailedMessageIdent);
xhr.ontimeout = onerror(timeoutErrorMessageIdent);
xhr.onload = function () {
callback({
status: xhr.status,
statusText: xhr.statusText,
headers: xhr.getAllResponseHeaders().split("\r\n")
.filter(function (header) {
return header.length > 0;
})
.map(function (header) {
var i = header.indexOf(":");
return mkHeader(header.substring(0, i))(header.substring(i + 2));
}),
body: xhr.response
});
};
}
xhr.responseType = options.responseType;
xhr.withCredentials = options.withCredentials;
xhr.timeout = options.timeout;
xhr.send(options.content);

return function (timeoutErrorMessageIdent, requestFailedMessageIdent, mkHeader, options) {
return function (errback, callback) {
var xhr = platformSpecific.newXHR();
var fixedUrl = platformSpecific.fixupUrl(options.url, xhr);
xhr.open(options.method || "GET", fixedUrl, true, options.username, options.password);
if (options.headers) {
try {
// eslint-disable-next-line no-eq-null,eqeqeq
for (var i = 0, header; (header = options.headers[i]) != null; i++) {
xhr.setRequestHeader(header.field, header.value);
}
} catch (e) {
errback(e);
}
return function (error, cancelErrback, cancelCallback) {
try {
xhr.abort();
} catch (e) {
return cancelErrback(e);
}
var onerror = function (msgIdent) {
return function () {
errback(new Error(msgIdent));
};
};
xhr.onerror = onerror(requestFailedMessageIdent);
xhr.ontimeout = onerror(timeoutErrorMessageIdent);
xhr.onload = function () {
callback({
status: xhr.status,
statusText: xhr.statusText,
headers: xhr.getAllResponseHeaders().split("\r\n")
.filter(function (header) {
return header.length > 0;
})
.map(function (header) {
var i = header.indexOf(":");
return mkHeader(header.substring(0, i))(header.substring(i + 2));
}),
body: platformSpecific.getResponse(xhr)
});
};
xhr.responseType = options.responseType;
xhr.withCredentials = options.withCredentials;
xhr.timeout = options.timeout;
xhr.send(options.content);

return function (error, cancelErrback, cancelCallback) {
try {
xhr.abort();
} catch (e) {
return cancelErrback(e);
}
return cancelCallback();
};
return cancelCallback();
};
};
}();
}
Loading