Skip to content

Commit f359176

Browse files
committed
Initial commit
0 parents  commit f359176

File tree

12 files changed

+509
-0
lines changed

12 files changed

+509
-0
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/bower_components/
2+
/node_modules/
3+
/.pulp-cache/
4+
/output/
5+
/generated-docs/
6+
/.psc-package/
7+
/.psc*
8+
/.purs*
9+
/.psa*
10+
/.spago

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 purescript-contrib
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# purescript-js-blob
2+
Low-level bindings for the [`Blob` API](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob).
3+
4+
**Note:** If you are using Node.js then you will need Node.js version >= v15.7.0, v14.18.0

package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "purescript-js-blob",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"build": "spago build",
8+
"test": "spago -x test.dhall test"
9+
},
10+
"keywords": [],
11+
"author": "",
12+
"license": "MIT"
13+
}

packages.dhall

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
{-
2+
Welcome to your new Dhall package-set!
3+
4+
Below are instructions for how to edit this file for most use
5+
cases, so that you don't need to know Dhall to use it.
6+
7+
## Use Cases
8+
9+
Most will want to do one or both of these options:
10+
1. Override/Patch a package's dependency
11+
2. Add a package not already in the default package set
12+
13+
This file will continue to work whether you use one or both options.
14+
Instructions for each option are explained below.
15+
16+
### Overriding/Patching a package
17+
18+
Purpose:
19+
- Change a package's dependency to a newer/older release than the
20+
default package set's release
21+
- Use your own modified version of some dependency that may
22+
include new API, changed API, removed API by
23+
using your custom git repo of the library rather than
24+
the package set's repo
25+
26+
Syntax:
27+
where `entityName` is one of the following:
28+
- dependencies
29+
- repo
30+
- version
31+
-------------------------------
32+
let upstream = --
33+
in upstream
34+
with packageName.entityName = "new value"
35+
-------------------------------
36+
37+
Example:
38+
-------------------------------
39+
let upstream = --
40+
in upstream
41+
with halogen.version = "master"
42+
with halogen.repo = "https://example.com/path/to/git/repo.git"
43+
44+
with halogen-vdom.version = "v4.0.0"
45+
with halogen-vdom.dependencies = [ "extra-dependency" ] # halogen-vdom.dependencies
46+
-------------------------------
47+
48+
### Additions
49+
50+
Purpose:
51+
- Add packages that aren't already included in the default package set
52+
53+
Syntax:
54+
where `<version>` is:
55+
- a tag (i.e. "v4.0.0")
56+
- a branch (i.e. "master")
57+
- commit hash (i.e. "701f3e44aafb1a6459281714858fadf2c4c2a977")
58+
-------------------------------
59+
let upstream = --
60+
in upstream
61+
with new-package-name =
62+
{ dependencies =
63+
[ "dependency1"
64+
, "dependency2"
65+
]
66+
, repo =
67+
"https://example.com/path/to/git/repo.git"
68+
, version =
69+
"<version>"
70+
}
71+
-------------------------------
72+
73+
Example:
74+
-------------------------------
75+
let upstream = --
76+
in upstream
77+
with benchotron =
78+
{ dependencies =
79+
[ "arrays"
80+
, "exists"
81+
, "profunctor"
82+
, "strings"
83+
, "quickcheck"
84+
, "lcg"
85+
, "transformers"
86+
, "foldable-traversable"
87+
, "exceptions"
88+
, "node-fs"
89+
, "node-buffer"
90+
, "node-readline"
91+
, "datetime"
92+
, "now"
93+
]
94+
, repo =
95+
"https://github.com/hdgarrood/purescript-benchotron.git"
96+
, version =
97+
"v7.0.0"
98+
}
99+
-------------------------------
100+
-}
101+
let upstream =
102+
https://github.com/purescript/package-sets/releases/download/psc-0.15.7-20230310/packages.dhall
103+
sha256:c30c50d19c9eb55516b0a8a1bd368a0754bde47365be36abadb489295d86d77c
104+
105+
in upstream

spago.dhall

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{ name = "js-blob"
2+
, dependencies =
3+
[ "arrays"
4+
, "console"
5+
, "effect"
6+
, "integers"
7+
, "maybe"
8+
, "media-types"
9+
, "newtype"
10+
, "nullable"
11+
, "numbers"
12+
, "prelude"
13+
, "unsafe-coerce"
14+
]
15+
, packages = ./packages.dhall
16+
, sources = [ "src/**/*.purs" ]
17+
}

