diff --git a/README.md b/README.md index 70ffe3e..6da464c 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Deno IO methods as valid Task monads perfect to write great point-free software in JavaScript. -[![deno land](http://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno&labelColor=black)](https://deno.land/x/functional-deno-io@v0.3.2) -[![deno version](https://img.shields.io/badge/deno-^1.3.2-lightgrey?logo=deno)](https://github.com/denoland/deno) -[![GitHub release](https://img.shields.io/github/v/release/sebastienfilion/functional-deno-io)](https://github.com/sebastienfilion/functional-deno-io/releases) -[![GitHub licence](https://img.shields.io/github/license/sebastienfilion/functional-deno-io)](https://github.com/sebastienfilion/functional-deno-io/blob/v0.1.0/LICENSE) +[![deno land](http://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno&labelColor=black)](https://deno.land/x/functional_io@v1.0.0) +[![deno version](https://img.shields.io/badge/deno-^1.5.4-lightgrey?logo=deno)](https://github.com/denoland/deno) +[![GitHub release](https://img.shields.io/github/v/release/sebastienfilion/functional-io)](https://github.com/sebastienfilion/functional-io/releases) +[![GitHub licence](https://img.shields.io/github/license/sebastienfilion/functional-io)](https://github.com/sebastienfilion/functional-io/blob/v1.0.0/LICENSE) * [Buffer](#buffer) * [Directory](#directory) @@ -25,11 +25,11 @@ library that implements the [Fantasy-land specifications](https://github.com/fan ```js import { compose, chain, curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; -import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; -import Buffer from "https://deno.land/x/functional_io@v0.4.2/library/Buffer.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import { close, writeAll, create } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; +import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; +import Buffer from "https://deno.land/x/functional_io@v1.0.0/library/Buffer.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import { close, writeAll, create } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; const writeNewFile = curry( (buffer, destinationFile) => @@ -300,9 +300,9 @@ Change the current working directory to the specified path. `chdir :: Directory a -> Task e Directory a` ```js -import { chdir } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { chdir } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = chdir(Directory("..")); @@ -316,9 +316,9 @@ Changes the permission of a specific file/directory of specified path. Ignores t `chmod :: Number -> Location a -> Task e Location a` ```js -import { chmod } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { chmod } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = chmod(0o000, File.fromPath(`${Deno.cwd()}/hoge`)); @@ -332,9 +332,9 @@ Change owner of a regular file or directory. This functionality is not available `chown :: Number -> Number -> Location a -> Task e Location a` ```js -import { chown } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { chown } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = chown(null, null, File.fromPath(`${Deno.cwd()}/hoge`)); @@ -349,9 +349,9 @@ Closing a file when you are finished with it is important to avoid leaking resou `close :: File a -> Task e File a` ```js -import { close } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { close } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = close(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3)); @@ -365,9 +365,9 @@ Copies from a source to a destination until either EOF (null) is read from the s `copy :: Options -> Buffer a -> Buffer b -> Task e Buffer a` ```js -import { copy } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Buffer from "https://deno.land/x/functional_io@v0.4.2/library/Buffer.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { copy } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Buffer from "https://deno.land/x/functional_io@v1.0.0/library/Buffer.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = copy({}, Buffer(new Uint8Array([ 65, 66, 67, 68, 69 ])), Buffer(new Uint8Array([]))); @@ -382,9 +382,9 @@ else overwriting. Fails if target path is a directory or is unwritable. `copyFile :: File a -> File b -> Task e File b` ```js -import { copyFile } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { copyFile } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = copyFile(File.fromPath(`${Deno.cwd()}/hoge`), File.fromPath(`${Deno.cwd()}/piyo`)); @@ -398,9 +398,9 @@ Creates a file if none exists or truncates an existing file. `create :: File a -> Task e File a` ```js -import { create } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { create } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = create(File.fromPath(`${Deno.cwd()}/hoge`)); @@ -414,15 +414,15 @@ Return a Directory representation of the current working directory. `cwd :: () -> Task e Directory a` ```js -import { cwd } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { cwd } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = cwd(); assert(Task.is(container)); ``` -### `emptyDir` [📕](https://deno.land/std@0.68.0/fs#emptydir) +### `emptyDir` [📕](https://deno.land/std@0.79.0/fs#emptydir) Ensures that a directory is empty. Deletes directory contents if the directory is not empty. If the directory does not exist, it is created. The directory itself is not deleted. @@ -430,32 +430,32 @@ If the directory does not exist, it is created. The directory itself is not dele `emptyDir :: Directory a -> Task e Directory a` ```js -import { emptyDir } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { emptyDir } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = emptyDir(Directory(`${Deno.cwd()}/hoge`)); assert(Task.is(container)); ``` -### `ensureDir` [📕](https://deno.land/std@0.68.0/fs#ensuredir) +### `ensureDir` [📕](https://deno.land/std@0.79.0/fs#ensuredir) Ensures that the directory exists. If the directory structure does not exist, it is created. Like `mkdir -p`. `ensureDir :: Directory a -> Task e Directory a` ```js -import { ensureDir } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { ensureDir } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = emptyDir(Directory(`${Deno.cwd()}/hoge`)); assert(Task.is(container)); ``` -### `exists` [📕](https://deno.land/std@0.68.0/fs#exists) +### `exists` [📕](https://deno.land/std@0.79.0/fs#exists) Test whether the given path exists by checking with the file system. If the file or directory doesn't exist, it will resolve to `Either.Left(null)`. @@ -463,41 +463,41 @@ If the file or directory doesn't exist, it will resolve to `Either.Left(null)`. `exists :: Location a -> Task null Location a` ```js -import { exists } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { exists } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = exists(Directory(`${Deno.cwd()}/hoge`)); assert(Task.is(container)); ``` -### `mkdir` [📕](https://deno.land/std@0.68.0/fs#mkdir) +### `mkdir` [📕](https://deno.land/std@0.79.0/fs#mkdir) Creates a new directory with the specified path. `mkdir :: Options -> Directory a -> Task e Directory a` ```js -import { mkdir } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { mkdir } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = mkdir({}, Directory(`${Deno.cwd()}/hoge`)); assert(Task.is(container)); ``` -### `move` [📕](https://deno.land/std@0.68.0/fs#move) +### `move` [📕](https://deno.land/std@0.79.0/fs#move) Moves a file or directory. `move :: Options -> String -> Location a -> Task e Location b` ```js -import { move } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { move } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = move({}, `${Deno.cwd()}/piyo`, Directory(`${Deno.cwd()}/hoge`)); @@ -512,9 +512,9 @@ createNew open options. It is the callers responsibility to close the file when `open :: Options -> File a -> Task e File a` ```js -import { open } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { open } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = open({ read: true, write: true }, File.fromPath(`${Deno.cwd()}/hoge`)); @@ -528,9 +528,9 @@ Read from a Resource given it has a non-zero raw buffer. `read :: Resource a -> Task e Resource a` ```js -import { read } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { read } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = read(File(`${Deno.cwd()}/hoge`, new Uint8Array(5), 3)); @@ -544,10 +544,10 @@ Read from a Resource. `readAll :: Resource a -> Task e Resource a` ```js -import { readAll } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Buffer from "https://deno.land/x/functional_io@v0.4.2/library/Buffer.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { readAll } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Buffer from "https://deno.land/x/functional_io@v1.0.0/library/Buffer.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = readAll(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3)); @@ -561,9 +561,9 @@ Renames a file or directory. `rename :: String -> Location a -> Task e Location b` ```js -import { rename } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Directory from "https://deno.land/x/functional_io@v0.4.2/library/Directory.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { rename } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Directory from "https://deno.land/x/functional_io@v1.0.0/library/Directory.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = rename(`${Deno.cwd()}/piyo`, Directory(`${Deno.cwd()}/hoge`)); @@ -577,9 +577,9 @@ Write to a Resource given it has a non-zero raw buffer. `write :: Resource a -> Task e Resource a` ```js -import { write } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { write } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = write( File(`${Deno.cwd()}/hoge`, new Uint8Array([ 65, 66, 67, 68, 69 ]), _file.rid) @@ -595,10 +595,10 @@ Write all to a Resource from a Buffer. `writeAll :: Buffer b -> Resource a -> Task e Resource b` ```js -import { writeAll } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Buffer from "https://deno.land/x/functional_io@v0.4.2/library/Buffer.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { writeAll } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Buffer from "https://deno.land/x/functional_io@v1.0.0/library/Buffer.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = writeAll( Buffer(new Uint8Array([ 65, 66, 67, 68, 69 ])), @@ -615,10 +615,10 @@ Write a File to the file system. `writeFile :: Options -> File a -> Task e File b` ```js -import { writeFile } from "https://deno.land/x/functional_io@v0.4.2/library/fs.js"; -import Buffer from "https://deno.land/x/functional_io@v0.4.2/library/Buffer.js"; -import File from "https://deno.land/x/functional_io@v0.4.2/library/File.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { writeFile } from "https://deno.land/x/functional_io@v1.0.0/library/fs.js"; +import Buffer from "https://deno.land/x/functional_io@v1.0.0/library/Buffer.js"; +import File from "https://deno.land/x/functional_io@v1.0.0/library/File.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const container = writeFile( {}, @@ -637,10 +637,10 @@ Fetches a resource on a local/remote server. `fetch :: Request a -> Task e Response b` ```js -import { fetch } from "https://deno.land/x/functional_io@v0.4.2/library/browser-safe.js"; -import Request from "https://deno.land/x/functional_io@v0.4.2/library/Request.js"; -import Response from "https://deno.land/x/functional_io@v0.4.2/library/Response.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { fetch } from "https://deno.land/x/functional_io@v1.0.0/library/browser-safe.js"; +import Request from "https://deno.land/x/functional_io@v1.0.0/library/Request.js"; +import Response from "https://deno.land/x/functional_io@v1.0.0/library/Response.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; const containerA = fetch(Request.GET("http://localhost:8000")); diff --git a/library/Buffer.js b/library/Buffer.js index 7732d9c..1b9d00a 100644 --- a/library/Buffer.js +++ b/library/Buffer.js @@ -1,8 +1,7 @@ -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; -import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; - -export const Buffer = factorizeType("Buffer", [ "raw" ]); +import { curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; +import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; /** * The `Buffer` is the most basic type; it only has one attribute which is a typed array named "raw". @@ -22,6 +21,8 @@ export const Buffer = factorizeType("Buffer", [ "raw" ]); * ``` */ +export const Buffer = factorizeType("Buffer", [ "raw" ]); + Buffer.prototype.ap = Buffer.prototype["fantasy-land/ap"] = function (container) { return Buffer.of(container.raw(this.raw)); @@ -92,4 +93,6 @@ Buffer.prototype.map = Buffer.prototype["fantasy-land/map"] = function (unaryFun Buffer.of = Buffer.prototype.of = Buffer.prototype["fantasy-land/of"] = buffer => Buffer(buffer); +export const factorizeBuffer = curry(Buffer); + export default Buffer; diff --git a/library/Buffer_test.js b/library/Buffer_test.js index 8b4d067..bd046ff 100644 --- a/library/Buffer_test.js +++ b/library/Buffer_test.js @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import Buffer from "./Buffer.js"; diff --git a/library/Directory.js b/library/Directory.js index d6f823a..b8c67b5 100644 --- a/library/Directory.js +++ b/library/Directory.js @@ -1,7 +1,7 @@ -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; -import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; +import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; /** * The `Directory` type represents a directory on the file system. It is the only type with the same shape as `URL`. diff --git a/library/Directory_test.js b/library/Directory_test.js index eae212c..eef66cc 100644 --- a/library/Directory_test.js +++ b/library/Directory_test.js @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import Directory from "./Directory.js"; diff --git a/library/File.js b/library/File.js index 479b052..0ccf4ce 100644 --- a/library/File.js +++ b/library/File.js @@ -1,7 +1,7 @@ -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; -import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; +import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; /** * The `File` type extends the `Resource` type. It represents a file with a path. diff --git a/library/FileSystemCollection.js b/library/FileSystemCollection.js index 994710d..ce1dbee 100644 --- a/library/FileSystemCollection.js +++ b/library/FileSystemCollection.js @@ -1,6 +1,6 @@ -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; -import { $$value } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; +import { $$value } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; /** * The `FileSystemCollection` is represents a collection of `Location`, namely of `Directory` and `File`. This of it diff --git a/library/FileSystemCollection_test.js b/library/FileSystemCollection_test.js index 71d59d9..1c344ee 100644 --- a/library/FileSystemCollection_test.js +++ b/library/FileSystemCollection_test.js @@ -1,4 +1,4 @@ -import { assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import FileSystemCollection from "./FileSystemCollection.js"; import File from "./File.js"; diff --git a/library/File_test.js b/library/File_test.js index 6840344..2dec035 100644 --- a/library/File_test.js +++ b/library/File_test.js @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import File from "./File.js"; diff --git a/library/Request.js b/library/Request.js index b9204b4..8c613cc 100644 --- a/library/Request.js +++ b/library/Request.js @@ -1,6 +1,6 @@ import { curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; /** * The `Request` represent a HTTP request. diff --git a/library/Request_test.js b/library/Request_test.js index caa65f3..143af69 100644 --- a/library/Request_test.js +++ b/library/Request_test.js @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "https://deno.land/std@0.65.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import Request from "./Request.js"; diff --git a/library/Resource.js b/library/Resource.js index b9d138b..dd77215 100644 --- a/library/Resource.js +++ b/library/Resource.js @@ -1,7 +1,8 @@ -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; -import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; +import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; /** * The `Resource` type extends the `Buffer` type. It represents a system resource with a handle, eg: STDOUT, STDIN or a @@ -103,4 +104,6 @@ Resource.prototype.map = Resource.prototype["fantasy-land/map"] = function (unar Resource.of = Resource.prototype.of = Resource.prototype["fantasy-land/of"] = raw => Resource(raw, 0); +export const factorizeResource = curry(Resource); + export default Resource; diff --git a/library/Resource_test.js b/library/Resource_test.js index c228da7..4bc1b2e 100644 --- a/library/Resource_test.js +++ b/library/Resource_test.js @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import Resource from "./Resource.js"; diff --git a/library/Response.js b/library/Response.js index b065526..357a2e9 100644 --- a/library/Response.js +++ b/library/Response.js @@ -1,6 +1,6 @@ import { curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; -import { factorizeSumType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; +import { factorizeSumType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; /** * The `Response` represent a HTTP response. diff --git a/library/Response_test.js b/library/Response_test.js index 3f9a608..38270b4 100644 --- a/library/Response_test.js +++ b/library/Response_test.js @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "https://deno.land/std@0.65.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import Response from "./Response.js"; diff --git a/library/URL.js b/library/URL.js index c6ba29c..5a15bb2 100644 --- a/library/URL.js +++ b/library/URL.js @@ -1,7 +1,7 @@ -import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; -import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; +import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; /** * The `URL` type represents an URL; either of a location on the file system or on a remote server. diff --git a/library/browser_safe.js b/library/browser_safe.js index b3f41b1..33c0442 100644 --- a/library/browser_safe.js +++ b/library/browser_safe.js @@ -1,6 +1,6 @@ import { apply, lift } from "https://x.nest.land/ramda@0.27.0/source/index.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; import Request from "./Request.js"; import Response from "./Response.js"; diff --git a/library/browser_safe_test.js b/library/browser_safe_test.js index d908e6e..d1dd8e7 100644 --- a/library/browser_safe_test.js +++ b/library/browser_safe_test.js @@ -1,9 +1,9 @@ -import { assert } from "https://deno.land/std@0.70.0/testing/asserts.ts"; -import { serve } from "https://deno.land/std@0.74.0/http/server.ts"; +import { assert } from "https://deno.land/std@0.79.0/testing/asserts.ts"; +import { serve } from "https://deno.land/std@0.79.0/http/server.ts"; import { fetch } from "./browser_safe.js"; -import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"; +import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"; import Request from "./Request.js"; const startAsyncIterator = async (state, server, callback) => { diff --git a/library/fs.js b/library/fs.js index b1e9e9a..91ab770 100644 --- a/library/fs.js +++ b/library/fs.js @@ -4,15 +4,15 @@ import { ensureSymlink as _ensureSymlink, exists as _exists, move as _move -} from "https://deno.land/std@0.70.0/fs/mod.ts"; -import { curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; -import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js" -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js" +} from "https://deno.land/std@0.79.0/fs/mod.ts"; +import { compose, curry } from "https://x.nest.land/ramda@0.27.0/source/index.js"; +import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js" +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js" import Buffer from "./Buffer.js"; import Directory from "./Directory.js"; import File from "./File.js"; import Resource from "./Resource.js"; -import { coerceAsReader, coerceAsWriter } from "./utilities.js"; +import { coerceAsReader, coerceAsWriter, factorizeUint8Array } from "./utilities.js"; // chdir :: Directory a -> Task e Directory a export const chdir = directory => Directory.isOrThrow(directory) @@ -32,10 +32,10 @@ export const chown = curry( .map(_ => File(file.path, file.raw, file.rid)) ); -// close :: File a -> Task e File a -export const close = file => File.isOrThrow(file) - && Task.wrap(_ => Deno.close(file.rid) || Promise.resolve(undefined)) - .map(_ => File(file.path, file.raw, file.rid)); +// close :: Resource a -> Task e Resource a +export const close = resource => Resource.isOrThrow(resource) + && Task.wrap(_ => Deno.close(resource.rid) || Promise.resolve(undefined)) + .map(_ => resource.constructor.from({ ...resource })); // copy :: Options -> Buffer a -> Buffer b -> Task e Buffer a export const copy = curry( @@ -75,18 +75,18 @@ export const ensureSymlink = directory => Directory.isOrThrow(directory) && Task.wrap(_ => _ensureSymlink(directory.path)) .map(_ => Directory(directory.path)); -// exists :: Location a -> Task null Location a -export const exists = location => { - if (!Directory.is(location) && !File.is(location)) { - throw new Error(`Expected a Directory or a File but got a "${typeof location}"`); +// exists :: URL a -> Task null URL a +export const exists = url => { + if (!Directory.is(url) && !File.is(url)) { + throw new Error(`Expected a Directory or a File but got a "${typeof url}"`); } - return Task.wrap(_ => _exists(location.path)) + return Task.wrap(_ => _exists(url.path)) .map( fileExists => { if (!fileExists) return Either.Left(null); - return location.constructor.from({ ...location }); + return url.constructor.from({ ...url }); } ) }; @@ -98,11 +98,11 @@ export const mkdir = curry( .map(_ => Directory(directory.path)) ); -// move :: Options -> String -> Location a -> Task e Location b +// move :: Options -> String -> URL a -> Task e URL b export const move = curry( - (options, destinationPath, location) => location.hasOwnProperty("path") - && Task.wrap(_ => _move(location.path, destinationPath)) - .map(_ => location.constructor.from({ ...location, path: destinationPath })) + (options, destinationPath, url) => url.hasOwnProperty("path") + && Task.wrap(_ => _move(url.path, destinationPath)) + .map(_ => url.constructor.from({ ...url, path: destinationPath })) ); // open :: Options -> File a -> Task e File a @@ -121,6 +121,34 @@ export const read = resource => { .map(_ => resource.constructor.from({ ...resource, raw: _buffer })) }; +// readLine :: Resource a -> Task e Resource a +export const readLine = resource => Task.wrap(async _ => { + let _accumulatorBuffer = new Uint8Array(1024); + let index = 0; + let _buffer = new Uint8Array(1); + let reachedCL = false; + + while (await Deno.read(resource.rid, _buffer)) { + _accumulatorBuffer[index++] = _buffer[0]; + if (reachedCL && _buffer[0] === 10) break; + reachedCL = _buffer[0] === 13; + _buffer = new Uint8Array(1); + } + + return resource.constructor.from({ ...resource, raw: _accumulatorBuffer.slice(0, index) }); +}); + +// readNBytes :: Number -> Resource a -> Task e Resource a +export const readNBytes = curry( + compose( + read, + (n, resource) => resource.constructor.from({ ...resource, raw: factorizeUint8Array(n) }) + ) +); + +// readOneByte :: Resource a -> Task e Resource a +export const readOneByte = readNBytes(1); + // readAll :: Resource a -> Task e Resource a export const readAll = resource => Resource.isOrThrow(resource) && Task.wrap(_ => Deno.readAll(coerceAsReader(resource))) @@ -131,18 +159,18 @@ export const readFile = file => File.isOrThrow(file) && Task.wrap(_ => Deno.readFile(file.path)) .map(_buffer => File(file.path, _buffer, file.rid)); -// remove :: Options -> Location a -> Task e Location a +// remove :: Options -> URL a -> Task e URL a export const remove = curry( - (options, location) => location.hasOwnProperty("path") - && Task.wrap(_ => Deno.remove(location.path, options)) - .map(_ => location.constructor.from({ ...location })) + (options, url) => url.hasOwnProperty("path") + && Task.wrap(_ => Deno.remove(url.path, options)) + .map(_ => url.constructor.from({ ...url })) ); -// rename :: String -> Location a -> Task e Location b +// rename :: String -> URL a -> Task e URL b export const rename = curry( - (destinationPath, location) => location.hasOwnProperty("path") - && Task.wrap(_ => Deno.rename(location.path, destinationPath)) - .map(_ => location.constructor.from({ ...location, path: destinationPath })) + (destinationPath, url) => url.hasOwnProperty("path") + && Task.wrap(_ => Deno.rename(url.path, destinationPath)) + .map(_ => url.constructor.from({ ...url, path: destinationPath })) ); // write :: Resource a -> Task e Resource a @@ -164,3 +192,4 @@ export const writeFile = curry( && Task.wrap(_ => Deno.writeFile(file.path, file.raw, options)) .map(_ => file.constructor.from({ ...file })) ); + diff --git a/library/fs_test.js b/library/fs_test.js index 1e5f7c8..b02d987 100644 --- a/library/fs_test.js +++ b/library/fs_test.js @@ -12,13 +12,13 @@ import { replace, trim } from "https://x.nest.land/ramda@0.27.0/source/index.js"; -import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import { emptyDir as _emptyDir, ensureDir as _ensureDir -} from "https://deno.land/std@0.70.0/fs/mod.ts"; -import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js" -import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js" +} from "https://deno.land/std@0.79.0/fs/mod.ts"; +import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js" +import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js" import { chdir, chmod, @@ -37,6 +37,7 @@ import { read, readAll, readFile, + readNBytes, remove, rename, write, @@ -47,7 +48,7 @@ import Buffer from "./Buffer.js"; import Directory from "./Directory.js"; import File from "./File.js"; -import { $$value } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js"; +import { $$value } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js"; Deno.test( "Integration: chdir", @@ -515,6 +516,32 @@ Deno.test( } ); +Deno.test( + "Integration: readNBytes", + async () => { + await _ensureDir(`${Deno.cwd()}/dump`); + await Deno.writeTextFile(`${Deno.cwd()}/dump/hoge`, "ABCDE"); + const _file = await Deno.open(`${Deno.cwd()}/dump/hoge`, { read: true, write: true }); + + const containerA = readNBytes(5, File(`${Deno.cwd()}/dump/hoge`, new Uint8Array([]), _file.rid)); + const promise = containerA.run(); + + assert(Task.is(containerA)); + assert(promise instanceof Promise); + + const containerB = await promise; + + assert(Either.Right.is(containerB)); + assertEquals( + containerB.toString(), + `Either.Right(File("${Deno.cwd()}/dump/hoge", 65,66,67,68,69, ${_file.rid}))` + ); + + await Deno.remove(`${Deno.cwd()}/dump/hoge`); + Deno.close(_file.rid); + } +); + Deno.test( "Integration: readFile", async () => { diff --git a/library/network.js b/library/network.js index dae82ab..1aa6f1d 100644 --- a/library/network.js +++ b/library/network.js @@ -1,5 +1,5 @@ import { Connection } from "./Resource.js"; -import Task from "https://deno.land/x/functional@v1.0.0/library/Task"; +import Task from "https://deno.land/x/functional@v1.2.1/library/Task"; // connect :: Connection a -> Task e Connection a export const connect = connection => Connection.isOrThrow(connection) diff --git a/library/utilities.js b/library/utilities.js index 84454ae..ffc4fee 100644 --- a/library/utilities.js +++ b/library/utilities.js @@ -1,3 +1,81 @@ +import { + __, + always, + ap, + compose, + flip, + gte, + ifElse, + map, + prop, + reduce, + slice, + subtract, +} from "https://x.nest.land/ramda@0.27.0/source/index.js"; + +import Pair from "https://deno.land/x/functional@v1.2.1/library/Pair.js"; + +const CHARACTER_CODE_CL = "\r".charCodeAt(0); +const CHARACTER_CODE_RF = "\n".charCodeAt(0); + +const $$decoder = new TextDecoder(); +const $$encoder = new TextEncoder(); + +export const decodeRaw = $$decoder.decode.bind($$decoder); +export const encodeText = $$encoder.encode.bind($$encoder); + +// findCLRFIndex :: Uint8Array -> Number +export const findCLRFIndex = compose( + prop("second"), + reduce( + ({ first: index, second: cursor }, characterCode) => + index === -1 && Pair(index, cursor) + || ( + characterCode === CHARACTER_CODE_CL && cursor === -1 + ? Pair(index + 1, index) + : characterCode === CHARACTER_CODE_RF && cursor !== -1 + ? Pair(-1, index + 1) + : Pair(index + 1, -1) + ), + Pair(0, -1) + ) +); + +export const discardFirstLine = ap(flip(slice(__, Infinity)), findCLRFIndex); + +export const discardNCharacter = slice(__, Infinity); + +export const getFirstLine = ap(flip(slice(0)), findCLRFIndex); + +export const joinCLRF = reduce( + (accumulator, _buffer) => new Uint8Array([ ...accumulator, 13, 10, ..._buffer ]), + new Uint8Array([]) +); + +// splitCLRF :: Uint8Array -> Uint8Array[] +export const splitCLRF = characterCodeList => { + const accumulator = []; + let remainingCharacterCodeList = characterCodeList; + + while (true) { + if (remainingCharacterCodeList.length === 0) break; + const index = findCLRFIndex(remainingCharacterCodeList); + accumulator.push( + remainingCharacterCodeList.slice(0, index === -1 ? remainingCharacterCodeList.length : index) + ); + if (index === -1) break; + remainingCharacterCodeList = remainingCharacterCodeList.slice(index, remainingCharacterCodeList.length); + } + + return accumulator; +}; + +// mapBuffer :: Buffer -> (String -> String) -> Buffer +export const mapBuffer = unaryFunction => map(compose(encodeText, unaryFunction, decodeRaw)); + +// trimCRLF :: Uint8Array -> Uint8Array +export const trimCRLF = ap(flip(slice(0)), compose(ifElse(flip(gte)(0), subtract(__, 2), always(Infinity)), findCLRFIndex)); + export const coerceAsReader = resource => { return { @@ -31,4 +109,6 @@ export const coerceAsWriter = resource => { }, ...resource }; -}; \ No newline at end of file +}; + +export const factorizeUint8Array = x => new Uint8Array(x); diff --git a/library/utilities_test.js b/library/utilities_test.js index b35f482..bf610da 100644 --- a/library/utilities_test.js +++ b/library/utilities_test.js @@ -1,7 +1,7 @@ -import { assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts"; +import { assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts"; import Buffer from "./Buffer.js"; -import { coerceAsReader, coerceAsWriter } from "./utilities.js"; +import { coerceAsReader, coerceAsWriter, findCLRFIndex, splitCLRF, trimCRLF } from "./utilities.js"; Deno.test( "coerceAsReader", @@ -123,4 +123,78 @@ Deno.test( assertEquals(promiseG, Promise.resolve(5)); assertEquals(promiseH, Promise.resolve(5)); } -); \ No newline at end of file +); + +Deno.test( + "findCLRFIndex", + () => { + assertEquals( + findCLRFIndex(new Uint8Array([ 104, 111, 103, 101, 13, 10 ])), + 6 + ); + + assertEquals( + findCLRFIndex(new Uint8Array([ 104, 111, 103, 101, 13, 10, 104, 111, 103, 101, 13, 10 ])), + 6 + ); + + assertEquals( + findCLRFIndex(new Uint8Array([ 104, 111, 103, 101, 13, 104, 111, 103, 101 ])), + -1 + ); + + assertEquals( + findCLRFIndex(new Uint8Array([ 104, 111, 103, 101, 10, 104, 111, 103, 101 ])), + -1 + ); + } +); + +Deno.test( + "splitCLRF", + () => { + assertEquals( + splitCLRF(new Uint8Array([ 104, 111, 103, 101, 13, 10 ])), + [ + new Uint8Array([ 104, 111, 103, 101, 13, 10 ]) + ] + ); + + assertEquals( + splitCLRF(new Uint8Array([ 104, 111, 103, 101, 13, 10, 104, 111, 103, 101, 13, 10 ])), + [ + new Uint8Array([ 104, 111, 103, 101, 13, 10 ]), + new Uint8Array([ 104, 111, 103, 101, 13, 10 ]) + ] + ); + + assertEquals( + splitCLRF(new Uint8Array([ 104, 111, 103, 101, 13, 104, 111, 103, 101 ])), + [ + new Uint8Array([ 104, 111, 103, 101, 13, 104, 111, 103, 101 ]) + ] + ); + + assertEquals( + splitCLRF(new Uint8Array([ 104, 111, 103, 101, 10, 104, 111, 103, 101 ])), + [ + new Uint8Array([ 104, 111, 103, 101, 10, 104, 111, 103, 101 ]) + ] + ); + } +); + +Deno.test( + "trimCRLF", + () => { + assertEquals( + trimCRLF(new Uint8Array([ 104, 111, 103, 101, 13, 10 ])), + new Uint8Array([ 104, 111, 103, 101 ]) + ); + + assertEquals( + trimCRLF(new Uint8Array([ 104, 111, 103, 101 ])), + new Uint8Array([ 104, 111, 103, 101 ]) + ); + } +); diff --git a/scratch.js b/scratch.js deleted file mode 100644 index f210fad..0000000 --- a/scratch.js +++ /dev/null @@ -1,7 +0,0 @@ -import { serve } from "https://deno.land/std@0.70.0/http/server.ts"; -const server = serve({ port:8000 }); -console.debug("FU") - -for await (const request of server) { - request.respond({ body: "hello world" }); -} \ No newline at end of file