src/Js/Blob.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
export function typeImpl(blob) {
2+
return blob.type;
3+
}
4+
5+
const fromSources = function (sources, options) {
6+
if (options === null) {
7+
return new Blob(sources);
8+
} else {
9+
return new Blob(sources, options);
10+
}
11+
};
12+
13+
export const fromStringsImpl = function (sources) {
14+
return function (options) {
15+
return fromSources(sources, options);
16+
};
17+
};
18+
19+
export function size(blob) {
20+
return blob.size;
21+
}
22+
23+
export function sliceImpl(contentType) {
24+
return function (start) {
25+
return function (end) {
26+
return function (blob) {
27+
if (contentType != null) {
28+
return blob.slice(start, end, contentType);
29+
} else {
30+
return blob.slice(start, end);
31+
}
32+
};
33+
};
34+
};
35+
}
36+
37+
export const text = function (blob) {
38+
return function () {
39+
return blob.text();
40+
};
41+
};
42+
43+
export const toArrayBuffer = function (blob) {
44+
return function () {
45+
return blob.arrayBuffer();
46+
};
47+
};
48+
49+
export const fromArrayBuffersImpl = function (sources) {
50+
return function (options) {
51+
return fromSources(sources, options);
52+
};
53+
};
54+
55+
export const fromBlobsImpl = function (sources) {
56+
return function (options) {
57+
return fromSources(sources, options);
58+
};
59+
};
60+
61+
export const fromDataViewImpl = function (sources) {
62+
return function (options) {
63+
return fromSources(sources, options);
64+
};
65+
};

src/Js/Blob.purs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
module Js.Blob
2+
( Blob
3+
, BlobEnding(..)
4+
, BlobOptions
5+
, ByteIdx
6+
, EndByte(..)
7+
, StartByte(..)
8+
, fromArrayBuffers
9+
, fromBlobs
10+
, fromDataView
11+
, fromString
12+
, fromStrings
13+
, idxFromInt
14+
, idxFromNumber
15+
, size
16+
, slice
17+
, slice'
18+
, text
19+
, toArrayBuffer
20+
, type_
21+
) where
22+
23+
import Control.Applicative ((<#>))
24+
import Data.Array.NonEmpty (NonEmptyArray)
25+
import Data.Array.NonEmpty as NonEmptyArray
26+
import Data.ArrayBuffer.Types (ArrayBuffer, DataView)
27+
import Data.Int (toNumber)
28+
import Data.Maybe (Maybe(..))
29+
import Data.MediaType (MediaType(..))
30+
import Data.Newtype (un)
31+
import Data.Nullable (Nullable, toNullable)
32+
import Data.Nullable as Nullable
33+
import Data.Number (round)
34+
import Effect (Effect)
35+
import Prelude ((#), (==), (>>>))
36+
import Promise (Promise)
37+
import Unsafe.Coerce (unsafeCoerce)
38+
39+
foreign import data Blob :: Type
40+
41+
data BlobEnding = Transparent | Native
42+
43+
type BlobOptions =
44+
{ "type" :: MediaType
45+
, endings :: BlobEnding
46+
}
47+
48+
type BlobOptionsImpl =
49+
{ "type" :: String
50+
, endings :: String
51+
}
52+
53+
toBlobOptionsImpl :: BlobOptions -> BlobOptionsImpl
54+
toBlobOptionsImpl { "type": mediaType, endings } =
55+
{ "type": un MediaType mediaType
56+
, endings: toEndings endings
57+
}
58+
where
59+
toEndings Transparent = "transparent"
60+
toEndings Native = "native"
61+
62+
foreign import fromStringsImpl :: Array String -> Nullable BlobOptionsImpl -> Blob
63+
64+
-- | Creates a String with the given Mediatype
65+
-- | For example:
66+
-- | ```
67+
-- | myBlob = fromString (unsafeStringify { name: "Carl", age: 25 }) (MediaType "application/json")
68+
-- | ```
69+
fromString :: String -> Maybe BlobOptions -> Blob
70+
fromString strs opts = fromStringsImpl [ strs ] (opts <#> toBlobOptionsImpl # toNullable)
71+
72+
-- | Creates a new Blob from one or more strings
73+
fromStrings :: NonEmptyArray String -> Maybe BlobOptions -> Blob
74+
fromStrings strs opts = fromStringsImpl (NonEmptyArray.toArray strs) (opts <#> toBlobOptionsImpl # toNullable)
75+
76+
foreign import typeImpl :: Blob -> String
77+
78+
-- | `MediaType` of the data contained in the `Blob`.
79+
-- | Returns `Nothing` if the `MediaType` is unknown.
80+
type_ :: Blob -> Maybe MediaType
81+
type_ blob =
82+
let
83+
blobType = typeImpl blob
84+
in
85+
if blobType == "" then Nothing
86+
else Just (MediaType blobType)
87+
88+
-- | The size (in bytes) of the data contained in the `Blob`.
89+
foreign import size :: Blob -> Int
90+
91+
-- | An index into the Blob indicating the first byte to include in the new Blob.
92+
-- | If you specify a negative value, it's treated as an offset from the end of the
93+
-- | string toward the beginning. For example, -10 would be the 10th from last byte
94+
-- | in the Blob. If you specify a value for start that is larger than the size
95+
-- | of the source Blob, the returned Blob has size 0 and contains no data.
96+
newtype StartByte = StartByte ByteIdx
97+
98+
-- | An index into the Blob indicating the first byte that will *not* be included
99+
-- | in the new Blob (i.e. the byte exactly at this index is not included).
100+
-- | If you specify a negative value, it's treated as an offset from the end of
101+
-- | the string toward the beginning. For example, -10 would be the 10th from
102+
-- | last byte in the Blob. The default value is size.
103+
newtype EndByte = EndByte ByteIdx
104+
105+
foreign import data ByteIdx :: Type
106+
107+
-- | Creates `ByteIdx` from `Int` value
108+
idxFromInt :: Int -> ByteIdx
109+
idxFromInt = toNumber >>> unsafeCoerce
110+
111+
-- | Creates `ByteIdx` from `Number` value using `Math.round`.
112+
idxFromNumber :: Number -> ByteIdx
113+
idxFromNumber = round >>> unsafeCoerce
114+
115+
-- | Creates a new `Blob` object (with specified `MediaType`), containing the
116+
-- | data in the specified range of bytes of the source Blob, by setting .
117+
foreign import sliceImpl Nullable MediaType -> StartByte -> EndByte -> Blob -> Blob
118+
119+
-- | Creates a new `Blob` object containing the data in the specified range
120+
-- | of bytes of the source Blob.
121+
slice MediaType -> StartByte -> EndByte -> Blob -> Blob
122+
slice mt = sliceImpl (Nullable.notNull mt)
123+
124+
-- | Creates a new `Blob` object containing the data in the specified range
125+
-- | of bytes of the source Blob.
126+
slice' StartByte -> EndByte -> Blob -> Blob
127+
slice' = sliceImpl (Nullable.null)
128+
129+
-- | Returns a promise that fulfills with the contents of the Blob decoded as a UTF-8 string.
130+
foreign import text :: Blob -> Effect (Promise String)
131+
132+
-- | Copies the data in the Blob to a new JS ArrayBuffer
133+
foreign import toArrayBuffer :: Blob -> Effect (Promise ArrayBuffer)
134+
135+
foreign import fromArrayBuffersImpl :: NonEmptyArray ArrayBuffer -> Nullable BlobOptionsImpl -> Blob
136+
137+
-- | Creates a new Blob from one ore more `ArrayBuffer`s
138+
fromArrayBuffers :: NonEmptyArray ArrayBuffer -> Maybe BlobOptions -> Blob
139+
fromArrayBuffers strs opts = fromArrayBuffersImpl strs (opts <#> toBlobOptionsImpl # toNullable)
140+
141+
foreign import fromBlobsImpl :: NonEmptyArray Blob -> Nullable BlobOptionsImpl -> Blob
142+
143+
-- | Creates a new Blob from one ore more `Blob`s
144+
fromBlobs :: NonEmptyArray Blob -> Maybe BlobOptions -> Blob
145+
fromBlobs strs opts = fromBlobsImpl strs (opts <#> toBlobOptionsImpl # toNullable)
146+
147+
foreign import fromDataViewImpl :: NonEmptyArray DataView -> Nullable BlobOptionsImpl -> Blob
148+
149+
-- | Creates a new Blob from one ore more `DataView`s
150+
fromDataView :: NonEmptyArray DataView -> Maybe BlobOptions -> Blob
151+
fromDataView strs opts = fromDataViewImpl strs (opts <#> toBlobOptionsImpl # toNullable)

0 commit comments

Comments
 (0)