git.iko.soy/purescript-indexed-DB
on master help sign in
.gitignore+2
since splitsnapshots
unifiedsplit
@@ -77,3 +77,5 @@ releases
77.purs*
77.purs*
78.psa*
78.psa*
79dist
79dist
80+.spago
81+test.js
README.md+41−9
@@ -14,8 +14,27 @@ menaingful namespace (e.g `IDBIndex.get`, `IDBObjectStore.openCursor` ...)
14
14
15Here's a quick example of what it look likes.
15Here's a quick example of what it look likes.
16```purescript
16```purescript
17+module Main where
18+
19+import Prelude
20+
21+import Control.Monad.Aff (Aff, launchAff_)
22+import Control.Monad.Aff.Console (CONSOLE, log)
23+import Control.Monad.Eff.Exception (EXCEPTION)
24+import Control.Monad.Eff (Eff)
25+import Data.Maybe (Maybe(..), maybe)
26+
27+import Database.IndexedDB.Core
28+import Database.IndexedDB.IDBFactory as IDBFactory
29+import Database.IndexedDB.IDBDatabase as IDBDatabase
30+import Database.IndexedDB.IDBObjectStore as IDBObjectStore
31+import Database.IndexedDB.IDBIndex as IDBIndex
32+import Database.IndexedDB.IDBTransaction as IDBTransaction
33+import Database.IndexedDB.IDBKeyRange as IDBKeyRange
34+
35+
17main :: Eff (idb :: IDB, exception :: EXCEPTION, console :: CONSOLE) Unit
36main :: Eff (idb :: IDB, exception :: EXCEPTION, console :: CONSOLE) Unit
18−main = launchAff' do
37+main = launchAff_ do
19 db <- IDBFactory.open "db" Nothing { onBlocked : Nothing
38 db <- IDBFactory.open "db" Nothing { onBlocked : Nothing
20 , onUpgradeNeeded : Just onUpgradeNeeded
39 , onUpgradeNeeded : Just onUpgradeNeeded
21 }
40 }
@@ -26,22 +45,21 @@ main = launchAff' do
26 log $ maybe "not found" id val
45 log $ maybe "not found" id val
27
46
28
47
29−onUpgradeNeeded :: forall e. Database -> Transaction -> Eff (idb :: IDB, exception :: EXCEPTION | e) Unit
48+onUpgradeNeeded :: forall e. Database -> Transaction -> { oldVersion :: Int } -> Eff (idb :: IDB, exception :: EXCEPTION | e) Unit
30−onUpgradeNeeded db _ = launchAff' do
49+onUpgradeNeeded db _ _ = launchAff_ do
31− store <- IDBDatabase.createObjectStore db "store" IDBObjectStore.defaultParameters
50+ store <- IDBDatabase.createObjectStore db "store" IDBDatabase.defaultParameters
32 _ <- IDBObjectStore.add store "patate" (Just 1)
51 _ <- IDBObjectStore.add store "patate" (Just 1)
33 _ <- IDBObjectStore.add store { property: 42 } (Just 2)
52 _ <- IDBObjectStore.add store { property: 42 } (Just 2)
34− _ <- IDBObjectStore.createIndex store "index" ["property"] IDBIndex.defaultParameters
53+ _ <- IDBObjectStore.createIndex store "index" ["property"] IDBObjectStore.defaultParameters
35 pure unit
54 pure unit
36```
55```
37
56
38## Notes
57## Notes
39
58
40### Errors
59### Errors
41−Errors normally thrown by the IDB\* interfaces are wrapped in the `Aff` Monad as `Error`
60+Errors normally thrown by the IDB\* interfaces are wrapped in the `Aff` Monad as `Error` where
42−where the `message` corresponds to the error's name (e.g. "InvalidStateError").
61+the `name` corresponds to the error's name (e.g. "InvalidStateError"). Pattern matching can
43−Pattern matching can therefore be done on any error message to handle specific errors thrown
62+therefore be done on any error to handle specific errors thrown by the API.
44−by the API.
45
63
46### Examples
64### Examples
47The `test` folder contains a great amount of examples showing practical usage of the IDB\*
65The `test` folder contains a great amount of examples showing practical usage of the IDB\*
@@ -52,6 +70,20 @@ one.
52
70
53## Changelog
71## Changelog
54
72
73+#### v3.0.0
74+
75+- callback to `onUpgradeNeeded` event now provide a record with the database old version.
76+
77+#### v2.0.0
78+
79+- review interface implementation (use of opaque classes to improve readability without compromising
80+ the reusability). The API doesn't really change from a user perspective though.
81+
82+- make the Key more opaque (by having an IDBKey instance for Foreign types)
83+
84+- Upgrade purescript-exceptions to 3.1.0 and leverage the new `name` accessor
85+
86+
55#### v1.0.0
87#### v1.0.0
56
88
57- [Indexed Database API 2.0](https://w3c.github.io/IndexedDB/) totally covered apart from
89- [Indexed Database API 2.0](https://w3c.github.io/IndexedDB/) totally covered apart from
bower.jsondeleted−42
@@ -1,42 +0,0 @@
1−{
2− "name": "purescript-indexeddb",
3− "description": "An API wrapper around IndexedDB",
4− "version": "1.0.2",
5− "authors": [
6− "Matthias Benkort <matthias.benkort@truqu.com>"
7− ],
8− "ignore": [
9− "**/.*",
10− "node_modules",
11− "bower_components",
12− "output",
13− "test",
14− "dist",
15− "releases",
16− "package.json",
17− "karma.conf.js",
18− "karma.browserstack.conf.js",
19− "deploy.sh"
20− ],
21− "license": "MIT",
22− "homepage": "https://github.com/truqu/purescript-indexedDB",
23− "repository": {
24− "type": "git",
25− "url": "git://github.com/truqu/purescript-indexedDB.git"
26− },
27− "dependencies": {
28− "purescript-aff": "^3.1.0",
29− "purescript-datetime": "^3.2.0",
30− "purescript-eff": "^3.1.0",
31− "purescript-exceptions": "https://github.com/truqu/purescript-exceptions.git#3.1.0",
32− "purescript-maybe": "^3.0.0",
33− "purescript-prelude": "^3.1.0",
34− "purescript-read": "^1.0.0"
35− },
36− "devDependencies": {
37− "purescript-spec": "^1.0.0",
38− "purescript-psci-support": "^3.0.0",
39− "purescript-now": "^3.0.0",
40− "purescript-spec-mocha": "https://github.com/truqu/purescript-spec-mocha.git#0.5.0"
41− }
42−}
deploy.shdeleted−6
@@ -1,6 +0,0 @@
1−#!/bin/sh
2−
3−git stash save
4−git clean -df
5−yes | pulp publish --no-push
6−git stash pop
index.jsnew file+4
@@ -0,0 +1,4 @@
1+import "fake-indexeddb/auto";
2+import * as Main from './output/Test.Main/index.js';
3+
4+Main.main();
karma.browserstack.conf.jsdeleted−91
@@ -1,91 +0,0 @@
1−module.exports = (config) => {
2− config.set({
3− browsers: [
4− 'FirefoxMAC',
5− 'ChromeMAC',
6− // 'SafariMAC',
7− 'OperaMAC',
8−
9− 'FirefoxWIN',
10− 'ChromeWIN',
11− 'OperaWIN',
12− ],
13− files: [
14− 'dist/karma/index.js',
15− ],
16− frameworks: [
17− 'mocha',
18− ],
19− plugins: [
20− 'karma-browserstack-launcher',
21− 'karma-mocha',
22− ],
23− reporters: [
24− 'dots',
25− 'BrowserStack',
26− ],
27− singleRun: true,
28− client: {
29− mocha: {
30− timeout: 10000,
31− },
32− },
33− browserStack: {
34− username: process.env.BROWSERSTACK_USERNAME,
35− accessKey: process.env.BROWSERSTACK_ACCESSKEY,
36− timeout: 1500,
37− captureTimeout: 500,
38− },
39− customLaunchers: {
40− FirefoxMAC: {
41− base: 'BrowserStack',
42− browser: 'Firefox',
43− browser_version: '51',
44− os: 'OS X',
45− os_version: 'Sierra',
46− },
47− ChromeMAC: {
48− base: 'BrowserStack',
49− browser: 'Chrome',
50− browser_version: '58',
51− os: 'OS X',
52− os_version: 'Sierra',
53− },
54− SafariMAC: {
55− base: 'BrowserStack',
56− browser: 'Safari',
57− browser_version: '10.1',
58− os: 'OS X',
59− os_version: 'Sierra',
60− },
61− OperaMAC: {
62− base: 'BrowserStack',
63− browser: 'Opera',
64− browser_version: '46',
65− os: 'OS X',
66− os_version: 'Sierra',
67− },
68− FirefoxWIN: {
69− base: 'BrowserStack',
70− browser: 'Firefox',
71− browser_version: '51',
72− os: 'WINDOWS',
73− os_version: '10',
74− },
75− ChromeWIN: {
76− base: 'BrowserStack',
77− browser: 'Chrome',
78− browser_version: '58',
79− os: 'WINDOWS',
80− os_version: '10',
81− },
82− OperaWIN: {
83− base: 'BrowserStack',
84− browser: 'Opera',
85− browser_version: '46',
86− os: 'WINDOWS',
87− os_version: '10',
88− },
89− },
90− });
91−};
karma.conf.jsdeleted−25
@@ -1,25 +0,0 @@
1−module.exports = config => {
2− config.set({
3− autoWatch: true,
4− singleRun: true,
5− browsers: ["Chrome"],
6− files: [
7− "dist/karma/index.js",
8− ],
9− frameworks: [
10− "mocha",
11− ],
12− plugins: [
13− "karma-chrome-launcher",
14− "karma-firefox-launcher",
15− "karma-spec-reporter",
16− "karma-mocha",
17− ],
18− reporters: ["spec"],
19− client: {
20− mocha: {
21− timeout: 10000
22− }
23− }
24− });
25−};
package.json+9−36
@@ -1,42 +1,15 @@
1{
1{
2− "name": "purescript-indexeddb",
2+ "name": "purescript-indexed-DB",
3 "version": "1.0.0",
3 "version": "1.0.0",
4− "description": "A wrapper around the IndexedDB API",
4+ "main": "index.js",
5+ "repository": "https://github.com/ilyakooo0/purescript-indexed-DB.git",
6+ "author": "iko <mail@iko.soy>",
7+ "license": "MIT",
5 "scripts": {
8 "scripts": {
6− "prepare:release": "mkdir -p releases/github && cp -r README.md LICENSE src bower.json releases/github",
9+ "test": "spago build && node index.js"
7− "test:build": "mkdir -p dist/karma && pulp browserify -j 4 --main \"Test.Main\" -I test --to dist/karma/index.js",
8− "test:run": "karma start karma.conf.js",
9− "test:run:browserstack": "karma start karma.browserstack.conf.js",
10− "test:browserstack": "npm run test:build && npm run test:run:browserstack",
11− "test": "npm run test:build && npm run test:run",
12− "start": "find . -type f -regex '.*\\(src\\|test\\).*' ! -regex '.*bower_components.*\\|.*node_modules.*|.*\\.sw.*' | entr -s 'npm run test -s'"
13− },
14− "dependencies": {},
15− "devDependencies": {
16− "bower": "1.8.0",
17− "eslint": "3.19.0",
18− "eslint-config-airbnb": "15.0.1",
19− "eslint-plugin-import": "2.5.0",
20− "eslint-plugin-jsx-a11y": "5.0.3",
21− "eslint-plugin-react": "7.1.0",
22− "karma": "1.7.0",
23− "karma-browserstack-launcher": "1.3.0",
24− "karma-chrome-launcher": "2.1.1",
25− "karma-firefox-launcher": "1.0.1",
26− "karma-mocha": "1.3.0",
27− "karma-spec-reporter": "0.0.31",
28− "mocha": "3.4.2",
29− "pulp": "11.0.0",
30− "purescript": "0.11.5"
31 },
10 },
32− "repository": {
11+ "dependencies": {
33− "type": "git",
12+ "fake-indexeddb": "^4.0.1"
34− "url": "git+https://github.com/Truqu/purescript-indexeddb.git"
35− },
36− "author": "Matthias Benkort <matthias.benkort@truqu.com>",
37− "license": "MIT",
38− "bugs": {
39− "url": "https://github.com/Truqu/purescript-indexeddb/issues"
40 },
13 },
41− "homepage": "https://github.com/Truqu/purescript-indexeddb#readme"
14+ "type": "module"
42}
15}
packages.dhallnew file+105
@@ -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+
102+let upstream =
103+ https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20221124/packages.dhall
104+ sha256:792255bbd8e2141468d967325f3e78246cb7e500bf3ab6d76d5b22dffbb09d49
105+in upstream
spago.dhallnew file+42
@@ -0,0 +1,42 @@
1+{-
2+Welcome to a Spago project!
3+You can edit this file as you like.
4+
5+Need help? See the following resources:
6+- Spago documentation: https://github.com/purescript/spago
7+- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
8+
9+When creating a new Spago project, you can use
10+`spago init --no-comments` or `spago init -C`
11+to generate this file without the comments in this block.
12+-}
13+{ name = "indexed-db"
14+, dependencies =
15+ [ "aff"
16+ , "arrays"
17+ , "avar"
18+ , "console"
19+ , "control"
20+ , "datetime"
21+ , "effect"
22+ , "either"
23+ , "enums"
24+ , "exceptions"
25+ , "foldable-traversable"
26+ , "foreign"
27+ , "functions"
28+ , "identity"
29+ , "lists"
30+ , "maybe"
31+ , "nonempty"
32+ , "now"
33+ , "nullable"
34+ , "prelude"
35+ , "read"
36+ , "spec"
37+ , "transformers"
38+ , "tuples"
39+ ]
40+, packages = ./packages.dhall
41+, sources = [ "src/**/*.purs", "test/**/*.purs" ]
42+}
src/Database/IndexedDB/Core.js+6−6
@@ -3,7 +3,7 @@ const toArray = function toArray(xs) {
3};
3};
4
4
5
5
6−exports._showCursor = function _showCursor(cursor) {
6+export function _showCursor(cursor) {
7 return '(IDBCursor ' +
7 return '(IDBCursor ' +
8 '{ direction: ' + cursor.direction +
8 '{ direction: ' + cursor.direction +
9 ', key: ' + cursor.key +
9 ', key: ' + cursor.key +
@@ -11,7 +11,7 @@ exports._showCursor = function _showCursor(cursor) {
11 ' })';
11 ' })';
12};
12};
13
13
14−exports._showDatabase = function _showDatabase(db) {
14+export function _showDatabase(db) {
15 return '(IDBDatabase ' +
15 return '(IDBDatabase ' +
16 '{ name: ' + db.name +
16 '{ name: ' + db.name +
17 ', objectStoreNames: [' + toArray(db.objectStoreNames).join(', ') + ']' +
17 ', objectStoreNames: [' + toArray(db.objectStoreNames).join(', ') + ']' +
@@ -19,7 +19,7 @@ exports._showDatabase = function _showDatabase(db) {
19 ' })';
19 ' })';
20};
20};
21
21
22−exports._showIndex = function _showIndex(index) {
22+export function _showIndex(index) {
23 return '(IDBIndex ' +
23 return '(IDBIndex ' +
24 '{ name: ' + index.name +
24 '{ name: ' + index.name +
25 ', keyPath: ' + index.keyPath +
25 ', keyPath: ' + index.keyPath +
@@ -28,7 +28,7 @@ exports._showIndex = function _showIndex(index) {
28 ' })';
28 ' })';
29};
29};
30
30
31−exports._showKeyRange = function _showKeyRange(range) {
31+export function _showKeyRange(range) {
32 return '(IDBKeyRange ' +
32 return '(IDBKeyRange ' +
33 '{ lower: ' + range.lower +
33 '{ lower: ' + range.lower +
34 ', upper: ' + range.upper +
34 ', upper: ' + range.upper +
@@ -37,7 +37,7 @@ exports._showKeyRange = function _showKeyRange(range) {
37 ' })';
37 ' })';
38};
38};
39
39
40−exports._showObjectStore = function _showObjectStore(store) {
40+export function _showObjectStore(store) {
41 return '(IDBObjectStore ' +
41 return '(IDBObjectStore ' +
42 '{ autoIncrement: ' + store.autoIncrement +
42 '{ autoIncrement: ' + store.autoIncrement +
43 ', indexNames: [' + toArray(store.indexNames).join(', ') + ']' +
43 ', indexNames: [' + toArray(store.indexNames).join(', ') + ']' +
@@ -46,7 +46,7 @@ exports._showObjectStore = function _showObjectStore(store) {
46 ' })';
46 ' })';
47};
47};
48
48
49−exports._showTransaction = function _showTransaction(tx) {
49+export function _showTransaction(tx) {
50 return '(IDBTransaction ' +
50 return '(IDBTransaction ' +
51 '{ error: ' + tx.error +
51 '{ error: ' + tx.error +
52 ', mode: ' + tx.mode +
52 ', mode: ' + tx.mode +
src/Database/IndexedDB/Core.purs+21−81
@@ -1,18 +1,12 @@
1-- | The Core module gathers types used across the library and provides basic Show instances for
1-- | The Core module gathers types used across the library and provides basic Show instances for
2-- | those types.
2-- | those types.
3−-- |
4−-- | NOTE:
5−-- | Errors normally thrown by the IDB* interfaces are wrapped in the `Aff` Monad as `Error`
6−-- | where the `message` corresponds to the error's name (e.g. "InvalidStateError").
7−-- | Pattern matching can therefore be done on any error message to handle specific errors thrown
8−-- | by the API.
9−
10module Database.IndexedDB.Core
3module Database.IndexedDB.Core
11 -- * Effects
4 -- * Effects
5+ (
12− ( IDB
6+ -- IDB
13
7
14− -- * Types
8+ -- * Types
15− , Database
9+ Database
16 , Index
10 , Index
17 , KeyCursor
11 , KeyCursor
18 , KeyRange
12 , KeyRange
@@ -37,23 +31,13 @@ module Database.IndexedDB.Core
37 , module Database.IndexedDB.IDBKey
31 , module Database.IndexedDB.IDBKey
38 ) where
32 ) where
39
33
40−import Prelude (class Show)
34+import Prelude (class Show)
41
35
42−import Control.Monad.Eff (kind Effect)
43−import Data.Maybe (Maybe(..))
36+import Data.Maybe (Maybe(..))
44−import Data.String.Read (class Read)
37+import Data.String.Read (class Read)
45
38
46import Database.IndexedDB.IDBKey
39import Database.IndexedDB.IDBKey
47
40
48−
49−--------------------
50−-- Effects
51−--
52−
53−-- | IDB Effects, manifestation that something happened with the IndexedDB
54−foreign import data IDB :: Effect
55−
56−
57--------------------
41--------------------
58-- TYPES
42-- TYPES
59--
43--
@@ -62,35 +46,28 @@ foreign import data IDB :: Effect
62-- | stores which hold the data stored in the database.
46-- | stores which hold the data stored in the database.
63foreign import data Database :: Type
47foreign import data Database :: Type
64
48
65−
66-- | An index allows looking up records in an object store using properties of the values
49-- | An index allows looking up records in an object store using properties of the values
67-- | in the object stores records.
50-- | in the object stores records.
68foreign import data Index :: Type
51foreign import data Index :: Type
69
52
70−
71-- | A key range is a continuous interval over some data type used for keys.
53-- | A key range is a continuous interval over some data type used for keys.
72foreign import data KeyRange :: Type
54foreign import data KeyRange :: Type
73
55
74−
75-- | A cursor is used to iterate over a range of records in an index or an object store
56-- | A cursor is used to iterate over a range of records in an index or an object store
76-- | in a specific direction. A KeyCursor doesn't hold any value.
57-- | in a specific direction. A KeyCursor doesn't hold any value.
77foreign import data KeyCursor :: Type
58foreign import data KeyCursor :: Type
78
59
79−
80-- | A Transaction is used to interact with the data in a database.
60-- | A Transaction is used to interact with the data in a database.
81-- | Whenever data is read or written to the database it is done by using a transaction.
61-- | Whenever data is read or written to the database it is done by using a transaction.
82foreign import data Transaction :: Type
62foreign import data Transaction :: Type
83
63
84−
85-- | An object store is the primary storage mechanism for storing data in a database.
64-- | An object store is the primary storage mechanism for storing data in a database.
86foreign import data ObjectStore :: Type
65foreign import data ObjectStore :: Type
87
66
88−
89-- | A cursor is used to iterate over a range of records in an index or an object store
67-- | A cursor is used to iterate over a range of records in an index or an object store
90-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
68-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
91foreign import data ValueCursor :: Type
69foreign import data ValueCursor :: Type
92
70
93−
94-- | A cursor has a direction that determines whether it moves in monotonically
71-- | A cursor has a direction that determines whether it moves in monotonically
95-- | increasing or decreasing order of the record keys when iterated, and if it
72-- | increasing or decreasing order of the record keys when iterated, and if it
96-- | skips duplicated values when iterating indexes.
73-- | skips duplicated values when iterating indexes.
@@ -102,7 +79,6 @@ data CursorDirection
102 | Prev
79 | Prev
103 | PrevUnique
80 | PrevUnique
104
81
105−
106-- | If the source of a cursor is an object store, the effective object store of
82-- | If the source of a cursor is an object store, the effective object store of
107-- | the cursor is that object store and the effective key of the cursor is the
83-- | the cursor is that object store and the effective key of the cursor is the
108-- | cursor’s position. If the source of a cursor is an index, the effective object
84-- | cursor’s position. If the source of a cursor is an index, the effective object
@@ -112,7 +88,6 @@ data CursorSource
112 = ObjectStore ObjectStore
88 = ObjectStore ObjectStore
113 | Index Index
89 | Index Index
114
90
115−
116-- | A key path is a list of strings that defines how to extract a key from a value.
91-- | A key path is a list of strings that defines how to extract a key from a value.
117-- | A valid key path is one of:
92-- | A valid key path is one of:
118-- |
93-- |
@@ -122,15 +97,13 @@ data CursorSource
122-- | - A non-empty list containing only strings conforming to the above requirements.
97-- | - A non-empty list containing only strings conforming to the above requirements.
123type KeyPath = Array String
98type KeyPath = Array String
124
99
125−
126-- | A transaction has a mode that determines which types of interactions can be performed
100-- | A transaction has a mode that determines which types of interactions can be performed
127-- | upon that transaction. The mode is set when the transaction is created and remains
101-- | upon that transaction. The mode is set when the transaction is created and remains
128-- | fixed for the life of the transaction.
102-- | fixed for the life of the transaction.
129data TransactionMode
103data TransactionMode
130− = ReadOnly -- ^ The transaction is only allowed to read data.
104+ = ReadOnly -- ^ The transaction is only allowed to read data.
131− | ReadWrite -- ^ The transaction is allowed to read, modify and delete data from existing object stores
105+ | ReadWrite -- ^ The transaction is allowed to read, modify and delete data from existing object stores
132− | VersionChange -- ^ The transaction is allowed to read, modify and delete data from existing object stores, and can also create and remove object stores and indexes.
106+ | VersionChange -- ^ The transaction is allowed to read, modify and delete data from existing object stores, and can also create and remove object stores and indexes.
133−
134
107
135--------------------
108--------------------
136-- Classes
109-- Classes
@@ -140,132 +113,104 @@ data TransactionMode
140-- | specific attributes (see KeyCursor or CursorWithValue).
113-- | specific attributes (see KeyCursor or CursorWithValue).
141class (IDBCursor cursor) <= IDBConcreteCursor cursor
114class (IDBCursor cursor) <= IDBConcreteCursor cursor
142
115
143−
144-- | Cursor objects implement the IDBCursor interface.
116-- | Cursor objects implement the IDBCursor interface.
145-- | There is only ever one IDBCursor instance representing a given cursor.
117-- | There is only ever one IDBCursor instance representing a given cursor.
146-- | There is no limit on how many cursors can be used at the same time.
118-- | There is no limit on how many cursors can be used at the same time.
147class IDBCursor cursor
119class IDBCursor cursor
148
120
149−
150-- | The IDBDatabase interface represents a connection to a database.
121-- | The IDBDatabase interface represents a connection to a database.
151class IDBDatabase db
122class IDBDatabase db
152
123
153−
154-- | The IDBIndex interface represents an index handle.
124-- | The IDBIndex interface represents an index handle.
155-- | Any of these methods throw an "TransactionInactiveError" DOMException
125-- | Any of these methods throw an "TransactionInactiveError" DOMException
156-- | if called when the transaction is not active.
126-- | if called when the transaction is not active.
157class IDBIndex index
127class IDBIndex index
158
128
159−
160-- | The IDBKeyRange interface represents a key range.
129-- | The IDBKeyRange interface represents a key range.
161class IDBKeyRange range
130class IDBKeyRange range
162
131
163−
164-- | The IDBtransaction interface.
132-- | The IDBtransaction interface.
165class IDBTransaction tx
133class IDBTransaction tx
166
134
167−
168-- | The IDBObjectStore interface represents an object store handle.
135-- | The IDBObjectStore interface represents an object store handle.
169class IDBObjectStore store
136class IDBObjectStore store
170
137
171−
172--------------------
138--------------------
173-- INSTANCES
139-- INSTANCES
174--
140--
175
141
176instance idbCursorKeyCursor :: IDBCursor KeyCursor
142instance idbCursorKeyCursor :: IDBCursor KeyCursor
177
143
178−
179instance idbCursorValueCursor :: IDBCursor ValueCursor
144instance idbCursorValueCursor :: IDBCursor ValueCursor
180
145
181−
182instance idbConcreteCursorKeyCursor :: IDBConcreteCursor KeyCursor
146instance idbConcreteCursorKeyCursor :: IDBConcreteCursor KeyCursor
183
147
184−
185instance idbConcreteCursorValueCursor :: IDBConcreteCursor ValueCursor
148instance idbConcreteCursorValueCursor :: IDBConcreteCursor ValueCursor
186
149
187−
188instance idbDatabaseDatabase :: IDBDatabase Database
150instance idbDatabaseDatabase :: IDBDatabase Database
189
151
190−
191instance idbIndexIndex :: IDBIndex Index
152instance idbIndexIndex :: IDBIndex Index
192
153
193−
194instance idbIndexObjectStore :: IDBIndex ObjectStore
154instance idbIndexObjectStore :: IDBIndex ObjectStore
195
155
196−
197instance idbKeyRangeKeyRange :: IDBKeyRange KeyRange
156instance idbKeyRangeKeyRange :: IDBKeyRange KeyRange
198
157
199−
200instance idbObjectStoreObjectStore :: IDBObjectStore ObjectStore
158instance idbObjectStoreObjectStore :: IDBObjectStore ObjectStore
201
159
202−
203instance idbTransactionTransaction :: IDBTransaction Transaction
160instance idbTransactionTransaction :: IDBTransaction Transaction
204
161
205−
206instance showKeyCursor :: Show KeyCursor where
162instance showKeyCursor :: Show KeyCursor where
207 show = _showCursor
163 show = _showCursor
208
164
209−
210instance showValueCursor :: Show ValueCursor where
165instance showValueCursor :: Show ValueCursor where
211 show = _showCursor
166 show = _showCursor
212
167
213−
214instance showIndex :: Show Index where
168instance showIndex :: Show Index where
215 show = _showIndex
169 show = _showIndex
216
170
217−
218instance showKeyRange :: Show KeyRange where
171instance showKeyRange :: Show KeyRange where
219 show = _showKeyRange
172 show = _showKeyRange
220
173
221−
222instance showObjectStore :: Show ObjectStore where
174instance showObjectStore :: Show ObjectStore where
223 show = _showObjectStore
175 show = _showObjectStore
224
176
225−
226instance showTransaction :: Show Transaction where
177instance showTransaction :: Show Transaction where
227 show = _showTransaction
178 show = _showTransaction
228
179
229−
230instance showDatabase :: Show Database where
180instance showDatabase :: Show Database where
231 show = _showDatabase
181 show = _showDatabase
232
182
233−
234instance showCursorDirection :: Show CursorDirection where
183instance showCursorDirection :: Show CursorDirection where
235 show x =
184 show x =
236 case x of
185 case x of
237− Next -> "next"
186+ Next -> "next"
238 NextUnique -> "nextunique"
187 NextUnique -> "nextunique"
239− Prev -> "prev"
188+ Prev -> "prev"
240 PrevUnique -> "prevunique"
189 PrevUnique -> "prevunique"
241
190
242−
243instance showTransactionMode :: Show TransactionMode where
191instance showTransactionMode :: Show TransactionMode where
244 show x =
192 show x =
245 case x of
193 case x of
246− ReadOnly -> "readonly"
194+ ReadOnly -> "readonly"
247− ReadWrite -> "readwrite"
195+ ReadWrite -> "readwrite"
248 VersionChange -> "versionchange"
196 VersionChange -> "versionchange"
249
197
250−
251instance readCursorDirection :: Read CursorDirection where
198instance readCursorDirection :: Read CursorDirection where
252 read s =
199 read s =
253 case s of
200 case s of
254− "next" -> Just Next
201+ "next" -> Just Next
255 "nextunique" -> Just NextUnique
202 "nextunique" -> Just NextUnique
256− "prev" -> Just Prev
203+ "prev" -> Just Prev
257 "prevunique" -> Just PrevUnique
204 "prevunique" -> Just PrevUnique
258− _ -> Nothing
205+ _ -> Nothing
259−
260
206
261instance readTransactionMode :: Read TransactionMode where
207instance readTransactionMode :: Read TransactionMode where
262 read s =
208 read s =
263 case s of
209 case s of
264− "readonly" -> Just ReadOnly
210+ "readonly" -> Just ReadOnly
265− "readwrite" -> Just ReadWrite
211+ "readwrite" -> Just ReadWrite
266 "versionchange" -> Just VersionChange
212 "versionchange" -> Just VersionChange
267− _ -> Nothing
213+ _ -> Nothing
268−
269
214
270--------------------
215--------------------
271-- FFI
216-- FFI
@@ -273,30 +218,25 @@ instance readTransactionMode :: Read TransactionMode where
273
218
274foreign import _showCursor
219foreign import _showCursor
275 :: forall cursor
220 :: forall cursor
276− . cursor
221+ . cursor
277 -> String
222 -> String
278
223
279−
280foreign import _showDatabase
224foreign import _showDatabase
281 :: Database
225 :: Database
282 -> String
226 -> String
283
227
284−
285foreign import _showIndex
228foreign import _showIndex
286 :: Index
229 :: Index
287 -> String
230 -> String
288
231
289−
290foreign import _showKeyRange
232foreign import _showKeyRange
291 :: KeyRange
233 :: KeyRange
292 -> String
234 -> String
293
235
294−
295foreign import _showObjectStore
236foreign import _showObjectStore
296 :: ObjectStore
237 :: ObjectStore
297 -> String
238 -> String
298
239
299−
300foreign import _showTransaction
240foreign import _showTransaction
301 :: Transaction
241 :: Transaction
302 -> String
242 -> String
src/Database/IndexedDB/IDBCursor.js+63−26
@@ -1,6 +1,6 @@
1const errorHandler = function errorHandler(cb) {
1const errorHandler = function errorHandler(cb) {
2 return function _handler(e) {
2 return function _handler(e) {
3− cb(new Error(e.target.error.name));
3+ cb(e.target.error);
4 };
4 };
5};
5};
6
6
@@ -10,98 +10,135 @@ const successHandler = function successHandler(cb) {
10 };
10 };
11};
11};
12
12
13−exports._advance = function _advance(cursor, count) {
13+export function _advance(cursor, count) {
14− return function aff(success, error) {
14+ return function aff(error, success) {
15 try {
15 try {
16 cursor.advance(count);
16 cursor.advance(count);
17 success();
17 success();
18 } catch (e) {
18 } catch (e) {
19− error(new Error(e.name));
19+ error(e);
20 }
20 }
21+
22+ return function canceler(_, cancelerError) {
23+ cancelerError(new Error("Can't cancel IDB Effects"));
24+ };
21 };
25 };
22};
26};
23
27
24−exports._continue = function _continue(cursor, key) {
28+export function _continue(cursor, key) {
25− return function aff(success, error) {
29+ return function aff(error, success) {
26 try {
30 try {
27 cursor.continue(key || undefined);
31 cursor.continue(key || undefined);
28 success();
32 success();
29 } catch (e) {
33 } catch (e) {
30− error(new Error(e.name));
34+ error(e);
31 }
35 }
36+
37+ return function canceler(_, cancelerError) {
38+ cancelerError(new Error("Can't cancel IDB Effects"));
39+ };
32 };
40 };
33};
41};
34
42
35−exports._continuePrimaryKey = function _continuePrimaryKey(cursor, key, primaryKey) {
43+export function _continuePrimaryKey(cursor, key, primaryKey) {
36− return function aff(success, error) {
44+ return function aff(error, success) {
37 try {
45 try {
38 cursor.continuePrimaryKey(key, primaryKey);
46 cursor.continuePrimaryKey(key, primaryKey);
39 success();
47 success();
40 } catch (e) {
48 } catch (e) {
41− error(new Error(e.name));
49+ error(e);
42 }
50 }
51+
52+ return function canceler(_, cancelerError) {
53+ cancelerError(new Error("Can't cancel IDB Effects"));
54+ };
43 };
55 };
44};
56};
45
57
46−exports._delete = function _delete(cursor) {
58+export function _delete(cursor) {
47− return function aff(success, error) {
59+ return function aff(error, success) {
48 try {
60 try {
49 const request = cursor.delete();
61 const request = cursor.delete();
50 request.onsuccess = successHandler(success);
62 request.onsuccess = successHandler(success);
51 request.onerror = errorHandler(error);
63 request.onerror = errorHandler(error);
52 } catch (e) {
64 } catch (e) {
53− error(new Error(e.name));
65+ error(e);
54 }
66 }
67+
68+ return function canceler(_, cancelerError) {
69+ cancelerError(new Error("Can't cancel IDB Effects"));
70+ };
55 };
71 };
56};
72};
57
73
58−exports._direction = function _direction(fromString, cursor) {
74+export function _direction(fromString, cursor) {
59 return fromString(cursor.direction);
75 return fromString(cursor.direction);
60};
76};
61
77
62−exports._key = function _key(cursor) {
78+export function _key(cursor) {
63− return function aff(success, error) {
79+ return function aff(error, success) {
64 try {
80 try {
65 success(cursor.key);
81 success(cursor.key);
66 } catch (e) {
82 } catch (e) {
67− error(new Error(e.name));
83+ error(e);
68 }
84 }
85+
86+ return function canceler(_, cancelerError) {
87+ cancelerError(new Error("Can't cancel IDB Effects"));
88+ };
69 };
89 };
70};
90};
71
91
72−exports._primaryKey = function _primaryKey(cursor) {
92+export function _primaryKey(cursor) {
73− return function aff(success, error) {
93+ return function aff(error, success) {
74 try {
94 try {
75 success(cursor.primaryKey);
95 success(cursor.primaryKey);
76 } catch (e) {
96 } catch (e) {
77− error(new Error(e.name));
97+ error(e);
78 }
98 }
99+
100+ return function canceler(_, cancelerError) {
101+ cancelerError(new Error("Can't cancel IDB Effects"));
102+ };
79 };
103 };
80};
104};
81
105
82−exports._source = function _source(IDBObjectStore, IDBIndex, cursor) {
106+export function _source(IDBObjectStore, IDBIndex, cursor) {
83 switch (cursor.source.constructor.name) {
107 switch (cursor.source.constructor.name) {
84 case 'IDBIndex':
108 case 'IDBIndex':
85 return IDBIndex(cursor.source);
109 return IDBIndex(cursor.source);
86 case 'IDBObjectStore':
110 case 'IDBObjectStore':
87 return IDBObjectStore(cursor.source);
111 return IDBObjectStore(cursor.source);
88 default:
112 default:
113+ throw Object.create(Error.prototype, {
114+ message: {
115+ enumerable: true,
116+ value: 'Unable to retrieve the cursor\'s source constructor.',
117+ },
118+ name: {
119+ enumerable: true,
89− throw new Error('UnexpectedCursorSource');
120+ value: 'UnexpectedCursorSource',
121+ },
122+ });
90 }
123 }
91};
124};
92
125
93−exports._update = function _update(cursor, value) {
126+export function _update(cursor, value) {
94− return function aff(success, error) {
127+ return function aff(error, success) {
95 try {
128 try {
96 const request = cursor.update(value);
129 const request = cursor.update(value);
97 request.onsuccess = successHandler(success);
130 request.onsuccess = successHandler(success);
98 request.onerror = errorHandler(error);
131 request.onerror = errorHandler(error);
99 } catch (e) {
132 } catch (e) {
100− error(new Error(e.name));
133+ error(e);
101 }
134 }
135+
136+ return function canceler(_, cancelerError) {
137+ cancelerError(new Error("Can't cancel IDB Effects"));
138+ };
102 };
139 };
103};
140};
104
141
105−exports._value = function _value(cursor) {
142+export function _value(cursor) {
106 return cursor.value;
143 return cursor.value;
107};
144};
src/Database/IndexedDB/IDBCursor.purs+76−86
@@ -16,20 +16,18 @@ module Database.IndexedDB.IDBCursor
16 , value
16 , value
17 ) where
17 ) where
18
18
19−import Prelude (Unit, ($), (>>>), map)
20−
21−import Control.Monad.Aff (Aff)
22−import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
23−import Data.Function.Uncurried as Fn
24−import Data.Function.Uncurried (Fn2, Fn3)
25−import Data.Maybe (Maybe)
26−import Data.Nullable (Nullable, toNullable)
27−import Data.String.Read (read)
28−
29import Database.IndexedDB.Core
19import Database.IndexedDB.Core
30−import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromKey)
31−import Database.IndexedDB.IDBKey.Internal as IDBKey
32
20
21+import Data.Function.Uncurried (Fn2, Fn3)
22+import Data.Function.Uncurried as Fn
23+import Data.Maybe (Maybe)
24+import Data.Nullable (Nullable, toNullable)
25+import Data.String.Read (read)
26+import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromKey)
27+import Effect.Aff (Aff)
28+import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
29+import Foreign (Foreign, unsafeFromForeign, unsafeToForeign)
30+import Prelude (Unit, ($), (>>>), (<<<), map)
33
31
34--------------------
32--------------------
35-- INTERFACES
33-- INTERFACES
@@ -37,56 +35,58 @@ import Database.IndexedDB.IDBKey.Internal as IDBKey
37
35
38-- | Advances the cursor through the next count records in range.
36-- | Advances the cursor through the next count records in range.
39advance
37advance
38+ :: forall cursor
40− :: forall e cursor. (IDBCursor cursor)
39+ . (IDBCursor cursor)
41− => cursor
40+ => cursor
42− -> Int
41+ -> Int
43− -> Aff (idb :: IDB | e) Unit
42+ -> Aff Unit
44−advance =
43+advance c =
45− Fn.runFn2 _advance
44+ fromEffectFnAff <<< Fn.runFn2 _advance c
46−
47
45
48-- | Advances the cursor to the next record in range matching or after key.
46-- | Advances the cursor to the next record in range matching or after key.
49continue
47continue
48+ :: forall k cursor
49+ . (IDBKey k)
50− :: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
50+ => (IDBCursor cursor)
51− => cursor
51+ => cursor
52− -> Maybe k
52+ -> Maybe k
53− -> Aff (idb :: IDB | e) Unit
53+ -> Aff Unit
54continue c mk =
54continue c mk =
55− Fn.runFn2 _continue c (toNullable $ map (toKey >>> unsafeFromKey) mk)
55+ fromEffectFnAff $ Fn.runFn2 _continue c (toNullable $ map (toKey >>> unsafeFromKey) mk)
56−
57
56
58-- | Advances the cursor to the next record in range matching or after key and primaryKey. Throws an "InvalidAccessError" DOMException if the source is not an index.
57-- | Advances the cursor to the next record in range matching or after key and primaryKey. Throws an "InvalidAccessError" DOMException if the source is not an index.
59continuePrimaryKey
58continuePrimaryKey
59+ :: forall k cursor
60+ . (IDBKey k)
60− :: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
61+ => (IDBCursor cursor)
61− => cursor
62+ => cursor
62− -> k
63+ -> k
63− -> k
64+ -> k
64− -> Aff (idb :: IDB | e) Unit
65+ -> Aff Unit
65continuePrimaryKey c k1 k2 =
66continuePrimaryKey c k1 k2 =
66− Fn.runFn3 _continuePrimaryKey c (unsafeFromKey $ toKey k1) (unsafeFromKey $ toKey k2)
67+ fromEffectFnAff $ Fn.runFn3 _continuePrimaryKey c (unsafeFromKey $ toKey k1) (unsafeFromKey $ toKey k2)
67−
68
68
69-- | Delete the record pointed at by the cursor with a new value.
69-- | Delete the record pointed at by the cursor with a new value.
70delete
70delete
71+ :: forall cursor
71− :: forall e cursor. (IDBCursor cursor)
72+ . (IDBCursor cursor)
72− => cursor
73+ => cursor
73− -> Aff (idb :: IDB | e) Unit
74+ -> Aff Unit
74delete =
75delete =
75− _delete
76+ fromEffectFnAff <<< _delete
76−
77
77
78-- | Update the record pointed at by the cursor with a new value.
78-- | Update the record pointed at by the cursor with a new value.
79-- |
79-- |
80-- | Throws a "DataError" DOMException if the effective object store uses
80-- | Throws a "DataError" DOMException if the effective object store uses
81-- | in-line keys and the key would have changed.
81-- | in-line keys and the key would have changed.
82update
82update
83− :: forall val e cursor. (IDBCursor cursor)
83+ :: forall val cursor
84+ . (IDBCursor cursor)
84− => cursor
85+ => cursor
85− -> val
86+ -> val
86− -> Aff (idb :: IDB | e) Key
87+ -> Aff Key
87update c =
88update c =
88− toForeign >>> Fn.runFn2 _update c >>> map toKey
89+ map toKey <<< fromEffectFnAff <<< Fn.runFn2 _update c <<< unsafeToForeign
89−
90
90
91--------------------
91--------------------
92-- ATTRIBUTES
92-- ATTRIBUTES
@@ -94,103 +94,93 @@ update c =
94
94
95-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
95-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
96direction
96direction
97+ :: forall cursor
97− :: forall cursor. (IDBConcreteCursor cursor)
98+ . (IDBConcreteCursor cursor)
98 => cursor
99 => cursor
99 -> CursorDirection
100 -> CursorDirection
100direction =
101direction =
101 Fn.runFn2 _direction (read >>> toNullable)
102 Fn.runFn2 _direction (read >>> toNullable)
102
103
103−
104-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
104-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
105-- | if the cursor is advancing or is finished.
105-- | if the cursor is advancing or is finished.
106key
106key
107+ :: forall cursor
107− :: forall e cursor. (IDBConcreteCursor cursor)
108+ . (IDBConcreteCursor cursor)
108 => cursor
109 => cursor
109− -> Aff (idb :: IDB | e) Key
110+ -> Aff Key
110key =
111key =
111− _key >>> map toKey
112+ map toKey <<< fromEffectFnAff <<< _key
112−
113
113
114-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
114-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
115-- | if the cursor is advancing or is finished.
115-- | if the cursor is advancing or is finished.
116primaryKey
116primaryKey
117+ :: forall cursor
117− :: forall e cursor. (IDBConcreteCursor cursor)
118+ . (IDBConcreteCursor cursor)
118 => cursor
119 => cursor
119− -> Aff (idb :: IDB | e) Key
120+ -> Aff Key
120primaryKey =
121primaryKey =
121− _primaryKey >>> map toKey
122+ map toKey <<< fromEffectFnAff <<< _primaryKey
122−
123
123
124-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
124-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
125source
125source
126+ :: forall cursor
126− :: forall cursor. (IDBConcreteCursor cursor)
127+ . (IDBConcreteCursor cursor)
127 => cursor
128 => cursor
128 -> CursorSource
129 -> CursorSource
129source =
130source =
130 Fn.runFn3 _source ObjectStore Index
131 Fn.runFn3 _source ObjectStore Index
131
132
132−
133value
133value
134 :: forall val
134 :: forall val
135− . ValueCursor
135+ . ValueCursor
136 -> val
136 -> val
137value =
137value =
138 _value >>> unsafeFromForeign
138 _value >>> unsafeFromForeign
139
139
140−
141--------------------
140--------------------
142-- FFI
141-- FFI
143--
142--
144
143
145foreign import _advance
144foreign import _advance
146− :: forall cursor e
145+ :: forall cursor
147− . Fn2 cursor Int (Aff (idb :: IDB | e) Unit)
146+ . Fn2 cursor Int (EffectFnAff Unit)
148−
149
147
150foreign import _continue
148foreign import _continue
151− :: forall cursor e
149+ :: forall cursor
152− . Fn2 cursor (Nullable Foreign) (Aff (idb :: IDB | e) Unit)
150+ . Fn2 cursor (Nullable Foreign) (EffectFnAff Unit)
153−
154
151
155foreign import _continuePrimaryKey
152foreign import _continuePrimaryKey
156− :: forall cursor e
153+ :: forall cursor
157− . Fn3 cursor Foreign Foreign (Aff (idb :: IDB | e) Unit)
154+ . Fn3 cursor Foreign Foreign (EffectFnAff Unit)
158−
159
155
160foreign import _delete
156foreign import _delete
161− :: forall cursor e
157+ :: forall cursor
162− . cursor
158+ . cursor
163− -> (Aff (idb :: IDB | e) Unit)
159+ -> (EffectFnAff Unit)
164−
165
160
166foreign import _direction
161foreign import _direction
167 :: forall cursor
162 :: forall cursor
168− . Fn2 (String -> Nullable CursorDirection) cursor CursorDirection
163+ . Fn2 (String -> Nullable CursorDirection) cursor CursorDirection
169−
170
164
171foreign import _key
165foreign import _key
172− :: forall cursor e
166+ :: forall cursor
173− . cursor
167+ . cursor
174− -> Aff (idb :: IDB | e) Key
168+ -> EffectFnAff Key
175−
176
169
177foreign import _primaryKey
170foreign import _primaryKey
178− :: forall cursor e
171+ :: forall cursor
179− . cursor
172+ . cursor
180− -> Aff (idb :: IDB | e) Key
173+ -> EffectFnAff Key
181−
182
174
183foreign import _source
175foreign import _source
184 :: forall cursor
176 :: forall cursor
185− . Fn3 (ObjectStore -> CursorSource) (Index -> CursorSource) cursor CursorSource
177+ . Fn3 (ObjectStore -> CursorSource) (Index -> CursorSource) cursor CursorSource
186−
187
178
188foreign import _update
179foreign import _update
189− :: forall cursor e
180+ :: forall cursor
190− . Fn2 cursor Foreign (Aff (idb :: IDB | e) Foreign)
181+ . Fn2 cursor Foreign (EffectFnAff Foreign)
191−
192
182
193foreign import _value
183foreign import _value
194 :: forall cursor val
184 :: forall cursor val
195− . cursor
185+ . cursor
196 -> val
186 -> val
src/Database/IndexedDB/IDBDatabase.js+59−33
@@ -3,27 +3,23 @@ const toArray = function toArray(xs) {
3};
3};
4
4
5
5
6−exports._showDatabase = function _showDatabase(db) {
7− return '(IDBDatabase ' +
8− '{ name: ' + db.name +
9− ', objectStoreNames: [' + toArray(db.objectStoreNames).join(', ') + ']' +
10− ', version: ' + db.version +
11− ' })';
12−};
13−
14−exports._close = function _close(db) {
6+export function _close(db) {
15− return function aff(success, error) {
7+ return function aff(error, success) {
16 try {
8 try {
17 db.close();
9 db.close();
18 success();
10 success();
19 } catch (e) {
11 } catch (e) {
20− error(new Error(e.name));
12+ error(e);
21 }
13 }
14+
15+ return function canceler(_, cancelerError) {
16+ cancelerError(new Error("Can't cancel IDB Effects"));
17+ };
22 };
18 };
23};
19};
24
20
25−exports._createObjectStore = function _createObjectStore(db, name, opts) {
21+export function _createObjectStore(db, name, opts) {
26− return function aff(success, error) {
22+ return function aff(error, success) {
27 var keyPath;
23 var keyPath;
28
24
29 try {
25 try {
@@ -47,77 +43,107 @@ exports._createObjectStore = function _createObjectStore(db, name, opts) {
47 });
43 });
48 success(store);
44 success(store);
49 } catch (e) {
45 } catch (e) {
50− error(new Error(e.name));
46+ error(e);
51 }
47 }
48+
49+ return function canceler(_, cancelerError) {
50+ cancelerError(new Error("Can't cancel IDB Effects"));
51+ };
52 };
52 };
53};
53};
54
54
55−exports._deleteObjectStore = function _deleteObjectStore(db, name) {
55+export function _deleteObjectStore(db, name) {
56− return function aff(success, error) {
56+ return function aff(error, success) {
57 try {
57 try {
58 db.deleteObjectStore(name);
58 db.deleteObjectStore(name);
59 success();
59 success();
60 } catch (e) {
60 } catch (e) {
61− error(new Error(e.name));
61+ error(e);
62 }
62 }
63+
64+ return function canceler(_, cancelerError) {
65+ cancelerError(new Error("Can't cancel IDB Effects"));
66+ };
63 };
67 };
64};
68};
65
69
66−exports._name = function _name(db) {
70+export function _name(db) {
67 return db.name;
71 return db.name;
68};
72};
69
73
70−exports._objectStoreNames = function _objectStoreNames(db) {
74+export function _objectStoreNames(db) {
71 return toArray(db.objectStoreNames);
75 return toArray(db.objectStoreNames);
72};
76};
73
77
74−exports._onAbort = function _onAbort(db, f) {
78+export function _onAbort(db, f) {
75− return function aff(success) {
79+ return function aff(error, success) {
76 db.onabort = function onabort() {
80 db.onabort = function onabort() {
77 f();
81 f();
78 };
82 };
79 success();
83 success();
84+
85+ return function canceler(_, cancelerError) {
86+ cancelerError(new Error("Can't cancel IDB Effects"));
87+ };
80 };
88 };
81};
89};
82
90
83−exports._onClose = function _onClose(db, f) {
91+export function _onClose(db, f) {
84− return function aff(success) {
92+ return function aff(error, success) {
85 db.onclose = function onclose() {
93 db.onclose = function onclose() {
86 f();
94 f();
87 };
95 };
88 success();
96 success();
97+
98+ return function canceler(_, cancelerError) {
99+ cancelerError(new Error("Can't cancel IDB Effects"));
100+ };
89 };
101 };
90};
102};
91
103
92−exports._onError = function _onError(db, f) {
104+export function _onError(db, f) {
93− return function aff(success) {
105+ return function aff(error, success) {
94 db.onerror = function onerror(e) {
106 db.onerror = function onerror(e) {
95− f(new Error(e.target.error.name))();
107+ f(e.target.error)();
96 };
108 };
97 success();
109 success();
110+
111+ return function canceler(_, cancelerError) {
112+ cancelerError(new Error("Can't cancel IDB Effects"));
113+ };
98 };
114 };
99};
115};
100
116
101−exports._onVersionChange = function _onVersionChange(db, f) {
117+export function _onVersionChange(db, f) {
102− return function aff(success) {
118+ return function aff(error, success) {
103 db.onversionchange = function onversionchange(e) {
119 db.onversionchange = function onversionchange(e) {
104 f({ oldVersion: e.oldVersion, newVersion: e.newVersion })();
120 f({ oldVersion: e.oldVersion, newVersion: e.newVersion })();
105 };
121 };
106 success();
122 success();
123+
124+ return function canceler(_, cancelerError) {
125+ cancelerError(new Error("Can't cancel IDB Effects"));
126+ };
107 };
127 };
108};
128};
109
129
110−exports._transaction = function _transaction(db, stores, mode) {
130+export function _transaction(db, stores, mode) {
111− return function aff(success, error) {
131+ return function aff(error, success) {
132+ var transaction;
112 try {
133 try {
113− const transaction = db.transaction(stores, mode);
134+ transaction = db.transaction(stores, mode);
114 success(transaction);
135 success(transaction);
115 } catch (e) {
136 } catch (e) {
116− error(new Error(e.name));
137+ error(e);
117 }
138 }
139+
140+ return function canceler(_, cancelerError, cancelerSuccess) {
141+ transaction.abort();
142+ cancelerSuccess();
143+ };
118 };
144 };
119};
145};
120
146
121−exports._version = function _version(db) {
147+export function _version(db) {
122 return db.version;
148 return db.version;
123};
149};
src/Database/IndexedDB/IDBDatabase.purs+73−97
@@ -24,16 +24,15 @@ module Database.IndexedDB.IDBDatabase
24 , onVersionChange
24 , onVersionChange
25 ) where
25 ) where
26
26
27−import Prelude (Unit, show)
28−
29−import Control.Monad.Aff (Aff)
30−import Control.Monad.Eff (Eff)
31−import Control.Monad.Eff.Exception (Error)
32−import Data.Function.Uncurried as Fn
33−import Data.Function.Uncurried (Fn2, Fn3)
34−
35import Database.IndexedDB.Core
27import Database.IndexedDB.Core
36
28
29+import Data.Function.Uncurried (Fn2, Fn3)
30+import Data.Function.Uncurried as Fn
31+import Effect (Effect)
32+import Effect.Aff (Aff)
33+import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
34+import Effect.Exception (Error)
35+import Prelude (Unit, show, (<<<), ($))
37
36
38--------------------
37--------------------
39-- TYPES
38-- TYPES
@@ -42,70 +41,67 @@ import Database.IndexedDB.Core
42-- | Type alias for StoreName
41-- | Type alias for StoreName
43type StoreName = String
42type StoreName = String
44
43
45−
46-- | Options provided when creating an object store.
44-- | Options provided when creating an object store.
47type ObjectStoreParameters =
45type ObjectStoreParameters =
48− { keyPath :: KeyPath
46+ { keyPath :: KeyPath
49 , autoIncrement :: Boolean
47 , autoIncrement :: Boolean
50 }
48 }
51
49
52−
53defaultParameters :: ObjectStoreParameters
50defaultParameters :: ObjectStoreParameters
54defaultParameters =
51defaultParameters =
55− { keyPath : []
52+ { keyPath: []
56− , autoIncrement : false
53+ , autoIncrement: false
57 }
54 }
58
55
59−
60--------------------
56--------------------
61-- INTERFACE
57-- INTERFACE
62--
58--
63
59
64-- | Closes the connection once all running transactions have finished.
60-- | Closes the connection once all running transactions have finished.
65close
61close
62+ :: forall db
66− :: forall e db. (IDBDatabase db)
63+ . (IDBDatabase db)
67 => db
64 => db
68− -> Aff (idb :: IDB | e) Unit
65+ -> Aff Unit
69close =
66close =
70− _close
67+ fromEffectFnAff <<< _close
71−
72
68
73-- | Creates a new object store with the given name and options and returns a new IDBObjectStore.
69-- | Creates a new object store with the given name and options and returns a new IDBObjectStore.
74-- |
70-- |
75-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction
71-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction
76createObjectStore
72createObjectStore
73+ :: forall db
77− :: forall e db. (IDBDatabase db)
74+ . (IDBDatabase db)
78 => db
75 => db
79 -> StoreName
76 -> StoreName
80 -> ObjectStoreParameters
77 -> ObjectStoreParameters
81− -> Aff (idb :: IDB | e) ObjectStore
78+ -> Aff ObjectStore
82createObjectStore db name' opts =
79createObjectStore db name' opts =
83− Fn.runFn3 _createObjectStore db name' opts
80+ fromEffectFnAff $ Fn.runFn3 _createObjectStore db name' opts
84−
85
81
86-- | Deletes the object store with the given name.
82-- | Deletes the object store with the given name.
87-- |
83-- |
88-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
84-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
89deleteObjectStore
85deleteObjectStore
86+ :: forall db
90− :: forall e db. (IDBDatabase db)
87+ . (IDBDatabase db)
91 => db
88 => db
92 -> StoreName
89 -> StoreName
93− -> Aff (idb :: IDB | e) ObjectStore
90+ -> Aff ObjectStore
94deleteObjectStore db name' =
91deleteObjectStore db name' =
95− Fn.runFn2 _deleteObjectStore db name'
92+ fromEffectFnAff $ Fn.runFn2 _deleteObjectStore db name'
96−
97
93
98-- | Returns a new transaction with the given mode (ReadOnly|ReadWrite)
94-- | Returns a new transaction with the given mode (ReadOnly|ReadWrite)
99-- | and scope which in the form of an array of object store names.
95-- | and scope which in the form of an array of object store names.
100transaction
96transaction
97+ :: forall db
101− :: forall e db. (IDBDatabase db)
98+ . (IDBDatabase db)
102 => db
99 => db
103 -> Array StoreName
100 -> Array StoreName
104 -> TransactionMode
101 -> TransactionMode
105− -> Aff (idb :: IDB | e) Transaction
102+ -> Aff Transaction
106transaction db stores mode' =
103transaction db stores mode' =
107− Fn.runFn3 _transaction db stores (show mode')
104+ fromEffectFnAff $ Fn.runFn3 _transaction db stores (show mode')
108−
109
105
110--------------------
106--------------------
111-- ATTRIBUTES
107-- ATTRIBUTES
@@ -113,127 +109,107 @@ transaction db stores mode' =
113
109
114-- | Returns the name of the database.
110-- | Returns the name of the database.
115name
111name
116− :: Database
112+ :: Database
117− -> String
113+ -> String
118name =
114name =
119 _name
115 _name
120
116
121−
122-- | Returns a list of the names of object stores in the database.
117-- | Returns a list of the names of object stores in the database.
123objectStoreNames
118objectStoreNames
124− :: Database
119+ :: Database
125− -> Array String
120+ -> Array String
126objectStoreNames =
121objectStoreNames =
127 _objectStoreNames
122 _objectStoreNames
128
123
129−
130-- | Returns the version of the database.
124-- | Returns the version of the database.
131version
125version
132− :: Database
126+ :: Database
133− -> Int
127+ -> Int
134version =
128version =
135 _version
129 _version
136
130
137−
138--------------------
131--------------------
139-- EVENT HANDLERS
132-- EVENT HANDLERS
140--
133--
141-- | Event handler for the `abort` event.
134-- | Event handler for the `abort` event.
142onAbort
135onAbort
143− :: forall e e'
144− . Database
136+ :: Database
145− -> Eff ( | e') Unit
137+ -> Effect Unit
146− -> Aff (idb :: IDB | e) Unit
138+ -> Aff Unit
147onAbort db f =
139onAbort db f =
148− Fn.runFn2 _onAbort db f
140+ fromEffectFnAff $ Fn.runFn2 _onAbort db f
149−
150
141
151-- | Event handler for the `close` event.
142-- | Event handler for the `close` event.
152onClose
143onClose
153− :: forall e e'
154− . Database
144+ :: Database
155− -> Eff ( | e') Unit
145+ -> Effect Unit
156− -> Aff (idb :: IDB | e) Unit
146+ -> Aff Unit
157onClose db f =
147onClose db f =
158− Fn.runFn2 _onClose db f
148+ fromEffectFnAff $ Fn.runFn2 _onClose db f
159−
160
149
161-- | Event handler for the `error` event.
150-- | Event handler for the `error` event.
162onError
151onError
163− :: forall e e'
164− . Database
152+ :: Database
165− -> (Error -> Eff ( | e') Unit)
153+ -> (Error -> Effect Unit)
166− -> Aff (idb :: IDB | e) Unit
154+ -> Aff Unit
167onError db f =
155onError db f =
168− Fn.runFn2 _onError db f
156+ fromEffectFnAff $ Fn.runFn2 _onError db f
169−
170
157
171-- | Event handler for the `versionchange` event.
158-- | Event handler for the `versionchange` event.
172onVersionChange
159onVersionChange
173− :: forall e e'
174− . Database
160+ :: Database
175− -> ({ oldVersion :: Int, newVersion :: Int }
161+ -> ( { oldVersion :: Int, newVersion :: Int }
176− -> Eff ( | e') Unit)
162+ -> Effect Unit
163+ )
177− -> Aff (idb :: IDB | e) Unit
164+ -> Aff Unit
178onVersionChange db f =
165onVersionChange db f =
179− Fn.runFn2 _onVersionChange db f
166+ fromEffectFnAff $ Fn.runFn2 _onVersionChange db f
180−
181
167
182--------------------
168--------------------
183-- FFI
169-- FFI
184--
170--
185
171
186foreign import _close
172foreign import _close
187− :: forall db e
173+ :: forall db
188− . db
174+ . db
189− -> Aff (idb :: IDB | e) Unit
175+ -> EffectFnAff Unit
190−
191
176
192foreign import _createObjectStore
177foreign import _createObjectStore
193− :: forall db e
178+ :: forall db
194− . Fn3 db String { keyPath :: Array String, autoIncrement :: Boolean } (Aff (idb :: IDB | e) ObjectStore)
179+ . Fn3 db String { keyPath :: Array String, autoIncrement :: Boolean } (EffectFnAff ObjectStore)
195−
196
180
197foreign import _deleteObjectStore
181foreign import _deleteObjectStore
198− :: forall db e
182+ :: forall db
199− . Fn2 db String (Aff (idb :: IDB | e) ObjectStore)
183+ . Fn2 db String (EffectFnAff ObjectStore)
200−
201
184
202foreign import _name
185foreign import _name
203− :: Database
186+ :: Database
204− -> String
187+ -> String
205−
206
188
207foreign import _objectStoreNames
189foreign import _objectStoreNames
208− :: Database
190+ :: Database
209− -> Array String
191+ -> Array String
210−
211
192
212foreign import _onAbort
193foreign import _onAbort
213− :: forall db e e'
194+ :: forall db
214− . Fn2 db (Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
195+ . Fn2 db (Effect Unit) (EffectFnAff Unit)
215−
216
196
217foreign import _onClose
197foreign import _onClose
218− :: forall db e e'
198+ :: forall db
219− . Fn2 db (Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
199+ . Fn2 db (Effect Unit) (EffectFnAff Unit)
220−
221
200
222foreign import _onError
201foreign import _onError
223− :: forall db e e'
202+ :: forall db
224− . Fn2 db (Error -> Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
203+ . Fn2 db (Error -> Effect Unit) (EffectFnAff Unit)
225−
226
204
227foreign import _onVersionChange
205foreign import _onVersionChange
228− :: forall db e e'
206+ :: forall db
229− . Fn2 db ({ oldVersion :: Int, newVersion :: Int } -> Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
207+ . Fn2 db ({ oldVersion :: Int, newVersion :: Int } -> Effect Unit) (EffectFnAff Unit)
230−
231
208
232foreign import _transaction
209foreign import _transaction
233− :: forall db e
210+ :: forall db
234− . Fn3 db (Array String) String (Aff (idb :: IDB | e) Transaction)
211+ . Fn3 db (Array String) String (EffectFnAff Transaction)
235−
236
212
237foreign import _version
213foreign import _version
238− :: Database
214+ :: Database
239− -> Int
215+ -> Int
src/Database/IndexedDB/IDBFactory.js+21−8
@@ -1,6 +1,6 @@
1const errorHandler = function errorHandler(cb) {
1const errorHandler = function errorHandler(cb) {
2 return function _handler(e) {
2 return function _handler(e) {
3− cb(new Error(e.target.error.name));
3+ cb(e.target.error);
4 };
4 };
5};
5};
6
6
@@ -14,9 +14,12 @@ const noOp2 = function noOp2() {
14 return noOp;
14 return noOp;
15};
15};
16
16
17+const noOp3 = function noOp3() {
18+ return noOp2;
19+};
17
20
18−exports._deleteDatabase = function _deleteDatabase(name) {
21+export function _deleteDatabase(name) {
19− return function aff(success, error) {
22+ return function aff(error, success) {
20 try {
23 try {
21 const request = indexedDB.deleteDatabase(name);
24 const request = indexedDB.deleteDatabase(name);
22
25
@@ -26,15 +29,19 @@ exports._deleteDatabase = function _deleteDatabase(name) {
26
29
27 request.onerror = errorHandler(error);
30 request.onerror = errorHandler(error);
28 } catch (e) {
31 } catch (e) {
29− error(new Error(e.name));
32+ error(e);
30 }
33 }
34+
35+ return function canceler(_, cancelerError) {
36+ cancelerError(new Error("Can't cancel IDB Effects"));
37+ };
31 };
38 };
32};
39};
33
40
34−exports._open = function _open(fromMaybe, name, mver, req) {
41+export function _open(fromMaybe, name, mver, req) {
35 const ver = fromMaybe(undefined)(mver);
42 const ver = fromMaybe(undefined)(mver);
36
43
37− return function aff(success, error) {
44+ return function aff(error, success) {
38 try {
45 try {
39 const request = indexedDB.open(name, ver);
46 const request = indexedDB.open(name, ver);
40 request.onsuccess = function onSuccess(e) {
47 request.onsuccess = function onSuccess(e) {
@@ -46,12 +53,18 @@ exports._open = function _open(fromMaybe, name, mver, req) {
46 };
53 };
47
54
48 request.onupgradeneeded = function onUpgradeNeeded(e) {
55 request.onupgradeneeded = function onUpgradeNeeded(e) {
56+ const meta = { oldVersion: e.oldVersion };
57+ // eslint-disable-next-line max-len
49− fromMaybe(noOp2)(req.onUpgradeNeeded)(e.target.result)(e.target.transaction)();
58+ fromMaybe(noOp3)(req.onUpgradeNeeded)(e.target.result)(e.target.transaction)(meta)();
50 };
59 };
51
60
52 request.onerror = errorHandler(error);
61 request.onerror = errorHandler(error);
53 } catch (e) {
62 } catch (e) {
54− error(new Error(e.name));
63+ error(e);
55 }
64 }
65+
66+ return function canceler(_, cancelerError) {
67+ cancelerError(new Error("Can't cancel IDB Effects"));
68+ };
56 };
69 };
57};
70};
src/Database/IndexedDB/IDBFactory.purs+22−32
@@ -12,36 +12,32 @@ module Database.IndexedDB.IDBFactory
12 , open
12 , open
13 ) where
13 ) where
14
14
15−import Prelude (Unit)
16−
17−import Control.Monad.Aff (Aff)
18−import Control.Monad.Eff (Eff)
19−import Data.Function.Uncurried as Fn
20−import Data.Function.Uncurried (Fn4)
21−import Data.Maybe (Maybe, fromMaybe)
22−
23import Database.IndexedDB.Core
15import Database.IndexedDB.Core
24
16
17+import Data.Function.Uncurried (Fn4)
18+import Data.Function.Uncurried as Fn
19+import Data.Maybe (Maybe, fromMaybe)
20+import Effect (Effect)
21+import Effect.Aff (Aff)
22+import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
23+import Prelude (Unit, ($), (<<<))
25
24
26--------------------
25--------------------
27-- TYPES
26-- TYPES
28--
27--
29
28
30-- Type alias for binding listeners to an initial open action.
29-- Type alias for binding listeners to an initial open action.
31−type Callbacks e =
30+type Callbacks =
32− { onBlocked :: Maybe (Eff (| e) Unit)
31+ { onBlocked :: Maybe (Effect Unit)
33− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Eff (| e) Unit)
32+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> { oldVersion :: Int } -> Effect Unit)
34 }
33 }
35
34
36−
37-- | Type alias for DatabaseName.
35-- | Type alias for DatabaseName.
38type DatabaseName = String
36type DatabaseName = String
39
37
40−
41-- | Type alias for Version.
38-- | Type alias for Version.
42type Version = Int
39type Version = Int
43
40
44−
45--------------------
41--------------------
46-- INTERFACE
42-- INTERFACE
47--
43--
@@ -50,12 +46,10 @@ type Version = Int
50-- | and there are open connections that don’t close in response to a
46-- | and there are open connections that don’t close in response to a
51-- | `versionchange` event, the request will be blocked until all they close.
47-- | `versionchange` event, the request will be blocked until all they close.
52deleteDatabase
48deleteDatabase
53− :: forall e
54− . DatabaseName
49+ :: DatabaseName
55− -> Aff (idb :: IDB | e) Int
50+ -> Aff Int
56deleteDatabase =
51deleteDatabase =
57− _deleteDatabase
52+ fromEffectFnAff <<< _deleteDatabase
58−
59
53
60-- | Attempts to open a connection to the named database with the specified version.
54-- | Attempts to open a connection to the named database with the specified version.
61-- | If the database already exists with a lower version and there are open connections
55-- | If the database already exists with a lower version and there are open connections
@@ -66,24 +60,20 @@ deleteDatabase =
66-- | When the version isn't provided (`Nothing`), attempts to open a connection to the
60-- | When the version isn't provided (`Nothing`), attempts to open a connection to the
67-- | named database with the current version, or 1 if it does not already exist.
61-- | named database with the current version, or 1 if it does not already exist.
68open
62open
69− :: forall e e'
70− . DatabaseName
63+ :: DatabaseName
71− -> Maybe Version
64+ -> Maybe Version
72− -> Callbacks e'
65+ -> Callbacks
73− -> Aff (idb :: IDB | e) Database
66+ -> Aff Database
74open name mver req =
67open name mver req =
75− Fn.runFn4 _open fromMaybe name mver req
68+ fromEffectFnAff $ Fn.runFn4 _open fromMaybe name mver req
76−
77
69
78--------------------
70--------------------
79-- FFI
71-- FFI
80--
72--
81foreign import _deleteDatabase
73foreign import _deleteDatabase
82− :: forall e
83− . String
74+ :: String
84− -> Aff (idb :: IDB | e) Int
75+ -> EffectFnAff Int
85−
86
76
87foreign import _open
77foreign import _open
88− :: forall a e e'
78+ :: forall a
89− . Fn4 (a -> Maybe a -> a) String (Maybe Int) (Callbacks e') (Aff (idb :: IDB | e) Database)
79+ . Fn4 (a -> Maybe a -> a) String (Maybe Int) (Callbacks) (EffectFnAff Database)
src/Database/IndexedDB/IDBIndex.js+52−28
@@ -1,6 +1,6 @@
1const errorHandler = function errorHandler(cb) {
1const errorHandler = function errorHandler(cb) {
2 return function _handler(e) {
2 return function _handler(e) {
3− cb(new Error(e.target.error.name));
3+ cb(e.target.error);
4 };
4 };
5};
5};
6
6
@@ -11,7 +11,7 @@ const successHandler = function successHandler(cb) {
11};
11};
12
12
13
13
14−exports._keyPath = function _keyPath(index) {
14+export function _keyPath(index) {
15 const path = index.keyPath;
15 const path = index.keyPath;
16
16
17 if (Array.isArray(path)) {
17 if (Array.isArray(path)) {
@@ -25,43 +25,51 @@ exports._keyPath = function _keyPath(index) {
25 return [];
25 return [];
26};
26};
27
27
28−exports._multiEntry = function _multiEntry(index) {
28+export function _multiEntry(index) {
29 return index.multiEntry;
29 return index.multiEntry;
30};
30};
31
31
32−exports._name = function _name(index) {
32+export function _name(index) {
33 return index.name;
33 return index.name;
34};
34};
35
35
36−exports._objectStore = function _objectStore(index) {
36+export function _objectStore(index) {
37 return index.obectStore;
37 return index.obectStore;
38};
38};
39
39
40−exports._unique = function _unique(index) {
40+export function _unique(index) {
41 return index.unique;
41 return index.unique;
42};
42};
43
43
44−exports._count = function _count(index, query) {
44+export function _count(index, query) {
45− return function aff(success, error) {
45+ return function aff(error, success) {
46 try {
46 try {
47 const request = index.count(query);
47 const request = index.count(query);
48 request.onsuccess = successHandler(success);
48 request.onsuccess = successHandler(success);
49 request.onerror = errorHandler(error);
49 request.onerror = errorHandler(error);
50 } catch (e) {
50 } catch (e) {
51− error(new Error(e.name));
51+ error(e);
52 }
52 }
53+
54+ return function canceler(_, cancelerError) {
55+ cancelerError(new Error("Can't cancel IDB Effects"));
56+ };
53 };
57 };
54};
58};
55
59
56−exports._get = function _get(index, range) {
60+export function _get(index, range) {
57− return function aff(success, error) {
61+ return function aff(error, success) {
58 try {
62 try {
59 const request = index.get(range);
63 const request = index.get(range);
60 request.onsuccess = successHandler(success);
64 request.onsuccess = successHandler(success);
61 request.onerror = errorHandler(error);
65 request.onerror = errorHandler(error);
62 } catch (e) {
66 } catch (e) {
63− error(new Error(e.name));
67+ error(e);
64 }
68 }
69+
70+ return function canceler(_, cancelerError) {
71+ cancelerError(new Error("Can't cancel IDB Effects"));
72+ };
65 };
73 };
66};
74};
67
75
@@ -71,8 +79,8 @@ exports._get = function _get(index, range) {
71 *
79 *
72 * However, it may be doable to convert the result to some key / value structure with values of
80 * However, it may be doable to convert the result to some key / value structure with values of
73 * different types.
81 * different types.
74−exports._getAll = function _getAll(index, query, count) {
82+export function _getAll(index, query, count) {
75− return function aff(success, error) {
83+ return function aff(error, success) {
76 const request = index.getAll(query, count);
84 const request = index.getAll(query, count);
77 request.onsuccess = successHandler(success);
85 request.onsuccess = successHandler(success);
78 request.onerror = errorHandler(error);
86 request.onerror = errorHandler(error);
@@ -80,32 +88,40 @@ exports._getAll = function _getAll(index, query, count) {
80};
88};
81*/
89*/
82
90
83−exports._getAllKeys = function _getAllKeys(index, range, count) {
91+export function _getAllKeys(index, range, count) {
84− return function aff(success, error) {
92+ return function aff(error, success) {
85 try {
93 try {
86 const request = index.getAllKeys(range, count || undefined);
94 const request = index.getAllKeys(range, count || undefined);
87 request.onsuccess = successHandler(success);
95 request.onsuccess = successHandler(success);
88 request.onerror = errorHandler(error);
96 request.onerror = errorHandler(error);
89 } catch (e) {
97 } catch (e) {
90− error(new Error(e.name));
98+ error(e);
91 }
99 }
100+
101+ return function canceler(_, cancelerError) {
102+ cancelerError(new Error("Can't cancel IDB Effects"));
103+ };
92 };
104 };
93};
105};
94
106
95−exports._getKey = function _getKey(index, range) {
107+export function _getKey(index, range) {
96− return function aff(success, error) {
108+ return function aff(error, success) {
97 try {
109 try {
98 const request = index.getKey(range);
110 const request = index.getKey(range);
99 request.onsuccess = successHandler(success);
111 request.onsuccess = successHandler(success);
100 request.onerror = errorHandler(error);
112 request.onerror = errorHandler(error);
101 } catch (e) {
113 } catch (e) {
102− error(new Error(e.name));
114+ error(e);
103 }
115 }
116+
117+ return function canceler(_, cancelerError) {
118+ cancelerError(new Error("Can't cancel IDB Effects"));
119+ };
104 };
120 };
105};
121};
106
122
107−exports._openCursor = function _openCursor(index, query, dir, cb) {
123+export function _openCursor(index, query, dir, cb) {
108− return function aff(success, error) {
124+ return function aff(error, success) {
109 try {
125 try {
110 const request = index.openCursor(query, dir);
126 const request = index.openCursor(query, dir);
111 request.onsuccess = function onSuccess(e) {
127 request.onsuccess = function onSuccess(e) {
@@ -116,17 +132,21 @@ exports._openCursor = function _openCursor(index, query, dir, cb) {
116 }
132 }
117 };
133 };
118 request.onerror = function onError(e) {
134 request.onerror = function onError(e) {
119− cb.onError(new Error(e.target.error.name));
135+ cb.onError(e.target.error);
120 };
136 };
121 success();
137 success();
122 } catch (e) {
138 } catch (e) {
123− error(new Error(e.name));
139+ error(e);
124 }
140 }
141+
142+ return function canceler(_, cancelerError) {
143+ cancelerError(new Error("Can't cancel IDB Effects"));
144+ };
125 };
145 };
126};
146};
127
147
128−exports._openKeyCursor = function _openKeyCursor(index, query, dir, cb) {
148+export function _openKeyCursor(index, query, dir, cb) {
129− return function aff(success, error) {
149+ return function aff(error, success) {
130 try {
150 try {
131 const request = index.openKeyCursor(query, dir);
151 const request = index.openKeyCursor(query, dir);
132 request.onsuccess = function onSuccess(e) {
152 request.onsuccess = function onSuccess(e) {
@@ -137,11 +157,15 @@ exports._openKeyCursor = function _openKeyCursor(index, query, dir, cb) {
137 }
157 }
138 };
158 };
139 request.onerror = function onError(e) {
159 request.onerror = function onError(e) {
140− cb.onError(new Error(e.target.error.name));
160+ cb.onError(e.target.error);
141 };
161 };
142 success();
162 success();
143 } catch (e) {
163 } catch (e) {
144− error(new Error(e.name));
164+ error(e);
145 }
165 }
166+
167+ return function canceler(_, cancelerError) {
168+ cancelerError(new Error("Can't cancel IDB Effects"));
169+ };
146 };
170 };
147};
171};
src/Database/IndexedDB/IDBIndex.purs+78−95
@@ -20,204 +20,187 @@ module Database.IndexedDB.IDBIndex
20 , unique
20 , unique
21 ) where
21 ) where
22
22
23−import Prelude (Unit, map, show, (<$>), (>>>))
24−
25−import Control.Monad.Aff (Aff)
26−import Control.Monad.Eff (Eff)
27−import Control.Monad.Eff.Exception (Error)
28−import Data.Foreign (Foreign, unsafeFromForeign)
29−import Data.Function.Uncurried as Fn
30−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
31−import Data.Maybe (Maybe)
32−import Data.Nullable (Nullable, toMaybe, toNullable)
33−
34import Database.IndexedDB.Core
23import Database.IndexedDB.Core
35−import Database.IndexedDB.IDBKey.Internal (Key, toKey)
36
24
25+import Data.Function.Uncurried (Fn2, Fn3, Fn4)
26+import Data.Function.Uncurried as Fn
27+import Data.Maybe (Maybe)
28+import Data.Nullable (Nullable, toMaybe, toNullable)
29+import Database.IndexedDB.IDBKey.Internal (Key, toKey)
30+import Effect (Effect)
31+import Effect.Aff (Aff)
32+import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
33+import Effect.Exception (Error)
34+import Foreign (Foreign, unsafeFromForeign)
35+import Prelude (Unit, map, show, ($), (>>>))
37
36
38--------------------
37--------------------
39-- TYPES
38-- TYPES
40--
39--
41
40
42-- | Callbacks to manipulate a cursor from an Open*Cursor call
41-- | Callbacks to manipulate a cursor from an Open*Cursor call
43−type Callbacks cursor e =
42+type Callbacks cursor =
44− { onSuccess :: cursor -> Eff ( | e) Unit
43+ { onSuccess :: cursor -> Effect Unit
45− , onError :: Error -> Eff ( | e) Unit
44+ , onError :: Error -> Effect Unit
46− , onComplete :: Eff ( | e) Unit
45+ , onComplete :: Effect Unit
47 }
46 }
48
47
49−
50--------------------
48--------------------
51-- INTERFACES
49-- INTERFACES
52--
50--
53
51
54-- | Retrieves the number of records matching the key range in query.
52-- | Retrieves the number of records matching the key range in query.
55count
53count
54+ :: forall index
56− :: forall e index. (IDBIndex index)
55+ . (IDBIndex index)
57− => index
56+ => index
58 -> Maybe KeyRange
57 -> Maybe KeyRange
59− -> Aff (idb :: IDB | e) Int
58+ -> Aff Int
60count index range =
59count index range =
61− Fn.runFn2 _count index (toNullable range)
60+ fromEffectFnAff $ Fn.runFn2 _count index (toNullable range)
62−
63
61
64-- | Retrieves the value of the first record matching the given key range in query.
62-- | Retrieves the value of the first record matching the given key range in query.
65-- |
63-- |
66-- | NOTE
64-- | NOTE
67-- | The coercion from `a` to any type is unsafe and might throw a runtime error if incorrect.
65-- | The coercion from `a` to any type is unsafe and might throw a runtime error if incorrect.
68get
66get
67+ :: forall a index
69− :: forall a e index. (IDBIndex index)
68+ . (IDBIndex index)
70 => index
69 => index
71 -> KeyRange
70 -> KeyRange
72− -> Aff (idb :: IDB | e) (Maybe a)
71+ -> Aff (Maybe a)
73get index range =
72get index range =
74− (toMaybe >>> map unsafeFromForeign) <$> Fn.runFn2 _get index range
73+ map (toMaybe >>> map unsafeFromForeign) $ fromEffectFnAff $ Fn.runFn2 _get index range
75−
76
74
77-- | Retrieves the keys of records matching the given key range in query
75-- | Retrieves the keys of records matching the given key range in query
78-- | (up to the number given if given).
76-- | (up to the number given if given).
79getAllKeys
77getAllKeys
78+ :: forall index
80− :: forall e index. (IDBIndex index)
79+ . (IDBIndex index)
81 => index
80 => index
82 -> Maybe KeyRange
81 -> Maybe KeyRange
83 -> Maybe Int
82 -> Maybe Int
84− -> Aff (idb :: IDB | e) (Array Key)
83+ -> Aff (Array Key)
85getAllKeys index range n =
84getAllKeys index range n =
86− map toKey <$> Fn.runFn3 _getAllKeys index (toNullable range) (toNullable n)
85+ map (map toKey) $ fromEffectFnAff $ Fn.runFn3 _getAllKeys index (toNullable range) (toNullable n)
87−
88
86
89-- | Retrieves the key of the first record matching the given key or key range in query.
87-- | Retrieves the key of the first record matching the given key or key range in query.
90getKey
88getKey
89+ :: forall index
91− :: forall e index. (IDBIndex index)
90+ . (IDBIndex index)
92 => index
91 => index
93 -> KeyRange
92 -> KeyRange
94− -> Aff (idb :: IDB | e) (Maybe Key)
93+ -> Aff (Maybe Key)
95getKey index range =
94getKey index range =
96− (toMaybe >>> map toKey) <$> Fn.runFn2 _getKey index range
95+ map (toMaybe >>> map toKey) $ fromEffectFnAff $ Fn.runFn2 _getKey index range
97−
98
96
99-- | Opens a ValueCursor over the records matching query, ordered by direction.
97-- | Opens a ValueCursor over the records matching query, ordered by direction.
100-- | If query is `Nothing`, all records in index are matched.
98-- | If query is `Nothing`, all records in index are matched.
101openCursor
99openCursor
100+ :: forall index
102− :: forall e e' index. (IDBIndex index)
101+ . (IDBIndex index)
103− => index
102+ => index
104 -> Maybe KeyRange
103 -> Maybe KeyRange
105 -> CursorDirection
104 -> CursorDirection
106− -> Callbacks ValueCursor e'
105+ -> Callbacks ValueCursor
107− -> Aff (idb :: IDB | e) Unit
106+ -> Aff Unit
108openCursor index range dir cb =
107openCursor index range dir cb =
109− Fn.runFn4 _openCursor index (toNullable range) (show dir) cb
108+ fromEffectFnAff $ Fn.runFn4 _openCursor index (toNullable range) (show dir) cb
110−
111
109
112-- | Opens a KeyCursor over the records matching query, ordered by direction.
110-- | Opens a KeyCursor over the records matching query, ordered by direction.
113-- | If query is `Nothing`, all records in index are matched.
111-- | If query is `Nothing`, all records in index are matched.
114openKeyCursor
112openKeyCursor
113+ :: forall index
115− :: forall e e' index. (IDBIndex index)
114+ . (IDBIndex index)
116− => index
115+ => index
117− -> Maybe KeyRange
116+ -> Maybe KeyRange
118− -> CursorDirection
117+ -> CursorDirection
119− -> Callbacks KeyCursor e'
118+ -> Callbacks KeyCursor
120− -> Aff (idb :: IDB | e) Unit
119+ -> Aff Unit
121openKeyCursor index range dir cb =
120openKeyCursor index range dir cb =
122− Fn.runFn4 _openKeyCursor index (toNullable range) (show dir) cb
121+ fromEffectFnAff $ Fn.runFn4 _openKeyCursor index (toNullable range) (show dir) cb
123−
124
122
125--------------------
123--------------------
126-- ATTRIBUTES
124-- ATTRIBUTES
127--
125--
128-- | Returns the key path of the index.
126-- | Returns the key path of the index.
129keyPath
127keyPath
130− :: Index
128+ :: Index
131− -> KeyPath
129+ -> KeyPath
132keyPath =
130keyPath =
133 _keyPath
131 _keyPath
134
132
135−
136-- | Returns true if the index's multiEntry flag is set.
133-- | Returns true if the index's multiEntry flag is set.
137multiEntry
134multiEntry
138− :: Index
135+ :: Index
139− -> Boolean
136+ -> Boolean
140multiEntry =
137multiEntry =
141 _multiEntry
138 _multiEntry
142
139
143−
144-- | Returns the name of the index.
140-- | Returns the name of the index.
145name
141name
146− :: Index
142+ :: Index
147− -> String
143+ -> String
148name =
144name =
149 _name
145 _name
150
146
151−
152-- | Returns the IDBObjectStore the index belongs to.
147-- | Returns the IDBObjectStore the index belongs to.
153objectStore
148objectStore
154− :: Index
149+ :: Index
155− -> ObjectStore
150+ -> ObjectStore
156objectStore =
151objectStore =
157 _objectStore
152 _objectStore
158
153
159−
160-- | Returns true if the index's unique flag is set.
154-- | Returns true if the index's unique flag is set.
161unique
155unique
162− :: Index
156+ :: Index
163− -> Boolean
157+ -> Boolean
164unique =
158unique =
165 _unique
159 _unique
166
160
167−
168--------------------
161--------------------
169-- FFI
162-- FFI
170--
163--
171foreign import _keyPath
164foreign import _keyPath
172− :: Index
165+ :: Index
173− -> Array String
166+ -> Array String
174−
175
167
176foreign import _multiEntry
168foreign import _multiEntry
177− :: Index
169+ :: Index
178− -> Boolean
170+ -> Boolean
179−
180
171
181foreign import _name
172foreign import _name
182− :: Index
173+ :: Index
183− -> String
174+ -> String
184−
185
175
186foreign import _objectStore
176foreign import _objectStore
187− :: Index
177+ :: Index
188− -> ObjectStore
178+ -> ObjectStore
189−
190
179
191foreign import _unique
180foreign import _unique
192− :: Index
181+ :: Index
193− -> Boolean
182+ -> Boolean
194−
195
183
196foreign import _count
184foreign import _count
197− :: forall index e
185+ :: forall index
198− . Fn2 index (Nullable KeyRange) (Aff (idb :: IDB | e) Int)
186+ . Fn2 index (Nullable KeyRange) (EffectFnAff Int)
199−
200
187
201foreign import _get
188foreign import _get
202− :: forall index e
189+ :: forall index
203− . Fn2 index KeyRange (Aff (idb :: IDB | e) (Nullable Foreign))
190+ . Fn2 index KeyRange (EffectFnAff (Nullable Foreign))
204−
205
191
206foreign import _getAllKeys
192foreign import _getAllKeys
207− :: forall index e
193+ :: forall index
208− . Fn3 index (Nullable KeyRange) (Nullable Int) (Aff (idb :: IDB | e) (Array Foreign))
194+ . Fn3 index (Nullable KeyRange) (Nullable Int) (EffectFnAff (Array Foreign))
209−
210
195
211foreign import _getKey
196foreign import _getKey
212− :: forall index e
197+ :: forall index
213− . Fn2 index KeyRange (Aff (idb :: IDB | e) (Nullable Foreign))
198+ . Fn2 index KeyRange (EffectFnAff (Nullable Foreign))
214−
215
199
216foreign import _openCursor
200foreign import _openCursor
217− :: forall index e e'
201+ :: forall index
218− . Fn4 index (Nullable KeyRange) String (Callbacks ValueCursor e') (Aff (idb :: IDB | e) Unit)
202+ . Fn4 index (Nullable KeyRange) String (Callbacks ValueCursor) (EffectFnAff Unit)
219−
220
203
221foreign import _openKeyCursor
204foreign import _openKeyCursor
222− :: forall index e e'
205+ :: forall index
223− . Fn4 index (Nullable KeyRange) String (Callbacks KeyCursor e') (Aff (idb :: IDB | e) Unit)
206+ . Fn4 index (Nullable KeyRange) String (Callbacks KeyCursor) (EffectFnAff Unit)
src/Database/IndexedDB/IDBKey/Internal.js+3−3
@@ -1,8 +1,8 @@
1−exports._dateTimeToForeign = function _dateTimeToForeign(y, m, d, h, mi, s, ms) {
1+export function _dateTimeToForeign(y, m, d, h, mi, s, ms) {
2 return new Date(y, m, d, h, mi, s, ms);
2 return new Date(y, m, d, h, mi, s, ms);
3};
3};
4
4
5−exports._readDateTime = function _readDateTime(parse, right, left, date) {
5+export function _readDateTime(parse, right, left, date) {
6 if (Object.getPrototypeOf(date) !== Date.prototype) {
6 if (Object.getPrototypeOf(date) !== Date.prototype) {
7 return left(typeof date);
7 return left(typeof date);
8 }
8 }
@@ -24,7 +24,7 @@ exports._readDateTime = function _readDateTime(parse, right, left, date) {
24 return right(mdate);
24 return right(mdate);
25};
25};
26
26
27−exports._unsafeReadDateTime = function _unsafeReadDateTime(parse, date) {
27+export function _unsafeReadDateTime(parse, date) {
28 const y = date.getFullYear();
28 const y = date.getFullYear();
29 const m = date.getMonth() + 1;
29 const m = date.getMonth() + 1;
30 const d = date.getDate();
30 const d = date.getDate();
src/Database/IndexedDB/IDBKey/Internal.purs+90−106
@@ -3,35 +3,36 @@
3-- | NOTE: Binary keys aren't supported yet.
3-- | NOTE: Binary keys aren't supported yet.
4module Database.IndexedDB.IDBKey.Internal
4module Database.IndexedDB.IDBKey.Internal
5 ( Key
5 ( Key
6+ , class IDBKey
7+ , toKey
8+ , fromKey
6− , class IDBKey, toKey , fromKey , unsafeFromKey
9+ , unsafeFromKey
7 , none
10 , none
8 ) where
11 ) where
9
12
10import Prelude
13import Prelude
11
14
12−import Control.Alt ((<|>))
15+import Control.Alt ((<|>))
13−import Control.Monad.Except (ExceptT(..), runExceptT)
16+import Control.Monad.Except (ExceptT(..), runExceptT)
14−import Data.Date as Date
17+import Data.Date as Date
15−import Data.DateTime (DateTime(..), Time(..))
18+import Data.DateTime (DateTime(..), Time(..))
16−import Data.Either (Either(..), either, isRight)
19+import Data.Either (Either(..), either, isRight)
17−import Data.Enum (fromEnum, toEnum)
20+import Data.Enum (fromEnum, toEnum)
18−import Data.Foreign as Foreign
21+import Foreign as Foreign
19−import Data.Foreign (Foreign, F)
22+import Foreign (Foreign, F)
20−import Data.Function.Uncurried as Fn
23+import Data.Function.Uncurried as Fn
21import Data.Function.Uncurried (Fn2, Fn4, Fn7)
24import Data.Function.Uncurried (Fn2, Fn4, Fn7)
22−import Data.Identity (Identity(..))
25+import Data.Identity (Identity(..))
23−import Data.List.NonEmpty (NonEmptyList(..))
26+import Data.List.NonEmpty (NonEmptyList(..))
24−import Data.List.Types (List(..))
27+import Data.List.Types (List(..))
25−import Data.Maybe (Maybe(..))
28+import Data.Maybe (Maybe(..))
26−import Data.NonEmpty (NonEmpty(..))
29+import Data.NonEmpty (NonEmpty(..))
27−import Data.Nullable (Nullable, toNullable)
30+import Data.Nullable (Nullable, toNullable)
28−import Data.Time as Time
31+import Data.Time as Time
29−import Data.Traversable (traverse)
32+import Data.Traversable (traverse)
30−
31
33
32newtype Key = Key Foreign
34newtype Key = Key Foreign
33
35
34−
35--------------------
36--------------------
36-- INTERFACES
37-- INTERFACES
37--
38--
@@ -39,100 +40,90 @@ newtype Key = Key Foreign
39-- | to a known type (e.g if you only strings as keys, or perfectly knows the
40-- | to a known type (e.g if you only strings as keys, or perfectly knows the
40-- | type of a given key).
41-- | type of a given key).
41class IDBKey a where
42class IDBKey a where
42− toKey :: a -> Key
43+ toKey :: a -> Key
43− fromKey :: Key -> F a
44+ fromKey :: Key -> F a
44 unsafeFromKey :: Key -> a
45 unsafeFromKey :: Key -> a
45
46
46−
47none :: Maybe Key
47none :: Maybe Key
48none =
48none =
49 Nothing
49 Nothing
50
50
51−
52--------------------
51--------------------
53-- INSTANCES
52-- INSTANCES
54--
53--
55instance eqKey :: Eq Key where
54instance eqKey :: Eq Key where
56 eq a b = (runExceptT >>> runIdentity >>> isRight) $
55 eq a b = (runExceptT >>> runIdentity >>> isRight) $
57− eq <$> ((fromKey a) :: F Int) <*> fromKey b
56+ eq <$> ((fromKey a) :: F Int) <*> fromKey b
58− <|>
57+ <|>
59− eq <$> ((fromKey a) :: F Number) <*> fromKey b
58+ eq <$> ((fromKey a) :: F Number) <*> fromKey b
60− <|>
59+ <|>
61− eq <$> ((fromKey a) :: F String) <*> fromKey b
60+ eq <$> ((fromKey a) :: F String) <*> fromKey b
62− <|>
61+ <|>
63− eq <$> ((fromKey a) :: F DateTime) <*> fromKey b
62+ eq <$> ((fromKey a) :: F DateTime) <*> fromKey b
64− <|>
63+ <|>
65− eq <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
64+ eq <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
66 where
65 where
67− runIdentity :: forall a. Identity a -> a
66+ runIdentity :: forall a. Identity a -> a
68− runIdentity (Identity x) = x
67+ runIdentity (Identity x) = x
69−
70
68
71instance ordKey :: Ord Key where
69instance ordKey :: Ord Key where
72− compare a b = (runExceptT >>> runIdentity >>> either (const LT) id) $
70+ compare a b = (runExceptT >>> runIdentity >>> either (const LT) identity) $
73− compare <$> ((fromKey a) :: F Int) <*> fromKey b
71+ compare <$> ((fromKey a) :: F Int) <*> fromKey b
74− <|>
72+ <|>
75− compare <$> ((fromKey a) :: F Number) <*> fromKey b
73+ compare <$> ((fromKey a) :: F Number) <*> fromKey b
76− <|>
74+ <|>
77− compare <$> ((fromKey a) :: F String) <*> fromKey b
75+ compare <$> ((fromKey a) :: F String) <*> fromKey b
78− <|>
76+ <|>
79− compare <$> ((fromKey a) :: F DateTime) <*> fromKey b
77+ compare <$> ((fromKey a) :: F DateTime) <*> fromKey b
80− <|>
78+ <|>
81− compare <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
79+ compare <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
82 where
80 where
83− runIdentity :: forall a. Identity a -> a
81+ runIdentity :: forall a. Identity a -> a
84− runIdentity (Identity x) = x
82+ runIdentity (Identity x) = x
85−
86
83
87instance showKey :: Show Key where
84instance showKey :: Show Key where
88 show a = (runExceptT >>> format) $
85 show a = (runExceptT >>> format) $
89− (show <$> (fromKey a :: F Int))
86+ (show <$> (fromKey a :: F Int))
90− <|>
87+ <|>
91− (show <$> (fromKey a :: F Number))
88+ (show <$> (fromKey a :: F Number))
92− <|>
89+ <|>
93− (show <$> (fromKey a :: F String))
90+ (show <$> (fromKey a :: F String))
94− <|>
91+ <|>
95− (show <$> (fromKey a :: F DateTime))
92+ (show <$> (fromKey a :: F DateTime))
96− <|>
93+ <|>
97− (show <$> (fromKey a :: F (Array Key)))
94+ (show <$> (fromKey a :: F (Array Key)))
98 where
95 where
99− format :: forall a. Identity (Either a String) -> String
96+ format :: forall a. Identity (Either a String) -> String
100− format (Identity x) =
97+ format (Identity x) =
101− either (const "(Key)") (\s -> "(Key " <> s <> ")") x
98+ either (const "(Key)") (\s -> "(Key " <> s <> ")") x
102−
103
99
104instance idbKeyKey :: IDBKey Key where
100instance idbKeyKey :: IDBKey Key where
105− toKey = id
101+ toKey = identity
106− fromKey = pure
102+ fromKey = pure
107− unsafeFromKey = id
103+ unsafeFromKey = identity
108−
109
104
110instance idbKeyForeign :: IDBKey Foreign where
105instance idbKeyForeign :: IDBKey Foreign where
111− toKey = Key
106+ toKey = Key
112− fromKey (Key f) = pure f
107+ fromKey (Key f) = pure f
113 unsafeFromKey (Key f) = f
108 unsafeFromKey (Key f) = f
114
109
115−
116instance idbKeyInt :: IDBKey Int where
110instance idbKeyInt :: IDBKey Int where
117− toKey = Foreign.toForeign >>> Key
111+ toKey = Foreign.unsafeToForeign >>> Key
118− fromKey (Key f) = Foreign.readInt f
112+ fromKey (Key f) = Foreign.readInt f
119 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
113 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
120
114
121−
122instance idbKeyNumber :: IDBKey Number where
115instance idbKeyNumber :: IDBKey Number where
123− toKey = Foreign.toForeign >>> Key
116+ toKey = Foreign.unsafeToForeign >>> Key
124− fromKey (Key f) = Foreign.readNumber f
117+ fromKey (Key f) = Foreign.readNumber f
125 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
118 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
126
119
127−
128instance idbKeyString :: IDBKey String where
120instance idbKeyString :: IDBKey String where
129− toKey = Foreign.toForeign >>> Key
121+ toKey = Foreign.unsafeToForeign >>> Key
130− fromKey (Key f) = Foreign.readString f
122+ fromKey (Key f) = Foreign.readString f
131 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
123 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
132
124
133−
134instance idbKeyDate :: IDBKey DateTime where
125instance idbKeyDate :: IDBKey DateTime where
135− toKey (DateTime d t) = Key $ Fn.runFn7 _dateTimeToForeign
126+ toKey (DateTime d t) = Key $ Fn.runFn7 _dateTimeToForeign
136 (fromEnum $ Date.year d)
127 (fromEnum $ Date.year d)
137 (fromEnum $ Date.month d)
128 (fromEnum $ Date.month d)
138 (fromEnum $ Date.day d)
129 (fromEnum $ Date.day d)
@@ -140,58 +131,51 @@ instance idbKeyDate :: IDBKey DateTime where
140 (fromEnum $ Time.minute t)
131 (fromEnum $ Time.minute t)
141 (fromEnum $ Time.second t)
132 (fromEnum $ Time.second t)
142 (fromEnum $ Time.millisecond t)
133 (fromEnum $ Time.millisecond t)
143− fromKey (Key f) = Fn.runFn4 _readDateTime dateTime dateTimeF dateTimeE f
134+ fromKey (Key f) = Fn.runFn4 _readDateTime dateTime dateTimeF dateTimeE f
144 unsafeFromKey (Key f) = Fn.runFn2 _unsafeReadDateTime dateTime f
135 unsafeFromKey (Key f) = Fn.runFn2 _unsafeReadDateTime dateTime f
145
136
146−
147instance idbKeyArray :: IDBKey a => IDBKey (Array a) where
137instance idbKeyArray :: IDBKey a => IDBKey (Array a) where
148− toKey = Foreign.toForeign >>> Key
138+ toKey = Foreign.unsafeToForeign >>> Key
149− fromKey (Key f) = Foreign.readArray f >>= traverse (Key >>> fromKey)
139+ fromKey (Key f) = Foreign.readArray f >>= traverse (Key >>> fromKey)
150 unsafeFromKey (Key f) = map unsafeFromKey (Foreign.unsafeFromForeign f)
140 unsafeFromKey (Key f) = map unsafeFromKey (Foreign.unsafeFromForeign f)
151
141
152−
153-- FFI constructor to build a DateTime from years, months, days, hours, minutes, seconds and millis
142-- FFI constructor to build a DateTime from years, months, days, hours, minutes, seconds and millis
154dateTime
143dateTime
155− :: Int -- ^ years
144+ :: Int -- ^ years
156− -> Int -- ^ months
145+ -> Int -- ^ months
157− -> Int -- ^ days
146+ -> Int -- ^ days
158− -> Int -- ^ hours
147+ -> Int -- ^ hours
159− -> Int -- ^ minutes
148+ -> Int -- ^ minutes
160− -> Int -- ^ seconds
149+ -> Int -- ^ seconds
161− -> Int -- ^ milliseconds
150+ -> Int -- ^ milliseconds
162− -> Nullable DateTime
151+ -> Nullable DateTime
163dateTime y m d h mi s ms =
152dateTime y m d h mi s ms =
164 toNullable $ DateTime
153 toNullable $ DateTime
165− <$> (Date.canonicalDate <$> toEnum y <*> toEnum m <*> toEnum d)
154+ <$> (Date.canonicalDate <$> toEnum y <*> toEnum m <*> toEnum d)
166− <*> (Time <$> toEnum h <*> toEnum mi <*> toEnum s <*> toEnum ms)
155+ <*> (Time <$> toEnum h <*> toEnum mi <*> toEnum s <*> toEnum ms)
167−
168
156
169-- FFI constructor to convert a JS `Date` into a successful `F DateTime`
157-- FFI constructor to convert a JS `Date` into a successful `F DateTime`
170dateTimeF
158dateTimeF
171− :: DateTime
159+ :: DateTime
172− -> F DateTime
160+ -> F DateTime
173dateTimeF =
161dateTimeF =
174 Right >>> Identity >>> ExceptT
162 Right >>> Identity >>> ExceptT
175
163
176−
177-- FFI constructor to convert a string into an errored `F DateTime`
164-- FFI constructor to convert a string into an errored `F DateTime`
178dateTimeE
165dateTimeE
179− :: String
166+ :: String
180− -> F DateTime
167+ -> F DateTime
181dateTimeE =
168dateTimeE =
182 Foreign.TypeMismatch "Date" >>> flip NonEmpty Nil >>> NonEmptyList >>> Left >>> Identity >>> ExceptT
169 Foreign.TypeMismatch "Date" >>> flip NonEmpty Nil >>> NonEmptyList >>> Left >>> Identity >>> ExceptT
183
170
184−
185--------------------
171--------------------
186-- FFI
172-- FFI
187--
173--
188foreign import _dateTimeToForeign
174foreign import _dateTimeToForeign
189− :: Fn7 Int Int Int Int Int Int Int Foreign
175+ :: Fn7 Int Int Int Int Int Int Int Foreign
190−
191
176
192foreign import _readDateTime
177foreign import _readDateTime
193− :: Fn4 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) (DateTime -> F DateTime) (String -> F DateTime) Foreign (F DateTime)
178+ :: Fn4 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) (DateTime -> F DateTime) (String -> F DateTime) Foreign (F DateTime)
194−
195
179
196foreign import _unsafeReadDateTime
180foreign import _unsafeReadDateTime
197− :: Fn2 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) Foreign DateTime
181+ :: Fn2 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) Foreign DateTime
src/Database/IndexedDB/IDBKeyRange.js+9−9
@@ -1,4 +1,4 @@
1−exports._bound = function _bound(lower, upper, lowerOpen, upperOpen) {
1+export function _bound(lower, upper, lowerOpen, upperOpen) {
2 try {
2 try {
3 return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
3 return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
4 } catch (e) {
4 } catch (e) {
@@ -6,34 +6,34 @@ exports._bound = function _bound(lower, upper, lowerOpen, upperOpen) {
6 }
6 }
7};
7};
8
8
9−exports._includes = function _includes(range, key) {
9+export function _includes(range, key) {
10 return range.includes(key);
10 return range.includes(key);
11};
11};
12
12
13−exports._lower = function _lower(range) {
13+export function _lower(range) {
14 return range.lower;
14 return range.lower;
15};
15};
16
16
17−exports._lowerBound = function _lowerBound(lower, open) {
17+export function _lowerBound(lower, open) {
18 return IDBKeyRange.lowerBound(lower, open);
18 return IDBKeyRange.lowerBound(lower, open);
19};
19};
20
20
21−exports._lowerOpen = function _lowerOpen(range) {
21+export function _lowerOpen(range) {
22 return range.lowerOpen;
22 return range.lowerOpen;
23};
23};
24
24
25−exports._only = function _only(key) {
25+export function _only(key) {
26 return IDBKeyRange.only(key);
26 return IDBKeyRange.only(key);
27};
27};
28
28
29−exports._upper = function _upper(range) {
29+export function _upper(range) {
30 return range.upper;
30 return range.upper;
31};
31};
32
32
33−exports._upperBound = function _upperBound(upper, open) {
33+export function _upperBound(upper, open) {
34 return IDBKeyRange.upperBound(upper, open);
34 return IDBKeyRange.upperBound(upper, open);
35};
35};
36
36
37−exports._upperOpen = function _upperOpen(range) {
37+export function _upperOpen(range) {
38 return range.upperOpen;
38 return range.upperOpen;
39};
39};
src/Database/IndexedDB/IDBKeyRange.purs+30−42
@@ -19,18 +19,17 @@ module Database.IndexedDB.IDBKeyRange
19 , upperOpen
19 , upperOpen
20 ) where
20 ) where
21
21
22−import Prelude (($), (>>>), map)
22+import Prelude (($), (>>>), map)
23
23
24−import Data.Foreign (Foreign)
24+import Foreign (Foreign)
25−import Data.Function.Uncurried as Fn
25+import Data.Function.Uncurried as Fn
26−import Data.Function.Uncurried (Fn2, Fn4)
26+import Data.Function.Uncurried (Fn2, Fn4)
27−import Data.Maybe (Maybe)
27+import Data.Maybe (Maybe)
28−import Data.Nullable (Nullable, toMaybe)
28+import Data.Nullable (Nullable, toMaybe)
29
29
30−import Database.IndexedDB.Core (class IDBKeyRange, KeyRange)
30+import Database.IndexedDB.Core (class IDBKeyRange, KeyRange)
31import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromKey)
31import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromKey)
32
32
33−
34--------------------
33--------------------
35-- TYPES
34-- TYPES
36--
35--
@@ -38,55 +37,54 @@ import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromK
38-- | Type alias for open
37-- | Type alias for open
39type Open = Boolean
38type Open = Boolean
40
39
41−
42--------------------
40--------------------
43-- CONSTRUCTORS
41-- CONSTRUCTORS
44--
42--
45
43
46-- | Returns a new IDBKeyRange spanning only key.
44-- | Returns a new IDBKeyRange spanning only key.
47only
45only
48− :: forall a. (IDBKey a)
46+ :: forall a
47+ . (IDBKey a)
49− => a
48+ => a
50− -> KeyRange
49+ -> KeyRange
51only key =
50only key =
52 _only (unsafeFromKey $ toKey key)
51 _only (unsafeFromKey $ toKey key)
53
52
54−
55-- | Returns a new IDBKeyRange starting at key with no upper bound.
53-- | Returns a new IDBKeyRange starting at key with no upper bound.
56-- | If `Open` is `true`, key is not included in the range.
54-- | If `Open` is `true`, key is not included in the range.
57lowerBound
55lowerBound
58− :: forall a. (IDBKey a)
56+ :: forall a
57+ . (IDBKey a)
59− => a
58+ => a
60− -> Open
59+ -> Open
61− -> KeyRange
60+ -> KeyRange
62lowerBound key open =
61lowerBound key open =
63 Fn.runFn2 _lowerBound (unsafeFromKey $ toKey key) open
62 Fn.runFn2 _lowerBound (unsafeFromKey $ toKey key) open
64
63
65−
66-- | Returns a new IDBKeyRange with no lower bound and ending at key.
64-- | Returns a new IDBKeyRange with no lower bound and ending at key.
67-- | If `Open` is `true`, key is not included in the range.
65-- | If `Open` is `true`, key is not included in the range.
68upperBound
66upperBound
69− :: forall a. (IDBKey a)
67+ :: forall a
68+ . (IDBKey a)
70− => a
69+ => a
71− -> Open
70+ -> Open
72− -> KeyRange
71+ -> KeyRange
73upperBound key open =
72upperBound key open =
74 Fn.runFn2 _upperBound (unsafeFromKey $ toKey key) open
73 Fn.runFn2 _upperBound (unsafeFromKey $ toKey key) open
75
74
76−
77-- | Returns a new IDBKeyRange spanning from `lower` to `upper`.
75-- | Returns a new IDBKeyRange spanning from `lower` to `upper`.
78-- | If `lowerOpen` is `true`, `lower` is not included in the range.
76-- | If `lowerOpen` is `true`, `lower` is not included in the range.
79-- | If `upperOpen` is `true`, `upper` is not included in the range.
77-- | If `upperOpen` is `true`, `upper` is not included in the range.
80-- |
78-- |
81-- | It throws a `DataError` if the bound is invalid.
79-- | It throws a `DataError` if the bound is invalid.
82bound
80bound
83− :: forall key. (IDBKey key)
81+ :: forall key
82+ . (IDBKey key)
84− => { lower :: key, upper :: key, lowerOpen :: Boolean, upperOpen :: Boolean }
83+ => { lower :: key, upper :: key, lowerOpen :: Boolean, upperOpen :: Boolean }
85− -> Maybe KeyRange
84+ -> Maybe KeyRange
86bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
85bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
87 toMaybe
86 toMaybe
88− $ Fn.runFn4 _bound (unsafeFromKey $ toKey key1) (unsafeFromKey $ toKey key2) open1 open2
87+ $ Fn.runFn4 _bound (unsafeFromKey $ toKey key1) (unsafeFromKey $ toKey key2) open1 open2
89−
90
88
91--------------------
89--------------------
92-- INTERFACE
90-- INTERFACE
@@ -94,14 +92,15 @@ bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
94
92
95-- | Returns true if key is included in the range, and false otherwise.
93-- | Returns true if key is included in the range, and false otherwise.
96includes
94includes
95+ :: forall key range
96+ . (IDBKey key)
97− :: forall key range. (IDBKey key) => (IDBKeyRange range)
97+ => (IDBKeyRange range)
98 => range
98 => range
99 -> key
99 -> key
100 -> Boolean
100 -> Boolean
101includes range =
101includes range =
102 toKey >>> unsafeFromKey >>> Fn.runFn2 _includes range
102 toKey >>> unsafeFromKey >>> Fn.runFn2 _includes range
103
103
104−
105--------------------
104--------------------
106-- ATTRIBUTES
105-- ATTRIBUTES
107--
106--
@@ -112,7 +111,6 @@ lower
112lower =
111lower =
113 _lower >>> toMaybe >>> map toKey
112 _lower >>> toMaybe >>> map toKey
114
113
115−
116-- | Returns upper bound if any.
114-- | Returns upper bound if any.
117upper
115upper
118 :: KeyRange
116 :: KeyRange
@@ -120,7 +118,6 @@ upper
120upper =
118upper =
121 _upper >>> toMaybe >>> map toKey
119 _upper >>> toMaybe >>> map toKey
122
120
123−
124-- | Returns true if the lower open flag is set, false otherwise.
121-- | Returns true if the lower open flag is set, false otherwise.
125lowerOpen
122lowerOpen
126 :: KeyRange
123 :: KeyRange
@@ -128,7 +125,6 @@ lowerOpen
128lowerOpen =
125lowerOpen =
129 _lowerOpen
126 _lowerOpen
130
127
131−
132-- | Returns true if the upper open flag is set, false otherwise.
128-- | Returns true if the upper open flag is set, false otherwise.
133upperOpen
129upperOpen
134 :: KeyRange
130 :: KeyRange
@@ -136,7 +132,6 @@ upperOpen
136upperOpen =
132upperOpen =
137 _upperOpen
133 _upperOpen
138
134
139−
140--------------------
135--------------------
141-- FFI
136-- FFI
142--
137--
@@ -148,35 +143,28 @@ foreign import _only
148foreign import _lowerBound
143foreign import _lowerBound
149 :: Fn2 Foreign Boolean KeyRange
144 :: Fn2 Foreign Boolean KeyRange
150
145
151−
152foreign import _upperBound
146foreign import _upperBound
153 :: Fn2 Foreign Boolean KeyRange
147 :: Fn2 Foreign Boolean KeyRange
154
148
155−
156foreign import _bound
149foreign import _bound
157 :: Fn4 Foreign Foreign Boolean Boolean (Nullable KeyRange)
150 :: Fn4 Foreign Foreign Boolean Boolean (Nullable KeyRange)
158
151
159−
160foreign import _includes
152foreign import _includes
161 :: forall range
153 :: forall range
162− . Fn2 range Foreign Boolean
154+ . Fn2 range Foreign Boolean
163−
164
155
165foreign import _lower
156foreign import _lower
166 :: KeyRange
157 :: KeyRange
167 -> Nullable Foreign
158 -> Nullable Foreign
168
159
169−
170foreign import _upper
160foreign import _upper
171 :: KeyRange
161 :: KeyRange
172 -> Nullable Foreign
162 -> Nullable Foreign
173
163
174−
175foreign import _lowerOpen
164foreign import _lowerOpen
176 :: KeyRange
165 :: KeyRange
177 -> Boolean
166 -> Boolean
178
167
179−
180foreign import _upperOpen
168foreign import _upperOpen
181 :: KeyRange
169 :: KeyRange
182 -> Boolean
170 -> Boolean
src/Database/IndexedDB/IDBObjectStore.js+55−27
@@ -1,6 +1,6 @@
1const errorHandler = function errorHandler(cb) {
1const errorHandler = function errorHandler(cb) {
2 return function _handler(e) {
2 return function _handler(e) {
3− cb(new Error(e.target.error.name));
3+ cb(e.target.error);
4 };
4 };
5};
5};
6
6
@@ -15,36 +15,44 @@ const toArray = function toArray(xs) {
15};
15};
16
16
17
17
18−exports._add = function _add(store, value, key) {
18+export function _add(store, value, key) {
19− return function aff(success, error) {
19+ return function aff(error, success) {
20 try {
20 try {
21 const request = store.add(value, key || undefined);
21 const request = store.add(value, key || undefined);
22 request.onsuccess = successHandler(success);
22 request.onsuccess = successHandler(success);
23 request.onerror = errorHandler(error);
23 request.onerror = errorHandler(error);
24 } catch (e) {
24 } catch (e) {
25− error(new Error(e.name));
25+ error(e);
26 }
26 }
27+
28+ return function canceler(_, cancelerError) {
29+ cancelerError(new Error("Can't cancel IDB Effects"));
30+ };
27 };
31 };
28};
32};
29
33
30−exports._autoIncrement = function _autoIncrement(store) {
34+export function _autoIncrement(store) {
31 return store.autoIncrement;
35 return store.autoIncrement;
32};
36};
33
37
34−exports._clear = function _clear(store) {
38+export function _clear(store) {
35− return function aff(success, error) {
39+ return function aff(error, success) {
36 try {
40 try {
37 const request = store.clear();
41 const request = store.clear();
38 request.onsuccess = successHandler(success);
42 request.onsuccess = successHandler(success);
39 request.onerror = errorHandler(error);
43 request.onerror = errorHandler(error);
40 } catch (e) {
44 } catch (e) {
41− error(new Error(e.name));
45+ error(e);
42 }
46 }
47+
48+ return function canceler(_, cancelerError) {
49+ cancelerError(new Error("Can't cancel IDB Effects"));
50+ };
43 };
51 };
44};
52};
45
53
46−exports._createIndex = function _createIndex(store, name, path, params) {
54+export function _createIndex(store, name, path, params) {
47− return function aff(success, error) {
55+ return function aff(error, success) {
48 var keyPath;
56 var keyPath;
49
57
50 try {
58 try {
@@ -64,50 +72,66 @@ exports._createIndex = function _createIndex(store, name, path, params) {
64 const index = store.createIndex(name, keyPath, params);
72 const index = store.createIndex(name, keyPath, params);
65 success(index);
73 success(index);
66 } catch (e) {
74 } catch (e) {
67− error(new Error(e.name));
75+ error(e);
68 }
76 }
77+
78+ return function canceler(_, cancelerError) {
79+ cancelerError(new Error("Can't cancel IDB Effects"));
80+ };
69 };
81 };
70};
82};
71
83
72−exports._deleteIndex = function _deleteIndex(store, name) {
84+export function _deleteIndex(store, name) {
73− return function aff(success, error) {
85+ return function aff(error, success) {
74 try {
86 try {
75 store.deleteIndex(name);
87 store.deleteIndex(name);
76 success();
88 success();
77 } catch (e) {
89 } catch (e) {
78− error(new Error(e.name));
90+ error(e);
79 }
91 }
92+
93+ return function canceler(_, cancelerError) {
94+ cancelerError(new Error("Can't cancel IDB Effects"));
95+ };
80 };
96 };
81};
97};
82
98
83−exports._delete = function _delete(store, query) {
99+export function _delete(store, query) {
84− return function aff(success, error) {
100+ return function aff(error, success) {
85 try {
101 try {
86 const request = store.delete(query);
102 const request = store.delete(query);
87 request.onsuccess = successHandler(success);
103 request.onsuccess = successHandler(success);
88 request.onerror = errorHandler(error);
104 request.onerror = errorHandler(error);
89 } catch (e) {
105 } catch (e) {
90− error(new Error(e.name));
106+ error(e);
91 }
107 }
108+
109+ return function canceler(_, cancelerError) {
110+ cancelerError(new Error("Can't cancel IDB Effects"));
111+ };
92 };
112 };
93};
113};
94
114
95−exports._index = function _index(store, name) {
115+export function _index(store, name) {
96− return function aff(success, error) {
116+ return function aff(error, success) {
97 try {
117 try {
98 const index = store.index(name);
118 const index = store.index(name);
99 success(index);
119 success(index);
100 } catch (e) {
120 } catch (e) {
101− error(new Error(e.name));
121+ error(e);
102 }
122 }
123+
124+ return function canceler(_, cancelerError) {
125+ cancelerError(new Error("Can't cancel IDB Effects"));
126+ };
103 };
127 };
104};
128};
105
129
106−exports._indexNames = function _indexNames(store) {
130+export function _indexNames(store) {
107 return toArray(store.indexNames);
131 return toArray(store.indexNames);
108};
132};
109
133
110−exports._keyPath = function _keyPath(store) {
134+export function _keyPath(store) {
111 const path = store.keyPath;
135 const path = store.keyPath;
112
136
113 if (Array.isArray(path)) {
137 if (Array.isArray(path)) {
@@ -121,22 +145,26 @@ exports._keyPath = function _keyPath(store) {
121 return [];
145 return [];
122};
146};
123
147
124−exports._name = function _name(store) {
148+export function _name(store) {
125 return store.name;
149 return store.name;
126};
150};
127
151
128−exports._put = function _put(store, value, key) {
152+export function _put(store, value, key) {
129− return function aff(success, error) {
153+ return function aff(error, success) {
130 try {
154 try {
131 const request = store.put(value, key || undefined);
155 const request = store.put(value, key || undefined);
132 request.onsuccess = successHandler(success);
156 request.onsuccess = successHandler(success);
133 request.onerror = errorHandler(error);
157 request.onerror = errorHandler(error);
134 } catch (e) {
158 } catch (e) {
135− error(new Error(e.name));
159+ error(e);
136 }
160 }
161+
162+ return function canceler(_, cancelerError) {
163+ cancelerError(new Error("Can't cancel IDB Effects"));
164+ };
137 };
165 };
138};
166};
139
167
140−exports._transaction = function _transaction(store) {
168+export function _transaction(store) {
141 return store.transaction;
169 return store.transaction;
142};
170};
src/Database/IndexedDB/IDBObjectStore.purs+58−75
@@ -25,18 +25,18 @@ module Database.IndexedDB.IDBObjectStore
25 , module Database.IndexedDB.IDBIndex
25 , module Database.IndexedDB.IDBIndex
26 ) where
26 ) where
27
27
28−import Prelude (Unit, ($), (<$>), (>>>))
29−
30−import Control.Monad.Aff (Aff)
31−import Data.Foreign (Foreign)
32−import Data.Function.Uncurried as Fn
33−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
34−import Data.Maybe (Maybe)
35−import Data.Nullable (Nullable, toNullable)
36−
37import Database.IndexedDB.Core
28import Database.IndexedDB.Core
29+
30+import Data.Function.Uncurried (Fn2, Fn3, Fn4)
31+import Data.Function.Uncurried as Fn
32+import Data.Maybe (Maybe)
33+import Data.Nullable (Nullable, toNullable)
38−import Database.IndexedDB.IDBIndex (count, get, getAllKeys, getKey, openCursor, openKeyCursor)
34+import Database.IndexedDB.IDBIndex (count, get, getAllKeys, getKey, openCursor, openKeyCursor)
39import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, unsafeFromKey, toKey)
35import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, unsafeFromKey, toKey)
36+import Effect.Aff (Aff)
37+import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
38+import Foreign (Foreign)
39+import Prelude (Unit, map, ($), (<$>), (>>>), (<<<))
40
40
41--------------------
41--------------------
42-- TYPES
42-- TYPES
@@ -45,7 +45,6 @@ import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, unsafeFromKey, toK
45-- | Type alias for IndexName
45-- | Type alias for IndexName
46type IndexName = String
46type IndexName = String
47
47
48−
49-- | Flags to set on the index.
48-- | Flags to set on the index.
50-- |
49-- |
51-- | An index has a `unique` flag. When this flag is set, the index enforces that no
50-- | An index has a `unique` flag. When this flag is set, the index enforces that no
@@ -60,18 +59,16 @@ type IndexName = String
60-- | If the `multiEntry` flag is true, then the one record is added to the index for each
59-- | If the `multiEntry` flag is true, then the one record is added to the index for each
61-- | of the subkeys.
60-- | of the subkeys.
62type IndexParameters =
61type IndexParameters =
63− { unique :: Boolean
62+ { unique :: Boolean
64 , multiEntry :: Boolean
63 , multiEntry :: Boolean
65 }
64 }
66
65
67−
68defaultParameters :: IndexParameters
66defaultParameters :: IndexParameters
69defaultParameters =
67defaultParameters =
70− { unique : false
68+ { unique: false
71− , multiEntry : false
69+ , multiEntry: false
72 }
70 }
73
71
74−
75--------------------
72--------------------
76-- INTERFACES
73-- INTERFACES
77--
74--
@@ -84,23 +81,24 @@ defaultParameters =
84-- | If add() is used, and if a record with the key already exists the request will fail,
81-- | If add() is used, and if a record with the key already exists the request will fail,
85-- | with a "ConstraintError" DOMException.
82-- | with a "ConstraintError" DOMException.
86add
83add
84+ :: forall key val store
85+ . (IDBKey key)
87− :: forall e key val store. (IDBKey key) => (IDBObjectStore store)
86+ => (IDBObjectStore store)
88 => store
87 => store
89 -> val
88 -> val
90 -> Maybe key
89 -> Maybe key
91− -> Aff (idb :: IDB | e) Key
90+ -> Aff Key
92add store value key =
91add store value key =
93− toKey <$> Fn.runFn3 _add store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
92+ map toKey $ fromEffectFnAff $ Fn.runFn3 _add store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
94−
95
93
96-- | Deletes all records in store.
94-- | Deletes all records in store.
97clear
95clear
96+ :: forall store
98− :: forall e store. (IDBObjectStore store)
97+ . (IDBObjectStore store)
99 => store
98 => store
100− -> Aff (idb :: IDB | e) Unit
99+ -> Aff Unit
101clear =
100clear =
102− _clear
101+ fromEffectFnAff <<< _clear
103−
104
102
105-- | Creates a new index in store with the given name, keyPath and options and
103-- | Creates a new index in store with the given name, keyPath and options and
106-- | returns a new IDBIndex. If the keyPath and options define constraints that
104-- | returns a new IDBIndex. If the keyPath and options define constraints that
@@ -109,47 +107,47 @@ clear =
109-- |
107-- |
110-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
108-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
111createIndex
109createIndex
110+ :: forall store
112− :: forall e store. (IDBObjectStore store)
111+ . (IDBObjectStore store)
113 => store
112 => store
114 -> IndexName
113 -> IndexName
115 -> KeyPath
114 -> KeyPath
116 -> IndexParameters
115 -> IndexParameters
117− -> Aff (idb :: IDB | e) Index
116+ -> Aff Index
118createIndex store name' path params =
117createIndex store name' path params =
119− Fn.runFn4 _createIndex store name' path params
118+ fromEffectFnAff $ Fn.runFn4 _createIndex store name' path params
120−
121
119
122-- | Deletes records in store with the given key or in the given key range in query.
120-- | Deletes records in store with the given key or in the given key range in query.
123delete
121delete
122+ :: forall store
124− :: forall e store. (IDBObjectStore store)
123+ . (IDBObjectStore store)
125 => store
124 => store
126 -> KeyRange
125 -> KeyRange
127− -> Aff (idb :: IDB | e) Unit
126+ -> Aff Unit
128delete store range =
127delete store range =
129− Fn.runFn2 _delete store range
128+ fromEffectFnAff $ Fn.runFn2 _delete store range
130−
131
129
132-- | Deletes the index in store with the given name.
130-- | Deletes the index in store with the given name.
133-- |
131-- |
134-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
132-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
135deleteIndex
133deleteIndex
134+ :: forall store
136− :: forall e store. (IDBObjectStore store)
135+ . (IDBObjectStore store)
137 => store
136 => store
138 -> IndexName
137 -> IndexName
139− -> Aff (idb :: IDB | e) Unit
138+ -> Aff Unit
140deleteIndex store name' =
139deleteIndex store name' =
141− Fn.runFn2 _deleteIndex store name'
140+ fromEffectFnAff $ Fn.runFn2 _deleteIndex store name'
142−
143
141
144-- | Returns an IDBIndex for the index named name in store.
142-- | Returns an IDBIndex for the index named name in store.
145index
143index
144+ :: forall store
146− :: forall e store. (IDBObjectStore store)
145+ . (IDBObjectStore store)
147 => store
146 => store
148 -> IndexName
147 -> IndexName
149− -> Aff (idb :: IDB | e) Index
148+ -> Aff Index
150index store name' =
149index store name' =
151− Fn.runFn2 _index store name'
150+ fromEffectFnAff $ Fn.runFn2 _index store name'
152−
153
151
154-- | Adds or updates a record in store with the given value and key.
152-- | Adds or updates a record in store with the given value and key.
155-- |
153-- |
@@ -158,14 +156,15 @@ index store name' =
158-- |
156-- |
159-- | If put() is used, any existing record with the key will be replaced.
157-- | If put() is used, any existing record with the key will be replaced.
160put
158put
159+ :: forall val key store
160+ . (IDBKey key)
161− :: forall e val key store. (IDBKey key) => (IDBObjectStore store)
161+ => (IDBObjectStore store)
162 => store
162 => store
163 -> val
163 -> val
164 -> Maybe key
164 -> Maybe key
165− -> Aff (idb :: IDB | e) Key
165+ -> Aff Key
166put store value key =
166put store value key =
167− toKey <$> Fn.runFn3 _put store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
167+ map toKey $ fromEffectFnAff $ Fn.runFn3 _put store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
168−
169
168
170--------------------
169--------------------
171-- ATTRIBUTES
170-- ATTRIBUTES
@@ -177,7 +176,6 @@ autoIncrement
177autoIncrement =
176autoIncrement =
178 _autoIncrement
177 _autoIncrement
179
178
180−
181--| Returns a list of the names of indexes in the store.
179--| Returns a list of the names of indexes in the store.
182indexNames
180indexNames
183 :: ObjectStore
181 :: ObjectStore
@@ -185,7 +183,6 @@ indexNames
185indexNames =
183indexNames =
186 _indexNames
184 _indexNames
187
185
188−
189-- | Returns the key path of the store, or empty array if none
186-- | Returns the key path of the store, or empty array if none
190keyPath
187keyPath
191 :: ObjectStore
188 :: ObjectStore
@@ -193,7 +190,6 @@ keyPath
193keyPath =
190keyPath =
194 _keyPath
191 _keyPath
195
192
196−
197-- | Returns the name of the store.
193-- | Returns the name of the store.
198name
194name
199 :: ObjectStore
195 :: ObjectStore
@@ -201,7 +197,6 @@ name
201name =
197name =
202 _name
198 _name
203
199
204−
205-- | Returns the associated transaction.
200-- | Returns the associated transaction.
206transaction
201transaction
207 :: ObjectStore
202 :: ObjectStore
@@ -209,65 +204,53 @@ transaction
209transaction =
204transaction =
210 _transaction
205 _transaction
211
206
212−
213--------------------
207--------------------
214-- FFI
208-- FFI
215--
209--
216foreign import _add
210foreign import _add
217− :: forall e val store
211+ :: forall val store
218− . Fn3 store val (Nullable Foreign) (Aff (idb :: IDB | e) Foreign)
212+ . Fn3 store val (Nullable Foreign) (EffectFnAff Foreign)
219−
220
213
221foreign import _autoIncrement
214foreign import _autoIncrement
222 :: ObjectStore
215 :: ObjectStore
223 -> Boolean
216 -> Boolean
224
217
225−
226foreign import _clear
218foreign import _clear
227− :: forall e store
219+ :: forall store
228− . store
220+ . store
229− -> Aff (idb :: IDB | e) Unit
221+ -> EffectFnAff Unit
230−
231
222
232foreign import _createIndex
223foreign import _createIndex
233− :: forall e store
224+ :: forall store
234− . Fn4 store String (Array String) { unique :: Boolean, multiEntry :: Boolean } (Aff (idb :: IDB | e) Index)
225+ . Fn4 store String (Array String) { unique :: Boolean, multiEntry :: Boolean } (EffectFnAff Index)
235−
236
226
237foreign import _delete
227foreign import _delete
238− :: forall e store
228+ :: forall store
239− . Fn2 store KeyRange (Aff (idb :: IDB | e) Unit)
229+ . Fn2 store KeyRange (EffectFnAff Unit)
240−
241
230
242foreign import _deleteIndex
231foreign import _deleteIndex
243− :: forall e store
232+ :: forall store
244− . Fn2 store String (Aff (idb :: IDB | e) Unit)
233+ . Fn2 store String (EffectFnAff Unit)
245−
246
234
247foreign import _index
235foreign import _index
248− :: forall e store
236+ :: forall store
249− . Fn2 store String (Aff (idb :: IDB | e) Index)
237+ . Fn2 store String (EffectFnAff Index)
250−
251
238
252foreign import _indexNames
239foreign import _indexNames
253 :: ObjectStore
240 :: ObjectStore
254 -> Array String
241 -> Array String
255
242
256−
257foreign import _keyPath
243foreign import _keyPath
258 :: ObjectStore
244 :: ObjectStore
259 -> Array String
245 -> Array String
260
246
261−
262foreign import _name
247foreign import _name
263 :: ObjectStore
248 :: ObjectStore
264 -> String
249 -> String
265
250
266−
267foreign import _put
251foreign import _put
268− :: forall e val store
252+ :: forall val store
269− . Fn3 store val (Nullable Foreign) (Aff (idb :: IDB | e) Foreign)
253+ . Fn3 store val (Nullable Foreign) (EffectFnAff Foreign)
270−
271
254
272foreign import _transaction
255foreign import _transaction
273 :: ObjectStore
256 :: ObjectStore
src/Database/IndexedDB/IDBTransaction.js+38−18
@@ -1,25 +1,29 @@
1−exports._abort = function _abort(tx) {
1+export function _abort(tx) {
2− return function aff(success, error) {
2+ return function aff(error, success) {
3 try {
3 try {
4 tx.abort();
4 tx.abort();
5 success();
5 success();
6 } catch (e) {
6 } catch (e) {
7− error(new Error(e.name));
7+ error(e);
8 }
8 }
9+
10+ return function canceler(_, cancelerError) {
11+ cancelerError(new Error("Can't cancel IDB Effects"));
12+ };
9 };
13 };
10};
14};
11
15
12−exports._db = function _db(tx) {
16+export function _db(tx) {
13 return tx.db;
17 return tx.db;
14};
18};
15
19
16−exports._error = function _error(tx) {
20+export function _error(tx) {
17 return tx.error == null
21 return tx.error == null
18 ? null
22 ? null
19− : new Error(tx.error.name);
23+ : tx.error;
20};
24};
21
25
22−exports._mode = function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
26+export function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
23 if (tx.mode === 'readwrite') {
27 if (tx.mode === 'readwrite') {
24 return ReadWrite;
28 return ReadWrite;
25 } else if (tx.mode === 'versionchange') {
29 } else if (tx.mode === 'versionchange') {
@@ -29,44 +33,60 @@ exports._mode = function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
29 return ReadOnly;
33 return ReadOnly;
30};
34};
31
35
32−exports._objectStore = function _objectStore(tx, name) {
36+export function _objectStore(tx, name) {
33− return function aff(success, error) {
37+ return function aff(error, success) {
34 try {
38 try {
35 const store = tx.objectStore(name);
39 const store = tx.objectStore(name);
36 success(store);
40 success(store);
37 } catch (e) {
41 } catch (e) {
38− error(new Error(e.name));
42+ error(e);
39 }
43 }
44+
45+ return function canceler(_, cancelerError) {
46+ cancelerError(new Error("Can't cancel IDB Effects"));
47+ };
40 };
48 };
41};
49};
42
50
43−exports._objectStoreNames = function _objectStoreNames(tx) {
51+export function _objectStoreNames(tx) {
44 return tx.objectStoreNames;
52 return tx.objectStoreNames;
45};
53};
46
54
47−exports._onAbort = function _onAbort(tx, f) {
55+export function _onAbort(tx, f) {
48− return function aff(success) {
56+ return function aff(error, success) {
49 tx.onabort = function onabort() {
57 tx.onabort = function onabort() {
50 f();
58 f();
51 };
59 };
52 success();
60 success();
61+
62+ return function canceler(_, cancelerError) {
63+ cancelerError(new Error("Can't cancel IDB Effects"));
64+ };
53 };
65 };
54};
66};
55
67
56−exports._onComplete = function _onComplete(tx, f) {
68+export function _onComplete(tx, f) {
57− return function aff(success) {
69+ return function aff(error, success) {
58 tx.oncomplete = function oncomplete() {
70 tx.oncomplete = function oncomplete() {
59 f();
71 f();
60 };
72 };
61 success();
73 success();
74+
75+ return function canceler(_, cancelerError) {
76+ cancelerError(new Error("Can't cancel IDB Effects"));
77+ };
62 };
78 };
63};
79};
64
80
65−exports._onError = function _onError(tx, f) {
81+export function _onError(tx, f) {
66− return function aff(success) {
82+ return function aff(error, success) {
67 tx.onerror = function onerror(e) {
83 tx.onerror = function onerror(e) {
68− f(new Error(e.target.error.name))();
84+ f(e.target.error)();
69 };
85 };
70 success();
86 success();
87+
88+ return function canceler(_, cancelerError) {
89+ cancelerError(new Error("Can't cancel IDB Effects"));
90+ };
71 };
91 };
72};
92};
src/Database/IndexedDB/IDBTransaction.purs+40−59
@@ -14,18 +14,17 @@ module Database.IndexedDB.IDBTransaction
14 , onError
14 , onError
15 ) where
15 ) where
16
16
17−import Prelude (Unit, (>>>))
18−
19−import Control.Monad.Aff (Aff)
20−import Control.Monad.Eff (Eff)
21−import Control.Monad.Eff.Exception (Error)
22−import Data.Function.Uncurried as Fn
23−import Data.Function.Uncurried (Fn2, Fn4)
24−import Data.Maybe (Maybe)
25−import Data.Nullable (Nullable, toMaybe)
26−
27import Database.IndexedDB.Core
17import Database.IndexedDB.Core
28
18
19+import Data.Function.Uncurried (Fn2, Fn4)
20+import Data.Function.Uncurried as Fn
21+import Data.Maybe (Maybe)
22+import Data.Nullable (Nullable, toMaybe)
23+import Effect (Effect)
24+import Effect.Aff (Aff)
25+import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
26+import Effect.Exception (Error)
27+import Prelude (Unit, ($), (<<<), (>>>))
29
28
30--------------------
29--------------------
31-- INTERFACES
30-- INTERFACES
@@ -34,22 +33,22 @@ import Database.IndexedDB.Core
34-- | Aborts the transaction. All pending requests will fail with a "AbortError"
33-- | Aborts the transaction. All pending requests will fail with a "AbortError"
35-- | DOMException and all changes made to the database will be reverted.
34-- | DOMException and all changes made to the database will be reverted.
36abort
35abort
36+ :: forall tx
37− :: forall e tx. (IDBTransaction tx)
37+ . (IDBTransaction tx)
38 => tx
38 => tx
39− -> Aff (idb :: IDB | e) Unit
39+ -> Aff Unit
40abort =
40abort =
41− _abort
41+ fromEffectFnAff <<< _abort
42−
43
42
44-- | Returns an IDBObjectStore in the transaction's scope.
43-- | Returns an IDBObjectStore in the transaction's scope.
45objectStore
44objectStore
45+ :: forall tx
46− :: forall e tx. (IDBTransaction tx)
46+ . (IDBTransaction tx)
47 => tx
47 => tx
48 -> String
48 -> String
49− -> Aff (idb :: IDB | e) ObjectStore
49+ -> Aff ObjectStore
50objectStore tx name =
50objectStore tx name =
51− Fn.runFn2 _objectStore tx name
51+ fromEffectFnAff $ Fn.runFn2 _objectStore tx name
52−
53
52
54--------------------
53--------------------
55-- ATTRIBUTES
54-- ATTRIBUTES
@@ -62,7 +61,6 @@ db
62db =
61db =
63 _db
62 _db
64
63
65−
66-- | If the transaction was aborted, returns the error (a DOMException) providing the reason.
64-- | If the transaction was aborted, returns the error (a DOMException) providing the reason.
67error
65error
68 :: Transaction
66 :: Transaction
@@ -70,7 +68,6 @@ error
70error =
68error =
71 _error >>> toMaybe
69 _error >>> toMaybe
72
70
73−
74-- | Returns the mode the transaction was created with (`ReadOnly|ReadWrite`)
71-- | Returns the mode the transaction was created with (`ReadOnly|ReadWrite`)
75-- | , or `VersionChange` for an upgrade transaction.
72-- | , or `VersionChange` for an upgrade transaction.
76mode
73mode
@@ -79,7 +76,6 @@ mode
79mode =
76mode =
80 Fn.runFn4 _mode ReadOnly ReadWrite VersionChange
77 Fn.runFn4 _mode ReadOnly ReadWrite VersionChange
81
78
82−
83-- | Returns a list of the names of object stores in the transaction’s scope.
79-- | Returns a list of the names of object stores in the transaction’s scope.
84-- | For an upgrade transaction this is all object stores in the database.
80-- | For an upgrade transaction this is all object stores in the database.
85objectStoreNames
81objectStoreNames
@@ -88,85 +84,70 @@ objectStoreNames
88objectStoreNames =
84objectStoreNames =
89 _objectStoreNames
85 _objectStoreNames
90
86
91−
92--------------------
87--------------------
93-- EVENT HANDLERS
88-- EVENT HANDLERS
94--
89--
95
90
96-- | Event handler for the `abort` event.
91-- | Event handler for the `abort` event.
97onAbort
92onAbort
98− :: forall e e'
99− . Transaction
93+ :: Transaction
100− -> Eff ( | e') Unit
94+ -> Effect Unit
101− -> Aff (idb :: IDB | e) Unit
95+ -> Aff Unit
102onAbort db' f =
96onAbort db' f =
103− Fn.runFn2 _onAbort db' f
97+ fromEffectFnAff $ Fn.runFn2 _onAbort db' f
104−
105
98
106-- | Event handler for the `complete` event.
99-- | Event handler for the `complete` event.
107onComplete
100onComplete
108− :: forall e e'
109− . Transaction
101+ :: Transaction
110− -> Eff ( | e') Unit
102+ -> Effect Unit
111− -> Aff (idb :: IDB | e) Unit
103+ -> Aff Unit
112onComplete db' f =
104onComplete db' f =
113− Fn.runFn2 _onComplete db' f
105+ fromEffectFnAff $ Fn.runFn2 _onComplete db' f
114−
115
106
116-- | Event handler for the `error` event.
107-- | Event handler for the `error` event.
117onError
108onError
118− :: forall e e'
119− . Transaction
109+ :: Transaction
120− -> (Error -> Eff ( | e') Unit)
110+ -> (Error -> Effect Unit)
121− -> Aff (idb :: IDB | e) Unit
111+ -> Aff Unit
122onError db' f =
112onError db' f =
123− Fn.runFn2 _onError db' f
113+ fromEffectFnAff $ Fn.runFn2 _onError db' f
124−
125
114
126--------------------
115--------------------
127-- FFI
116-- FFI
128--
117--
129
118
130foreign import _abort
119foreign import _abort
131− :: forall tx e
120+ :: forall tx
132− . tx
121+ . tx
133− -> Aff (idb :: IDB | e) Unit
122+ -> EffectFnAff Unit
134−
135
123
136foreign import _db
124foreign import _db
137 :: Transaction
125 :: Transaction
138 -> Database
126 -> Database
139
127
140−
141foreign import _error
128foreign import _error
142 :: Transaction
129 :: Transaction
143 -> (Nullable Error)
130 -> (Nullable Error)
144
131
145−
146foreign import _mode
132foreign import _mode
147 :: Fn4 TransactionMode TransactionMode TransactionMode Transaction TransactionMode
133 :: Fn4 TransactionMode TransactionMode TransactionMode Transaction TransactionMode
148
134
149−
150foreign import _objectStoreNames
135foreign import _objectStoreNames
151 :: Transaction
136 :: Transaction
152 -> Array String
137 -> Array String
153
138
154−
155foreign import _objectStore
139foreign import _objectStore
156− :: forall tx e
140+ :: forall tx
157− . Fn2 tx String (Aff (idb :: IDB | e) ObjectStore)
141+ . Fn2 tx String (EffectFnAff ObjectStore)
158−
159
142
160foreign import _onAbort
143foreign import _onAbort
161− :: forall tx e e'
144+ :: forall tx
162− . Fn2 tx (Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
145+ . Fn2 tx (Effect Unit) (EffectFnAff Unit)
163−
164
146
165foreign import _onComplete
147foreign import _onComplete
166− :: forall tx e e'
148+ :: forall tx
167− . Fn2 tx (Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
149+ . Fn2 tx (Effect Unit) (EffectFnAff Unit)
168−
169
150
170foreign import _onError
151foreign import _onError
171− :: forall tx e e'
152+ :: forall tx
172− . Fn2 tx (Error -> Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
153+ . Fn2 tx (Error -> Effect Unit) (EffectFnAff Unit)
test/Main.purs+974−904
@@ -2,995 +2,1060 @@ module Test.Main where
2
2
3import Prelude
3import Prelude
4
4
5−import Control.Monad.Aff (Aff, launchAff, forkAff, delay, attempt)
5+import Data.Array (head, drop)
6−import Control.Monad.Aff.AVar (AVAR, makeVar, makeVar', modifyVar, peekVar, putVar, takeVar)
7−import Control.Monad.Aff.Console (log)
8−import Control.Monad.Eff (Eff)
9−import Control.Monad.Eff.Class (liftEff)
10−import Control.Monad.Eff.Exception (EXCEPTION, message)
11−import Control.Monad.Eff.Now (NOW, now)
12−import Data.Date as Date
6+import Data.Date as Date
13−import Data.DateTime as DateTime
7+import Data.DateTime (DateTime(..), Time(..))
14−import Data.DateTime (DateTime(..), Time(..))
15−import Data.DateTime.Instant (toDateTime)
8+import Data.DateTime.Instant (toDateTime)
16−import Data.Either (Either(..))
9+import Data.Either (Either(..))
17−import Data.Enum (toEnum)
10+import Data.Enum (toEnum)
18−import Data.Maybe (Maybe(..), isNothing, maybe)
11+import Data.Maybe (Maybe(..), isNothing, maybe)
19−import Data.Array (head, drop)
20−import Data.Time.Duration (Milliseconds(..))
12+import Data.Time.Duration (Milliseconds(..))
21−import Data.Traversable (traverse)
13+import Data.Traversable (traverse)
22−import Data.Tuple (Tuple(..), uncurry)
14+import Data.Tuple (Tuple(..), uncurry)
15+import Database.IndexedDB.Core (CursorDirection(..), Database, Index, ObjectStore, Transaction, TransactionMode(..))
16+import Database.IndexedDB.IDBCursor as IDBCursor
17+import Database.IndexedDB.IDBDatabase as IDBDatabase
18+import Database.IndexedDB.IDBFactory as IDBFactory
19+import Database.IndexedDB.IDBIndex as IDBIndex
20+import Database.IndexedDB.IDBKey (Key, none, toKey)
21+import Database.IndexedDB.IDBKeyRange as IDBKeyRange
22+import Database.IndexedDB.IDBObjectStore as IDBObjectStore
23+import Database.IndexedDB.IDBTransaction as IDBTransaction
24+import Effect (Effect)
25+import Effect.Aff (Aff, attempt, delay, forkAff, launchAff, launchAff_)
26+import Effect.Aff.AVar (AVar)
27+import Effect.Aff.AVar as AVar
28+import Effect.Class (liftEffect)
29+import Effect.Console (log)
30+import Effect.Exception (name)
31+import Effect.Now (now)
23−import Test.Spec (describe, describeOnly, it)
32+import Test.Spec (describe, it)
24−import Test.Spec.Assertions (shouldEqual, fail)
33+import Test.Spec.Assertions (shouldEqual, fail)
25−import Test.Spec.Mocha (MOCHA, runMocha)
34+import Test.Spec.Reporter (consoleReporter)
26−
35+import Test.Spec.Runner (runSpec)
27−import Database.IndexedDB.Core
28−import Database.IndexedDB.IDBKey
29−import Database.IndexedDB.IDBCursor as IDBCursor
30−import Database.IndexedDB.IDBDatabase as IDBDatabase
31−import Database.IndexedDB.IDBFactory as IDBFactory
32−import Database.IndexedDB.IDBIndex as IDBIndex
33−import Database.IndexedDB.IDBKeyRange as IDBKeyRange
34−import Database.IndexedDB.IDBObjectStore as IDBObjectStore
35−import Database.IndexedDB.IDBTransaction as IDBTransaction
36−
37
36
38infixr 7 Tuple as :+:
37infixr 7 Tuple as :+:
39
38
40−launchAff' :: forall a e. Aff e a -> Eff (exception :: EXCEPTION | e) Unit
39+launchAff' :: forall a. Aff a -> Effect Unit
41−launchAff' aff =
40+launchAff' =
42− pure unit <* (launchAff aff)
41+ launchAff_ <<< void
42+
43+modifyAVar :: forall a. (a -> a) -> AVar a -> Aff Unit
44+modifyAVar fn v = do
45+ val <- AVar.take v
46+ AVar.put (fn val) v
43
47
44−-- main :: forall eff. Eff (now :: NOW, mocha :: MOCHA, idb :: IDB, exception :: EXCEPTION, avar :: AVAR | eff) Unit
48+main :: Effect Unit
45−main = runMocha do
49+main = do
50+ launchAff_ $ runSpec [ consoleReporter ] $ do
46− describe "IDBFactory" do
51+ describe "IDBFactory" do
47− let
52+ let
48 tearDown name version db = do
53 tearDown name version db = do
49 IDBDatabase.close db
54 IDBDatabase.close db
50 version' <- IDBFactory.deleteDatabase name
55 version' <- IDBFactory.deleteDatabase name
56+ liftEffect $ log $ show version'
51 version' `shouldEqual` version
57 version' `shouldEqual` version
52
58
53− it "open default" do
59+ it "open default" do
60+ let
54− let name = "db-default"
61+ name = "db-default"
55 version = 1
62 version = 1
56− db <- IDBFactory.open name Nothing
63+ db <- IDBFactory.open name Nothing
57− { onUpgradeNeeded : Nothing
64+ { onUpgradeNeeded: Nothing
58− , onBlocked : Nothing
65+ , onBlocked: Nothing
59− }
66+ }
60− IDBDatabase.name db `shouldEqual` name
67+ IDBDatabase.name db `shouldEqual` name
61− tearDown name version db
68+ tearDown name version db
62−
63
69
64− it "open specific version" do
70+ it "open specific version" do
71+ let
65− let name = "db-specific"
72+ name = "db-specific"
66 version = 14
73 version = 14
67− db <- IDBFactory.open name (Just version)
74+ db <- IDBFactory.open name (Just version)
68− { onUpgradeNeeded : Nothing
75+ { onUpgradeNeeded: Nothing
69− , onBlocked : Nothing
76+ , onBlocked: Nothing
70− }
77+ }
71− IDBDatabase.name db `shouldEqual` name
78+ IDBDatabase.name db `shouldEqual` name
72− tearDown name version db
79+ tearDown name version db
73−
74
80
75− it "open specific version -> close -> open latest" do
81+ it "open specific version -> close -> open latest" do
82+ let
76− let name = "db-latest"
83+ name = "db-latest"
77 version = 14
84 version = 14
78− db <- IDBFactory.open name (Just version)
85+ db01 <- IDBFactory.open name (Just version)
79− { onUpgradeNeeded : Nothing
86+ { onUpgradeNeeded: Nothing
80− , onBlocked : Nothing
87+ , onBlocked: Nothing
81− }
88+ }
82− IDBDatabase.name db `shouldEqual` name
89+ IDBDatabase.name db01 `shouldEqual` name
83− IDBDatabase.close db
90+ IDBDatabase.close db01
84− db <- IDBFactory.open name Nothing
91+ db02 <- IDBFactory.open name Nothing
85− { onUpgradeNeeded : Nothing
92+ { onUpgradeNeeded: Nothing
86− , onBlocked : Nothing
93+ , onBlocked: Nothing
87− }
94+ }
88− tearDown name version db
95+ tearDown name version db02
89−
96+
90−
91− it "open + onUpgradeNeed" do
97+ it "open + onUpgradeNeed" do
98+ let
92− let name = "db-upgrade-needed"
99+ name = "db-upgrade-needed"
93 version = 1
100 version = 1
94− callback var db _ = do
101+ callback (Tuple varName varVersion) db _ { oldVersion } = do
95− _ <- launchAff $ modifyVar (const $ IDBDatabase.name db) var
102+ _ <- launchAff $ modifyAVar (const $ IDBDatabase.name db) varName
103+ _ <- launchAff $ modifyAVar (const $ oldVersion) varVersion
96 pure unit
104 pure unit
97− var <- makeVar' "-"
105+ varName <- AVar.new "-"
106+ varVersion <- AVar.new (-1)
98− db <- IDBFactory.open name Nothing
107+ db <- IDBFactory.open name Nothing
99− { onUpgradeNeeded : Just (callback var)
108+ { onUpgradeNeeded: Just (callback (Tuple varName varVersion))
100− , onBlocked : Nothing
109+ , onBlocked: Nothing
101− }
110+ }
102− name <- peekVar var
111+ name' <- AVar.read varName
112+ version' <- AVar.read varVersion
103− name `shouldEqual` name
113+ name' `shouldEqual` name
114+ version' `shouldEqual` 0
104− tearDown name version db
115+ tearDown name version db
105−
116+
106−
107− it "open + onBlocked" do
117+ it "open + onBlocked" do
118+ let
108− let name = "db-blocked"
119+ name = "db-blocked"
109 version = 14
120 version = 14
110 callback var = do
121 callback var = do
111− _ <- launchAff $ modifyVar (const $ "db-blocked") var
122+ _ <- launchAff $ modifyAVar (const $ "db-blocked") var
112 pure unit
123 pure unit
113
124
114− var <- makeVar' "-"
125+ var <- AVar.new "-"
115− db01 <- IDBFactory.open name Nothing
126+ db01 <- IDBFactory.open name Nothing
116− { onUpgradeNeeded : Nothing
127+ { onUpgradeNeeded: Nothing
117− , onBlocked : Nothing
128+ , onBlocked: Nothing
118− }
129+ }
119− _ <- forkAff do
130+ _ <- forkAff do
120− delay (Milliseconds 100.0)
131+ delay (Milliseconds 100.0)
121− IDBDatabase.close db01
132+ IDBDatabase.close db01
122
133
123− db02 <- IDBFactory.open name (Just version)
134+ db02 <- IDBFactory.open name (Just version)
124− { onUpgradeNeeded : Nothing
135+ { onUpgradeNeeded: Nothing
125− , onBlocked : Just (callback var)
136+ , onBlocked: Just (callback var)
126− }
137+ }
127− name <- peekVar var
138+ name' <- AVar.read var
128− name `shouldEqual` name
139+ name' `shouldEqual` name
129− tearDown name version db02
140+ tearDown name version db02
130−
141+
131− describe "IDBKeyRange" do
142+ describe "IDBKeyRange" do
132− it "only(int)" do
143+ it "only(int)" do
144+ let
133− let key = 14
145+ key = 14
134 range = IDBKeyRange.only key
146 range = IDBKeyRange.only key
135− IDBKeyRange.includes range (toKey key) `shouldEqual` true
147+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
136
148
137− it "only(string)" do
149+ it "only(string)" do
150+ let
138− let key = "patate"
151+ key = "patate"
139 range = IDBKeyRange.only key
152 range = IDBKeyRange.only key
140− IDBKeyRange.includes range (toKey key) `shouldEqual` true
153+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
141
154
142− it "only(float)" do
155+ it "only(float)" do
156+ let
143− let key = 14.42
157+ key = 14.42
144 range = IDBKeyRange.only key
158 range = IDBKeyRange.only key
145− IDBKeyRange.includes range (toKey key) `shouldEqual` true
159+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
146
160
147− it "only(date)" do
161+ it "only(date)" do
162+ let
148− let mkey = DateTime
163+ mkey = DateTime
149 <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
164 <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
150 <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
165 <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
151
166
152− case mkey of
167+ case mkey of
153− Nothing ->
168+ Nothing ->
154− fail "unable to create datetime"
169+ fail "unable to create datetime"
155− Just key -> do
170+ Just key -> do
156− let range = IDBKeyRange.only key
171+ let range = IDBKeyRange.only key
157− IDBKeyRange.includes range (toKey key) `shouldEqual` true
172+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
158
173
159− it "only([int])" do
174+ it "only([int])" do
175+ let
160− let key = [14, 42]
176+ key = [ 14, 42 ]
161 range = IDBKeyRange.only key
177 range = IDBKeyRange.only key
162− IDBKeyRange.includes range (toKey key) `shouldEqual` true
178+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
163
179
164− it "only([string])" do
180+ it "only([string])" do
181+ let
165− let key = ["patate", "autruche"]
182+ key = [ "patate", "autruche" ]
166 range = IDBKeyRange.only key
183 range = IDBKeyRange.only key
167− IDBKeyRange.includes range (toKey key) `shouldEqual` true
184+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
168
185
169− it "lowerBound(14, open)" do
186+ it "lowerBound(14, open)" do
187+ let
170− let key = 14
188+ key = 14
171− open = true
189+ open = true
172 range = IDBKeyRange.lowerBound key open
190 range = IDBKeyRange.lowerBound key open
173− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
191+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
174− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
192+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
175− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
193+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
176−
194+
177− it "lowerBound(14, close)" do
195+ it "lowerBound(14, close)" do
196+ let
178− let key = 14
197+ key = 14
179− open = false
198+ open = false
180 range = IDBKeyRange.lowerBound key open
199 range = IDBKeyRange.lowerBound key open
181− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
200+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
182− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
201+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
183− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
202+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
184−
203+
185− it "upperBound(14, open)" do
204+ it "upperBound(14, open)" do
205+ let
186− let key = 14
206+ key = 14
187− open = true
207+ open = true
188 range = IDBKeyRange.upperBound key open
208 range = IDBKeyRange.upperBound key open
189− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
209+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
190− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
210+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
191− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
211+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
192−
212+
193− it "upperBound(14, close)" do
213+ it "upperBound(14, close)" do
214+ let
194− let key = 14
215+ key = 14
195− open = false
216+ open = false
196 range = IDBKeyRange.upperBound key open
217 range = IDBKeyRange.upperBound key open
197− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
218+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
198− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
219+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
199− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
220+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
200−
221+
201− it "bound(42, 14, open, open) => Nothing" do
222+ it "bound(42, 14, open, open) => Nothing" do
223+ let
202− let lower = 42
224+ lower = 42
203− upper = 14
225+ upper = 14
204 lowerOpen = true
226 lowerOpen = true
205 upperOpen = true
227 upperOpen = true
206− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
228+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
207− isNothing mrange `shouldEqual` true
229+ isNothing mrange `shouldEqual` true
208
230
209− it "bound(14, 42, open, open)" do
231+ it "bound(14, 42, open, open)" do
232+ let
210− let lower = 14
233+ lower = 14
211− upper = 42
234+ upper = 42
212 lowerOpen = true
235 lowerOpen = true
213 upperOpen = true
236 upperOpen = true
214− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
237+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
215− case mrange of
238+ case mrange of
216− Nothing ->
239+ Nothing ->
217− fail "invalid range provided"
240+ fail "invalid range provided"
218− Just range -> do
241+ Just range -> do
219− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
242+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
220− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
243+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
221− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
244+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
222− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
245+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
223− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
246+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
224− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
247+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
225−
248+
226− it "bound(14, 42, open, close)" do
249+ it "bound(14, 42, open, close)" do
250+ let
227− let lower = 14
251+ lower = 14
228− upper = 42
252+ upper = 42
229 lowerOpen = true
253 lowerOpen = true
230 upperOpen = false
254 upperOpen = false
231− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
255+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
232− case mrange of
256+ case mrange of
233− Nothing ->
257+ Nothing ->
234− fail "invalid range provided"
258+ fail "invalid range provided"
235− Just range -> do
259+ Just range -> do
236− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
260+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
237− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
261+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
238− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
262+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
239− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
263+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
240− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
264+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
241− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
265+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
242−
266+
243− it "bound(14, 42, close, open)" do
267+ it "bound(14, 42, close, open)" do
268+ let
244− let lower = 14
269+ lower = 14
245− upper = 42
270+ upper = 42
246 lowerOpen = false
271 lowerOpen = false
247 upperOpen = true
272 upperOpen = true
248− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
273+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
249− case mrange of
274+ case mrange of
250− Nothing ->
275+ Nothing ->
251− fail "invalid range provided"
276+ fail "invalid range provided"
252− Just range -> do
277+ Just range -> do
253− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
278+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
254− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
279+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
255− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
280+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
256− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
281+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
257− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
282+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
258− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
283+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
259−
284+
260− it "bound(14, 42, close, close)" do
285+ it "bound(14, 42, close, close)" do
286+ let
261− let lower = 14
287+ lower = 14
262− upper = 42
288+ upper = 42
263 lowerOpen = false
289 lowerOpen = false
264 upperOpen = false
290 upperOpen = false
265− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
291+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
266− case mrange of
292+ case mrange of
267− Nothing ->
293+ Nothing ->
268− fail "invalid range provided"
294+ fail "invalid range provided"
269− Just range -> do
295+ Just range -> do
270− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
296+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
271− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
297+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
272− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
298+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
273− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
299+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
274− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
300+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
275− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
301+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
276−
302+
277− it "can access attributes of a range" do
303+ it "can access attributes of a range" do
278− let range = IDBKeyRange.lowerBound 14 false
304+ let range = IDBKeyRange.lowerBound 14 false
279− IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
305+ IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
280− IDBKeyRange.upper range `shouldEqual` none
306+ IDBKeyRange.upper range `shouldEqual` none
281− IDBKeyRange.lowerOpen range `shouldEqual` false
307+ IDBKeyRange.lowerOpen range `shouldEqual` false
282− IDBKeyRange.upperOpen range `shouldEqual` true
308+ IDBKeyRange.upperOpen range `shouldEqual` true
283−
309+
284− describe "IDBDatabase" do
310+ describe "IDBDatabase" do
285− let
311+ let
286 tearDown db = do
312 tearDown db = do
287 IDBDatabase.close db
313 IDBDatabase.close db
288 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
314 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
289 pure unit
315 pure unit
290
316
291 setup storeParams = do
317 setup storeParams = do
318+ let
292− let onUpgradeNeeded var db _ = launchAff' do
319+ onUpgradeNeeded var db _ _ = launchAff' do
293− store <- IDBDatabase.createObjectStore db "store" storeParams
320+ store <- IDBDatabase.createObjectStore db "store" storeParams
294− _ <- putVar var { db, store }
321+ _ <- AVar.put { db, store } var
295− pure unit
322+ pure unit
296−
323+
297− var <- makeVar
324+ var <- AVar.empty
298− db <- IDBFactory.open "db" Nothing
325+ _ <- IDBFactory.open "db" Nothing
299− { onUpgradeNeeded : Just (onUpgradeNeeded var)
326+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
300− , onBlocked : Nothing
327+ , onBlocked: Nothing
301 }
328 }
302
329
303− takeVar var
330+ AVar.take var
304−
331+
305− it "createObjectStore (keyPath: [], autoIncrement: true)" do
332+ it "createObjectStore (keyPath: [], autoIncrement: true)" do
306− { db, store } <- setup { keyPath: [], autoIncrement: true }
333+ { db, store } <- setup { keyPath: [], autoIncrement: true }
307− IDBObjectStore.name store `shouldEqual` "store"
334+ IDBObjectStore.name store `shouldEqual` "store"
308− IDBObjectStore.keyPath store `shouldEqual` []
335+ IDBObjectStore.keyPath store `shouldEqual` []
309− IDBObjectStore.autoIncrement store `shouldEqual` true
336+ IDBObjectStore.autoIncrement store `shouldEqual` true
310− IDBObjectStore.indexNames store `shouldEqual` []
337+ IDBObjectStore.indexNames store `shouldEqual` []
311− tearDown db
338+ tearDown db
312−
339+
313− it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
340+ it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
314− { db, store } <- setup { keyPath: ["patate"], autoIncrement: true }
341+ { db, store } <- setup { keyPath: [ "patate" ], autoIncrement: true }
315− IDBObjectStore.name store `shouldEqual` "store"
342+ IDBObjectStore.name store `shouldEqual` "store"
316− IDBObjectStore.keyPath store `shouldEqual` ["patate"]
343+ IDBObjectStore.keyPath store `shouldEqual` [ "patate" ]
317− IDBObjectStore.autoIncrement store `shouldEqual` true
344+ IDBObjectStore.autoIncrement store `shouldEqual` true
318− IDBObjectStore.indexNames store `shouldEqual` []
345+ IDBObjectStore.indexNames store `shouldEqual` []
319− tearDown db
346+ tearDown db
320−
347+
321− it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
348+ it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
322− { db, store } <- setup { keyPath: ["patate", "autruche"], autoIncrement: false }
349+ { db, store } <- setup { keyPath: [ "patate", "autruche" ], autoIncrement: false }
323− IDBObjectStore.name store `shouldEqual` "store"
350+ IDBObjectStore.name store `shouldEqual` "store"
324− IDBObjectStore.keyPath store `shouldEqual` ["patate", "autruche"]
351+ IDBObjectStore.keyPath store `shouldEqual` [ "patate", "autruche" ]
325− IDBObjectStore.autoIncrement store `shouldEqual` false
352+ IDBObjectStore.autoIncrement store `shouldEqual` false
326− IDBObjectStore.indexNames store `shouldEqual` []
353+ IDBObjectStore.indexNames store `shouldEqual` []
327− tearDown db
354+ tearDown db
328−
355+
329− it "deleteObjectStore" do
356+ it "deleteObjectStore" do
357+ let
330− let onUpgradeNeeded var db _ = launchAff' do
358+ onUpgradeNeeded var db _ _ = launchAff' do
331 _ <- IDBDatabase.deleteObjectStore db "store"
359 _ <- IDBDatabase.deleteObjectStore db "store"
332− putVar var true
360+ AVar.put true var
333−
361+
334− var <- makeVar
362+ var <- AVar.empty
335− { db, store } <- setup IDBDatabase.defaultParameters
363+ { db } <- setup IDBDatabase.defaultParameters
336− IDBDatabase.close db
364+ IDBDatabase.close db
365+ db' <- IDBFactory.open "db" (Just 999)
337− db <- IDBFactory.open "db" (Just 999) { onUpgradeNeeded : Just (onUpgradeNeeded var)
366+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
338− , onBlocked : Nothing
367+ , onBlocked: Nothing
339− }
368+ }
340− deleted <- takeVar var
369+ deleted <- AVar.take var
341− deleted `shouldEqual` true
370+ deleted `shouldEqual` true
342− tearDown db
371+ tearDown db'
343−
344
372
345− describe "IDBObjectStore" do
373+ describe "IDBObjectStore" do
346− let
374+ let
347 tearDown db = do
375 tearDown db = do
348 IDBDatabase.close db
376 IDBDatabase.close db
349 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
377 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
350 pure unit
378 pure unit
351
379
352 setup { storeParams, onUpgradeNeeded } = do
380 setup { storeParams, onUpgradeNeeded } = do
381+ let
353− let onUpgradeNeeded' var db _ = launchAff' do
382+ onUpgradeNeeded' var db _ _ = launchAff' do
354− store <- IDBDatabase.createObjectStore db "store" storeParams
383+ store <- IDBDatabase.createObjectStore db "store" storeParams
355− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure store)
384+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure store)
356− putVar var { db, store }
385+ AVar.put { db, store } var
357−
386+
358− var <- makeVar
387+ var <- AVar.empty
359− db <- IDBFactory.open "db" Nothing
388+ _ <- IDBFactory.open "db" Nothing
360− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
389+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
361− , onBlocked : Nothing
390+ , onBlocked: Nothing
362 }
391 }
363
392
364− takeVar var
393+ AVar.take var
365−
394+
366− it "add()" do
395+ it "add()" do
367− date <- liftEff $ toDateTime <$> now
396+ date <- liftEffect $ toDateTime <$> now
368− { db } <- setup
397+ { db } <- setup
369− { storeParams: { autoIncrement: true, keyPath: [] }
398+ { storeParams: { autoIncrement: true, keyPath: [] }
370− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
399+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
371− -- no key
400+ -- no key
372− key <- IDBObjectStore.add store "patate" none
401+ key <- IDBObjectStore.add store "patate" none
373− (toKey 1) `shouldEqual` key
402+ (toKey 1) `shouldEqual` key
374−
403+
375− -- int key
404+ -- int key
376− key <- IDBObjectStore.add store "patate" (Just 14)
405+ key' <- IDBObjectStore.add store "patate" (Just 14)
377− (toKey 14) `shouldEqual` key
406+ (toKey 14) `shouldEqual` key'
378−
407+
379− -- number key
408+ -- number key
380− key <- IDBObjectStore.add store "patate" (Just 14.42)
409+ key'' <- IDBObjectStore.add store "patate" (Just 14.42)
381− (toKey 14.42) `shouldEqual` key
410+ (toKey 14.42) `shouldEqual` key''
382−
411+
383− -- string key
412+ -- string key
384− key <- IDBObjectStore.add store "patate" (Just "key")
413+ key''' <- IDBObjectStore.add store "patate" (Just "key")
385− (toKey "key") `shouldEqual` key
414+ (toKey "key") `shouldEqual` key'''
386−
415+
387− -- date key
416+ -- date key
388− key <- IDBObjectStore.add store "patate" (Just date)
417+ key'''' <- IDBObjectStore.add store "patate" (Just date)
389− (toKey date) `shouldEqual` key
418+ (toKey date) `shouldEqual` key''''
390−
419+
391− -- array key
420+ -- array key
392− key <- IDBObjectStore.add store "patate" (Just $ toKey [14, 42])
421+ key''''' <- IDBObjectStore.add store "patate" (Just $ toKey [ 14, 42 ])
393− (toKey [14, 42]) `shouldEqual` key
422+ (toKey [ 14, 42 ]) `shouldEqual` key'''''
394− }
423+ }
395− tearDown db
424+ tearDown db
396−
425+
397− it "clear()" do
426+ it "clear()" do
398− { db } <- setup
427+ { db } <- setup
399− { storeParams: IDBDatabase.defaultParameters
428+ { storeParams: IDBDatabase.defaultParameters
400− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
429+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
401− key <- IDBObjectStore.add store "patate" (Just 14)
430+ key <- IDBObjectStore.add store "patate" (Just 14)
402− _ <- IDBObjectStore.clear store
431+ _ <- IDBObjectStore.clear store
403− val <- IDBObjectStore.get store (IDBKeyRange.only key)
432+ val <- IDBObjectStore.get store (IDBKeyRange.only key)
404− val `shouldEqual` (Nothing :: Maybe String)
433+ val `shouldEqual` (Nothing :: Maybe String)
405− }
406− tearDown db
407−
408− it "count()" do
409− { db } <- setup
410− { storeParams: IDBDatabase.defaultParameters
411− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
412− key <- IDBObjectStore.add store "patate" (Just 14)
413− key <- IDBObjectStore.add store "autruche" (Just 42)
414− n <- IDBObjectStore.count store Nothing
415− n `shouldEqual` 2
416− }
417− tearDown db
418−
419− it "getKey()" do
420− { db } <- setup
421− { storeParams: IDBDatabase.defaultParameters
422− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
423− key <- IDBObjectStore.add store "patate" (Just 14)
424− mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
425− mkey `shouldEqual` (Just key)
426−
427− mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 42)
428− mkey `shouldEqual` none
429 }
434 }
435+ tearDown db
436+
437+ it "count()" do
438+ { db } <- setup
439+ { storeParams: IDBDatabase.defaultParameters
440+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
441+ _ <- IDBObjectStore.add store "patate" (Just 14)
442+ _ <- IDBObjectStore.add store "autruche" (Just 42)
443+ n <- IDBObjectStore.count store Nothing
444+ n `shouldEqual` 2
445+ }
446+ tearDown db
447+
448+ it "getKey()" do
449+ { db } <- setup
450+ { storeParams: IDBDatabase.defaultParameters
451+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
452+ key <- IDBObjectStore.add store "patate" (Just 14)
453+ mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
454+ mkey `shouldEqual` (Just key)
455+
456+ mkey' <- IDBObjectStore.getKey store (IDBKeyRange.only 42)
457+ mkey' `shouldEqual` none
458+ }
430− tearDown db
459+ tearDown db
431−
460+
432− it "getAllKeys()" do
461+ it "getAllKeys()" do
433− { db } <- setup
462+ { db } <- setup
434− { storeParams: IDBDatabase.defaultParameters
463+ { storeParams: IDBDatabase.defaultParameters
435− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
464+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
436− key1 <- IDBObjectStore.add store "patate" (Just 14)
465+ key1 <- IDBObjectStore.add store "patate" (Just 14)
437− key2 <- IDBObjectStore.add store "autruche" (Just 42)
466+ key2 <- IDBObjectStore.add store "autruche" (Just 42)
438− key3 <- IDBObjectStore.add store 14 (Just 1337)
467+ key3 <- IDBObjectStore.add store 14 (Just 1337)
439−
468+
440− -- no bounds
469+ -- no bounds
441− keys <- IDBObjectStore.getAllKeys store Nothing Nothing
470+ keys <- IDBObjectStore.getAllKeys store Nothing Nothing
442− keys `shouldEqual` [key1, key2, key3]
471+ keys `shouldEqual` [ key1, key2, key3 ]
443−
472+
444− -- lower bound
473+ -- lower bound
445− keys <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
474+ keys' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
446− keys `shouldEqual` [key2, key3]
475+ keys' `shouldEqual` [ key2, key3 ]
447−
476+
448− -- upper bound
477+ -- upper bound
449− keys <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
478+ keys'' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
450− keys `shouldEqual` [key1, key2]
479+ keys'' `shouldEqual` [ key1, key2 ]
451−
480+
452− -- count
481+ -- count
453− keys <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
482+ keys''' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
454− keys `shouldEqual` [key1, key2]
483+ keys''' `shouldEqual` [ key1, key2 ]
455− }
484+ }
456− tearDown db
485+ tearDown db
457−
486+
458− it "openCursor()" do
487+ it "openCursor()" do
459− let cb =
488+ let
489+ cb =
460− { onSuccess : const $ pure unit
490+ { onSuccess: const $ pure unit
461− , onError : show >>> fail >>> launchAff'
491+ , onError: show >>> fail >>> launchAff'
462 , onComplete: pure unit
492 , onComplete: pure unit
463 }
493 }
464− { db } <- setup
494+ { db } <- setup
465− { storeParams: IDBDatabase.defaultParameters
495+ { storeParams: IDBDatabase.defaultParameters
466− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
496+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
467− _ <- IDBObjectStore.openCursor store Nothing Next cb
497+ _ <- IDBObjectStore.openCursor store Nothing Next cb
468− _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
498+ _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
469− _ <- IDBObjectStore.openCursor store Nothing Prev cb
499+ _ <- IDBObjectStore.openCursor store Nothing Prev cb
470− _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
500+ _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
471− _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
501+ _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
472− pure unit
502+ pure unit
473− }
503+ }
474− tearDown db
504+ tearDown db
475
505
476− it "openKeyCursor()" do
506+ it "openKeyCursor()" do
477− let cb =
507+ let
508+ cb =
478− { onSuccess : const $ pure unit
509+ { onSuccess: const $ pure unit
479− , onError : show >>> fail >>> launchAff'
510+ , onError: show >>> fail >>> launchAff'
480 , onComplete: pure unit
511 , onComplete: pure unit
481 }
512 }
482− { db } <- setup
513+ { db } <- setup
483− { storeParams: IDBDatabase.defaultParameters
514+ { storeParams: IDBDatabase.defaultParameters
484− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
515+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
485− _ <- IDBObjectStore.openKeyCursor store Nothing Next cb
516+ _ <- IDBObjectStore.openKeyCursor store Nothing Next cb
486− _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique cb
517+ _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique cb
487− _ <- IDBObjectStore.openKeyCursor store Nothing Prev cb
518+ _ <- IDBObjectStore.openKeyCursor store Nothing Prev cb
488− _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique cb
519+ _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique cb
489− _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
520+ _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
490− pure unit
521+ pure unit
491− }
522+ }
492− tearDown db
523+ tearDown db
493
524
494− describe "IDBIndex" do
525+ describe "IDBIndex" do
495− let
526+ let
496 tearDown db = do
527 tearDown db = do
497 IDBDatabase.close db
528 IDBDatabase.close db
498 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
529 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
499 pure unit
530 pure unit
500
531
532+ setup
501− setup :: forall value e e'.
533+ :: forall value
502− { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
534+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
503− , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
535+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
504− , values :: Array (Tuple value (Maybe Key))
536+ , values :: Array (Tuple value (Maybe Key))
505− , keyPath :: Array String
537+ , keyPath :: Array String
506− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Eff (idb :: IDB, avar :: AVAR, exception :: EXCEPTION | e') Unit)
538+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
539+ }
507− } -> Aff (idb :: IDB, avar :: AVAR | e) { db :: Database, index :: Index, store :: ObjectStore }
540+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
508 setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
541 setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
542+ let
509− let onUpgradeNeeded' var db tx = launchAff' do
543+ onUpgradeNeeded' var db tx _ = launchAff' do
510− store <- IDBDatabase.createObjectStore db "store" storeParams
544+ store <- IDBDatabase.createObjectStore db "store" storeParams
511− _ <- traverse (uncurry (IDBObjectStore.add store)) values
545+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
512− index <- IDBObjectStore.createIndex store "index" keyPath indexParams
546+ index <- IDBObjectStore.createIndex store "index" keyPath indexParams
513− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
547+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
514− putVar var { db, index, store }
548+ AVar.put { db, index, store } var
515−
549+
516− var <- makeVar
550+ var <- AVar.empty
517− db <- IDBFactory.open "db" Nothing
551+ _ <- IDBFactory.open "db" Nothing
518− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
552+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
519− , onBlocked : Nothing
553+ , onBlocked: Nothing
520 }
554 }
521− takeVar var
555+ AVar.take var
522−
556+
523−
524− it "returns an IDBIndex and the properties are set correctly" do
557+ it "returns an IDBIndex and the properties are set correctly" do
525− { db, index } <- setup
558+ { db, index } <- setup
526− { storeParams : IDBDatabase.defaultParameters
559+ { storeParams: IDBDatabase.defaultParameters
527− , indexParams : IDBObjectStore.defaultParameters
560+ , indexParams: IDBObjectStore.defaultParameters
528− , onUpgradeNeeded : Nothing
561+ , onUpgradeNeeded: Nothing
529− , keyPath : []
562+ , keyPath: []
530− , values : []
563+ , values: []
531− }
564+ }
532− IDBIndex.name index `shouldEqual` "index"
565+ IDBIndex.name index `shouldEqual` "index"
533− IDBIndex.keyPath index `shouldEqual` []
566+ IDBIndex.keyPath index `shouldEqual` []
534− IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
567+ IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
535− IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
568+ IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
536− tearDown db
569+ tearDown db
537−
570+
538− it "attempt to create an index that requires unique values on an object store already contains duplicates" do
571+ it "attempt to create an index that requires unique values on an object store already contains duplicates" do
539− let onAbort var = launchAff' (putVar var true)
572+ let onAbort var = launchAff' (AVar.put true var)
540− txVar <- makeVar
573+ txVar <- AVar.empty
541− dbVar <- makeVar
574+ dbVar <- AVar.empty
542− res <- attempt $ setup
575+ res <- attempt $ setup
543− { storeParams : IDBDatabase.defaultParameters
576+ { storeParams: IDBDatabase.defaultParameters
544− , indexParams : { unique : true
577+ , indexParams:
578+ { unique: true
545− , multiEntry : false
579+ , multiEntry: false
546− }
580+ }
547− , keyPath : ["indexedProperty"]
581+ , keyPath: [ "indexedProperty" ]
582+ , values:
548− , values : [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
583+ [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
549− , { indexedProperty: "bar" } :+: (Just $ toKey 2)
584+ , { indexedProperty: "bar" } :+: (Just $ toKey 2)
550− ]
585+ ]
551− , onUpgradeNeeded : Just $ \db tx _ -> launchAff' do
586+ , onUpgradeNeeded: Just $ \db tx _ -> launchAff' do
552− IDBTransaction.onAbort tx (onAbort txVar)
587+ IDBTransaction.onAbort tx (onAbort txVar)
553− IDBDatabase.onAbort db (onAbort dbVar)
588+ IDBDatabase.onAbort db (onAbort dbVar)
554− }
589+ }
555− case res of
590+ case res of
556− Right _ ->
591+ Right _ ->
557− fail "expected abort"
592+ fail "expected abort"
558− _ -> do
593+ _ -> do
559− shouldEqual true =<< takeVar txVar
594+ shouldEqual true =<< AVar.take txVar
560− shouldEqual true =<< takeVar dbVar
595+ shouldEqual true =<< AVar.take dbVar
561−
596+
562−
563− it "the index is usable right after being made" do
597+ it "the index is usable right after being made" do
564− { db } <- setup
598+ { db } <- setup
565− { storeParams : { keyPath : ["key"]
599+ { storeParams:
600+ { keyPath: [ "key" ]
566− , autoIncrement : false
601+ , autoIncrement: false
567− }
602+ }
568− , indexParams : IDBObjectStore.defaultParameters
603+ , indexParams: IDBObjectStore.defaultParameters
569− , keyPath : ["indexedProperty"]
604+ , keyPath: [ "indexedProperty" ]
605+ , values:
570− , values : [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
606+ [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
571− , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
607+ , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
572− , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
608+ , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
573− ]
609+ ]
574− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
610+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
575− val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
611+ val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
576− ((\r -> r.key) <$> val) `shouldEqual` (Just $ toKey "key2")
612+ ((\r -> r.key) <$> val) `shouldEqual` (Just $ toKey "key2")
577− }
613+ }
578− tearDown db
614+ tearDown db
579−
615+
580− it "empty keyPath" do
616+ it "empty keyPath" do
581− { db } <- setup
617+ { db } <- setup
582− { storeParams : IDBDatabase.defaultParameters
618+ { storeParams: IDBDatabase.defaultParameters
583− , indexParams : IDBObjectStore.defaultParameters
619+ , indexParams: IDBObjectStore.defaultParameters
584− , keyPath : []
620+ , keyPath: []
621+ , values:
585− , values : [ "object_1" :+: (Just $ toKey 1)
622+ [ "object_1" :+: (Just $ toKey 1)
586− , "object_2" :+: (Just $ toKey 2)
623+ , "object_2" :+: (Just $ toKey 2)
587− , "object_3" :+: (Just $ toKey 3)
624+ , "object_3" :+: (Just $ toKey 3)
588− ]
625+ ]
589− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
626+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
590− val <- IDBIndex.get index (IDBKeyRange.only "object_3")
627+ val <- IDBIndex.get index (IDBKeyRange.only "object_3")
591− val `shouldEqual` (Just "object_3")
628+ val `shouldEqual` (Just "object_3")
592− }
629+ }
593− tearDown db
630+ tearDown db
594−
631+
595− it "index can be valid keys [date]" do
632+ it "index can be valid keys [date]" do
596− date <- liftEff $ toDateTime <$> now
633+ date <- liftEffect $ toDateTime <$> now
597− { db } <- setup
634+ { db } <- setup
598− { storeParams : { keyPath: ["key"]
635+ { storeParams:
636+ { keyPath: [ "key" ]
599− , autoIncrement: false
637+ , autoIncrement: false
600− }
638+ }
601− , indexParams : IDBObjectStore.defaultParameters
639+ , indexParams: IDBObjectStore.defaultParameters
602− , keyPath : ["i"]
640+ , keyPath: [ "i" ]
641+ , values:
603− , values : [ { key: "date", i: (toKey date) } :+: Nothing
642+ [ { key: "date", i: (toKey date) } :+: Nothing
604− ]
643+ ]
605− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
644+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
606− val <- IDBIndex.get index (IDBKeyRange.only date)
645+ val <- IDBIndex.get index (IDBKeyRange.only date)
607− ((\r -> r.key) <$> val) `shouldEqual` (Just "date")
646+ ((\r -> r.key) <$> val) `shouldEqual` (Just "date")
608− }
647+ }
609− tearDown db
648+ tearDown db
610−
649+
611− it "index can be valid keys [num]" do
650+ it "index can be valid keys [num]" do
612− let num = 14
651+ let num = 14
613− { db } <- setup
652+ { db } <- setup
614− { storeParams : { keyPath: ["key"]
653+ { storeParams:
654+ { keyPath: [ "key" ]
615− , autoIncrement: false
655+ , autoIncrement: false
616− }
656+ }
617− , indexParams : IDBObjectStore.defaultParameters
657+ , indexParams: IDBObjectStore.defaultParameters
618− , keyPath : ["i"]
658+ , keyPath: [ "i" ]
659+ , values:
619− , values : [ { key: "num", i: (toKey num) } :+: Nothing
660+ [ { key: "num", i: (toKey num) } :+: Nothing
620− ]
661+ ]
621− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
662+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
622− val <- IDBIndex.get index (IDBKeyRange.only num)
663+ val <- IDBIndex.get index (IDBKeyRange.only num)
623− ((\r -> r.key) <$> val) `shouldEqual` (Just "num")
664+ ((\r -> r.key) <$> val) `shouldEqual` (Just "num")
624− }
665+ }
625− tearDown db
666+ tearDown db
626−
667+
627− it "index can be valid keys [array]" do
668+ it "index can be valid keys [array]" do
628− let array = ["patate", "autruche"]
669+ let array = [ "patate", "autruche" ]
629− { db } <- setup
670+ { db } <- setup
630− { storeParams : { keyPath: ["key"]
671+ { storeParams:
672+ { keyPath: [ "key" ]
631− , autoIncrement: false
673+ , autoIncrement: false
632− }
674+ }
633− , indexParams : IDBObjectStore.defaultParameters
675+ , indexParams: IDBObjectStore.defaultParameters
634− , keyPath : ["i"]
676+ , keyPath: [ "i" ]
677+ , values:
635− , values : [ { key: "array", i: (toKey array) } :+: Nothing
678+ [ { key: "array", i: (toKey array) } :+: Nothing
636− ]
679+ ]
637− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
680+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
638− val <- IDBIndex.get index (IDBKeyRange.only array)
681+ val <- IDBIndex.get index (IDBKeyRange.only array)
639− ((\r -> r.key) <$> val) `shouldEqual` (Just "array")
682+ ((\r -> r.key) <$> val) `shouldEqual` (Just "array")
640− }
683+ }
641− tearDown db
684+ tearDown db
642−
685+
643− it "openKeyCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
686+ it "openKeyCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
644− res <- attempt $ setup
687+ res <- attempt $ setup
645− { storeParams : { keyPath: ["key"], autoIncrement: false }
688+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
646− , indexParams : IDBObjectStore.defaultParameters
689+ , indexParams: IDBObjectStore.defaultParameters
647− , keyPath : ["indexedProperty"]
690+ , keyPath: [ "indexedProperty" ]
691+ , values:
648− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
692+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
649− ]
693+ ]
650− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
694+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
651− let cb =
695+ let
696+ cb =
652− { onSuccess : const $ pure unit
697+ { onSuccess: const $ pure unit
653− , onError : show >>> fail >>> launchAff'
698+ , onError: show >>> fail >>> launchAff'
654 , onComplete: pure unit
699 , onComplete: pure unit
655 }
700 }
656− IDBTransaction.onAbort tx (pure unit)
701+ IDBTransaction.onAbort tx (pure unit)
657− IDBDatabase.onAbort db (pure unit)
702+ IDBDatabase.onAbort db (pure unit)
658− IDBTransaction.abort tx
703+ IDBTransaction.abort tx
659− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
704+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
660− case cursor of
705+ case cursor of
661− Right _ -> fail "expected InvalidStateError"
706+ Right _ -> fail "expected InvalidStateError"
662− Left err -> message err `shouldEqual` "InvalidStateError"
707+ Left err -> name err `shouldEqual` "InvalidStateError"
663− }
708+ }
664− case res of
709+ case res of
665− Right _ -> fail "expected InvalidStateError"
710+ Right _ -> fail "expected InvalidStateError"
666− _ -> pure unit
711+ _ -> pure unit
667−
712+
668− it "openKeyCursor() - throw TransactionInactiveError on aborted transaction" do
713+ it "openKeyCursor() - throw TransactionInactiveError on aborted transaction" do
669− { db } <- setup
714+ { db } <- setup
670− { storeParams : { keyPath: ["key"], autoIncrement: false }
715+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
671− , indexParams : IDBObjectStore.defaultParameters
716+ , indexParams: IDBObjectStore.defaultParameters
672− , keyPath : ["indexedProperty"]
717+ , keyPath: [ "indexedProperty" ]
718+ , values:
673− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
719+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
674− ]
720+ ]
675− , onUpgradeNeeded : Nothing
721+ , onUpgradeNeeded: Nothing
676− }
722+ }
677− let cb =
723+ let
724+ cb =
678− { onSuccess : const $ pure unit
725+ { onSuccess: const $ pure unit
679− , onError : show >>> fail >>> launchAff'
726+ , onError: show >>> fail >>> launchAff'
680 , onComplete: pure unit
727 , onComplete: pure unit
681 }
728 }
682− tx <- IDBDatabase.transaction db ["store"] ReadOnly
729+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
683− store <- IDBTransaction.objectStore tx "store"
730+ store <- IDBTransaction.objectStore tx "store"
684− index <- IDBObjectStore.index store "index"
731+ index <- IDBObjectStore.index store "index"
685− IDBTransaction.onAbort tx (pure unit)
732+ IDBTransaction.onAbort tx (pure unit)
686− IDBTransaction.abort tx
733+ IDBTransaction.abort tx
687− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
734+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
688− case cursor of
735+ case cursor of
689− Right _ -> fail "expected TransactionInactiveError"
736+ Right _ -> fail "expected TransactionInactiveError"
690− Left err -> message err `shouldEqual` "TransactionInactiveError"
737+ Left err -> name err `shouldEqual` "TransactionInactiveError"
691−
738+
692− tearDown db
739+ tearDown db
693−
740+
694− it "openKeyCursor() - throw InvalidStateError when the index is deleted" do
741+ it "openKeyCursor() - throw InvalidStateError when the index is deleted" do
695− { db } <- setup
742+ { db } <- setup
696− { storeParams : { keyPath: ["key"], autoIncrement: false }
743+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
697− , indexParams : IDBObjectStore.defaultParameters
744+ , indexParams: IDBObjectStore.defaultParameters
698− , keyPath : ["indexedProperty"]
745+ , keyPath: [ "indexedProperty" ]
746+ , values:
699− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
747+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
700− ]
748+ ]
701− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
749+ , onUpgradeNeeded: Just $ \_ tx index -> launchAff' do
702− let cb =
750+ let
751+ cb =
703− { onSuccess : const $ pure unit
752+ { onSuccess: const $ pure unit
704− , onError : show >>> fail >>> launchAff'
753+ , onError: show >>> fail >>> launchAff'
705 , onComplete: pure unit
754 , onComplete: pure unit
706 }
755 }
707− store <- IDBTransaction.objectStore tx "store"
756+ store <- IDBTransaction.objectStore tx "store"
708− IDBObjectStore.deleteIndex store "index"
757+ IDBObjectStore.deleteIndex store "index"
709− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
758+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
710− case cursor of
759+ case cursor of
711− Right _ -> fail "expected InvalidStateError"
760+ Right _ -> fail "expected InvalidStateError"
712− Left err -> message err `shouldEqual` "InvalidStateError"
761+ Left err -> name err `shouldEqual` "InvalidStateError"
713− }
762+ }
714−
763+
715− tearDown db
764+ tearDown db
716−
765+
717− it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
766+ it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
718− res <- attempt $ setup
767+ res <- attempt $ setup
719− { storeParams : { keyPath: ["key"], autoIncrement: false }
768+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
720− , indexParams : IDBObjectStore.defaultParameters
769+ , indexParams: IDBObjectStore.defaultParameters
721− , keyPath : ["indexedProperty"]
770+ , keyPath: [ "indexedProperty" ]
771+ , values:
722− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
772+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
723− ]
773+ ]
724− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
774+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
725− let cb =
775+ let
776+ cb =
726− { onSuccess : const $ pure unit
777+ { onSuccess: const $ pure unit
727− , onError : show >>> fail >>> launchAff'
778+ , onError: show >>> fail >>> launchAff'
728 , onComplete: pure unit
779 , onComplete: pure unit
729 }
780 }
730− IDBTransaction.onAbort tx (pure unit)
781+ IDBTransaction.onAbort tx (pure unit)
731− IDBDatabase.onAbort db (pure unit)
782+ IDBDatabase.onAbort db (pure unit)
732− IDBTransaction.abort tx
783+ IDBTransaction.abort tx
733− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
784+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
734− case cursor of
785+ case cursor of
735− Right _ -> fail "expected InvalidStateError"
786+ Right _ -> fail "expected InvalidStateError"
736− Left err -> message err `shouldEqual` "InvalidStateError"
787+ Left err -> name err `shouldEqual` "InvalidStateError"
737− }
788+ }
738− case res of
789+ case res of
739− Right _ -> fail "expected InvalidStateError"
790+ Right _ -> fail "expected InvalidStateError"
740− _ -> pure unit
791+ _ -> pure unit
741−
792+
742− it "openCursor() - throw TransactionInactiveError on aborted transaction" do
793+ it "openCursor() - throw TransactionInactiveError on aborted transaction" do
743− { db } <- setup
794+ { db } <- setup
744− { storeParams : { keyPath: ["key"], autoIncrement: false }
795+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
745− , indexParams : IDBObjectStore.defaultParameters
796+ , indexParams: IDBObjectStore.defaultParameters
746− , keyPath : ["indexedProperty"]
797+ , keyPath: [ "indexedProperty" ]
798+ , values:
747− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
799+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
748− ]
800+ ]
749− , onUpgradeNeeded : Nothing
801+ , onUpgradeNeeded: Nothing
750− }
802+ }
751− let cb =
803+ let
804+ cb =
752− { onSuccess : const $ pure unit
805+ { onSuccess: const $ pure unit
753− , onError : show >>> fail >>> launchAff'
806+ , onError: show >>> fail >>> launchAff'
754 , onComplete: pure unit
807 , onComplete: pure unit
755 }
808 }
756− tx <- IDBDatabase.transaction db ["store"] ReadOnly
809+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
757− store <- IDBTransaction.objectStore tx "store"
810+ store <- IDBTransaction.objectStore tx "store"
758− index <- IDBObjectStore.index store "index"
811+ index <- IDBObjectStore.index store "index"
759− IDBTransaction.onAbort tx (pure unit)
812+ IDBTransaction.onAbort tx (pure unit)
760− IDBTransaction.abort tx
813+ IDBTransaction.abort tx
761− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
814+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
762− case cursor of
815+ case cursor of
763− Right _ -> fail "expected TransactionInactiveError"
816+ Right _ -> fail "expected TransactionInactiveError"
764− Left err -> message err `shouldEqual` "TransactionInactiveError"
817+ Left err -> name err `shouldEqual` "TransactionInactiveError"
765−
818+
766− tearDown db
819+ tearDown db
767−
820+
768− it "openCursor() - throw InvalidStateError when the index is deleted" do
821+ it "openCursor() - throw InvalidStateError when the index is deleted" do
769− { db } <- setup
822+ { db } <- setup
770− { storeParams : { keyPath: ["key"], autoIncrement: false }
823+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
771− , indexParams : IDBObjectStore.defaultParameters
824+ , indexParams: IDBObjectStore.defaultParameters
772− , keyPath : ["indexedProperty"]
825+ , keyPath: [ "indexedProperty" ]
826+ , values:
773− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
827+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
774− ]
828+ ]
775− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
829+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
776− let cb =
830+ let
831+ cb =
777− { onSuccess : const $ pure unit
832+ { onSuccess: const $ pure unit
778− , onError : show >>> fail >>> launchAff'
833+ , onError: show >>> fail >>> launchAff'
779 , onComplete: pure unit
834 , onComplete: pure unit
780 }
835 }
781− store <- IDBTransaction.objectStore tx "store"
836+ store <- IDBTransaction.objectStore tx "store"
782− IDBObjectStore.deleteIndex store "index"
837+ IDBObjectStore.deleteIndex store "index"
783− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
838+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
784− case cursor of
839+ case cursor of
785− Right _ -> fail "expected InvalidStateError"
840+ Right _ -> fail "expected InvalidStateError"
786− Left err -> message err `shouldEqual` "InvalidStateError"
841+ Left err -> name err `shouldEqual` "InvalidStateError"
787− }
842+ }
788−
843+
789− tearDown db
844+ tearDown db
790−
845+
791− it "getKey() - multiEntry - adding keys" do
846+ it "getKey() - multiEntry - adding keys" do
792− { db } <- setup
847+ { db } <- setup
793− { storeParams : IDBDatabase.defaultParameters
848+ { storeParams: IDBDatabase.defaultParameters
794− , indexParams : { unique: false, multiEntry: true }
849+ , indexParams: { unique: false, multiEntry: true }
795− , keyPath : ["name"]
850+ , keyPath: [ "name" ]
851+ , values:
796− , values : [ { name: ["patate", "autruche"] } :+: (Just $ toKey 1)
852+ [ { name: [ "patate", "autruche" ] } :+: (Just $ toKey 1)
797− , { name: ["bob"] } :+: (Just $ toKey 2)
853+ , { name: [ "bob" ] } :+: (Just $ toKey 2)
798− ]
854+ ]
799− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
855+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
800− key <- IDBIndex.getKey index (IDBKeyRange.only "patate")
856+ key <- IDBIndex.getKey index (IDBKeyRange.only "patate")
801− key `shouldEqual` (Just $ toKey 1)
857+ key `shouldEqual` (Just $ toKey 1)
802−
858+
803− key <- IDBIndex.getKey index (IDBKeyRange.only "autruche")
859+ key' <- IDBIndex.getKey index (IDBKeyRange.only "autruche")
804− key `shouldEqual` (Just $ toKey 1)
860+ key' `shouldEqual` (Just $ toKey 1)
805−
861+
806− key <- IDBIndex.getKey index (IDBKeyRange.only "bob")
862+ key'' <- IDBIndex.getKey index (IDBKeyRange.only "bob")
807− key `shouldEqual` (Just $ toKey 2)
863+ key'' `shouldEqual` (Just $ toKey 2)
808− }
864+ }
809− tearDown db
865+ tearDown db
810−
866+
811−
812− it "get() - returns the record with the first key in the range" do
867+ it "get() - returns the record with the first key in the range" do
813− { db } <- setup
868+ { db } <- setup
814− { storeParams : { keyPath: ["key"], autoIncrement: false }
869+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
815− , indexParams : IDBObjectStore.defaultParameters
870+ , indexParams: IDBObjectStore.defaultParameters
816− , keyPath : ["indexedProperty"]
871+ , keyPath: [ "indexedProperty" ]
872+ , values:
817− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
873+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
818− , { key: 42, indexedProperty: "autruche" } :+: Nothing
874+ , { key: 42, indexedProperty: "autruche" } :+: Nothing
819− , { key: 1337, indexedProperty: "baguette" } :+: Nothing
875+ , { key: 1337, indexedProperty: "baguette" } :+: Nothing
820− ]
876+ ]
821− , onUpgradeNeeded : Nothing
877+ , onUpgradeNeeded: Nothing
822− }
878+ }
823−
879+
824− tx <- IDBDatabase.transaction db ["store"] ReadOnly
880+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
825− store <- IDBTransaction.objectStore tx "store"
881+ store <- IDBTransaction.objectStore tx "store"
826− index <- IDBObjectStore.index store "index"
882+ index <- IDBObjectStore.index store "index"
827− val <- IDBIndex.get index (IDBKeyRange.lowerBound "autruche" false)
883+ val <- IDBIndex.get index (IDBKeyRange.lowerBound "autruche" false)
828− ((\r -> r.key) <$> val) `shouldEqual` (Just 42)
884+ ((\r -> r.key) <$> val) `shouldEqual` (Just 42)
829−
885+
830− tearDown db
886+ tearDown db
831−
887+
832− describe "IDBCursor" do
888+ describe "IDBCursor" do
833− let
889+ let
834 tearDown db = do
890 tearDown db = do
835 IDBDatabase.close db
891 IDBDatabase.close db
836 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
892 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
837 pure unit
893 pure unit
838
894
895+ setup
839− setup :: forall value e e'.
896+ :: forall value
840− { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
897+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
841− , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
898+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
842− , values :: Array (Tuple value (Maybe Key))
899+ , values :: Array (Tuple value (Maybe Key))
843− , keyPath :: Array String
900+ , keyPath :: Array String
844− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Eff (idb :: IDB, avar :: AVAR, exception :: EXCEPTION | e') Unit)
901+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
902+ }
845− } -> Aff (idb :: IDB, avar :: AVAR | e) { db :: Database, index :: Index, store :: ObjectStore }
903+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
846 setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
904 setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
905+ let
847− let onUpgradeNeeded' var db tx = launchAff' do
906+ onUpgradeNeeded' var db tx _ = launchAff' do
848− store <- IDBDatabase.createObjectStore db "store" storeParams
907+ store <- IDBDatabase.createObjectStore db "store" storeParams
849− _ <- traverse (uncurry (IDBObjectStore.add store)) values
908+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
850− index <- IDBObjectStore.createIndex store "index" keyPath indexParams
909+ index <- IDBObjectStore.createIndex store "index" keyPath indexParams
851− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
910+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
852− putVar var { db, index, store }
911+ AVar.put { db, index, store } var
853−
912+
854− var <- makeVar
913+ var <- AVar.empty
855− db <- IDBFactory.open "db" Nothing
914+ db <- IDBFactory.open "db" Nothing
856− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
915+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
857− , onBlocked : Nothing
916+ , onBlocked: Nothing
858 }
917 }
859− takeVar var
918+ AVar.take var
860−
919+
861− it "continue() - iterate to the next record" do
920+ it "continue() - iterate to the next record" do
862− { db } <- setup
921+ { db } <- setup
863− { storeParams : IDBDatabase.defaultParameters
922+ { storeParams: IDBDatabase.defaultParameters
864− , indexParams : IDBObjectStore.defaultParameters
923+ , indexParams: IDBObjectStore.defaultParameters
865− , keyPath : []
924+ , keyPath: []
925+ , values:
866− , values : [ "cupcake" :+: (Just $ toKey 4)
926+ [ "cupcake" :+: (Just $ toKey 4)
867− , "pancake" :+: (Just $ toKey 2)
927+ , "pancake" :+: (Just $ toKey 2)
868− , "pie" :+: (Just $ toKey 1)
928+ , "pie" :+: (Just $ toKey 1)
869− , "pie" :+: (Just $ toKey 3)
929+ , "pie" :+: (Just $ toKey 3)
870− ]
930+ ]
871− , onUpgradeNeeded: Nothing
931+ , onUpgradeNeeded: Nothing
872− }
932+ }
933+ let
873− let cb vdone vvals =
934+ cb vdone vvals =
874 { onComplete: launchAff' do
935 { onComplete: launchAff' do
875− putVar vdone unit
936+ AVar.put unit vdone
876
937
877− , onError: \error -> launchAff' do
938+ , onError: \error -> launchAff' do
878 fail $ "unexpected error: " <> show error
939 fail $ "unexpected error: " <> show error
879
940
880 , onSuccess: \cursor -> launchAff' do
941 , onSuccess: \cursor -> launchAff' do
881− vals <- takeVar vvals
942+ vals <- AVar.take vvals
882 pure (IDBCursor.value cursor) >>= shouldEqual (maybe "" _.v $ head vals)
943 pure (IDBCursor.value cursor) >>= shouldEqual (maybe "" _.v $ head vals)
883− IDBCursor.primaryKey cursor >>= shouldEqual (maybe (toKey 0) _.k $ head vals)
944+ IDBCursor.primaryKey cursor >>= shouldEqual (maybe (toKey 0) _.k $ head vals)
884− putVar vvals (drop 1 vals)
945+ AVar.put (drop 1 vals) vvals
885 IDBCursor.continue cursor none
946 IDBCursor.continue cursor none
886 }
947 }
887− vdone <- makeVar
948+ vdone <- AVar.empty
888− vvals <- makeVar'
949+ vvals <- AVar.new
889− [ { v: "pie" , k: toKey 1 }
950+ [ { v: "pie", k: toKey 1 }
890− , { v: "pancake", k: toKey 2 }
951+ , { v: "pancake", k: toKey 2 }
891− , { v: "pie" , k: toKey 3 }
952+ , { v: "pie", k: toKey 3 }
892− , { v: "cupcake", k: toKey 4 }
953+ , { v: "cupcake", k: toKey 4 }
893− ]
954+ ]
894− tx <- IDBDatabase.transaction db ["store"] ReadOnly
955+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
895− store <- IDBTransaction.objectStore tx "store"
956+ store <- IDBTransaction.objectStore tx "store"
896− IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
957+ IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
897− takeVar vdone
958+ AVar.take vdone
898− tearDown db
959+ tearDown db
899−
960+
900− it "continue() - attempt to iterate in the wrong direction" do
961+ it "continue() - attempt to iterate in the wrong direction" do
901− { db } <- setup
962+ { db } <- setup
902− { storeParams : IDBDatabase.defaultParameters
963+ { storeParams: IDBDatabase.defaultParameters
903− , indexParams : IDBObjectStore.defaultParameters
964+ , indexParams: IDBObjectStore.defaultParameters
904− , keyPath : []
965+ , keyPath: []
966+ , values:
905− , values : [ "cupcake" :+: (Just $ toKey 4)
967+ [ "cupcake" :+: (Just $ toKey 4)
906− , "pancake" :+: (Just $ toKey 2)
968+ , "pancake" :+: (Just $ toKey 2)
907− , "pie" :+: (Just $ toKey 1)
969+ , "pie" :+: (Just $ toKey 1)
908− , "pie" :+: (Just $ toKey 3)
970+ , "pie" :+: (Just $ toKey 3)
909− ]
971+ ]
910− , onUpgradeNeeded: Nothing
972+ , onUpgradeNeeded: Nothing
911− }
973+ }
974+ let
912− let cb vdone =
975+ cb vdone =
913 { onComplete: launchAff' do
976 { onComplete: launchAff' do
914 fail $ "shouldn't complete"
977 fail $ "shouldn't complete"
915
978
916− , onError: \error -> launchAff' do
979+ , onError: \error -> launchAff' do
917 fail $ "unexpected error: " <> show error
980 fail $ "unexpected error: " <> show error
918
981
919 , onSuccess: \cursor -> launchAff' do
982 , onSuccess: \cursor -> launchAff' do
920 res <- attempt $ IDBCursor.continue cursor (Just 1)
983 res <- attempt $ IDBCursor.continue cursor (Just 1)
921 case res of
984 case res of
922− Left err -> do
985+ Left err -> do
923− message err `shouldEqual` "DataError"
986+ name err `shouldEqual` "DataError"
924− putVar vdone unit
987+ AVar.put unit vdone
925 Right _ -> do
988 Right _ -> do
926 fail "expected continue to fail"
989 fail "expected continue to fail"
927 }
990 }
928− vdone <- makeVar
991+ vdone <- AVar.empty
929− tx <- IDBDatabase.transaction db ["store"] ReadOnly
992+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
930− store <- IDBTransaction.objectStore tx "store"
993+ store <- IDBTransaction.objectStore tx "store"
931− IDBObjectStore.openCursor store Nothing Next (cb vdone)
994+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
932− takeVar vdone
995+ AVar.take vdone
933− tearDown db
996+ tearDown db
934−
997+
935−
936− it "advance() - iterate cursor number of times specified by count" do
998+ it "advance() - iterate cursor number of times specified by count" do
937− { db } <- setup
999+ { db } <- setup
938− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1000+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
939− , indexParams : IDBObjectStore.defaultParameters
1001+ , indexParams: IDBObjectStore.defaultParameters
940− , keyPath : []
1002+ , keyPath: []
1003+ , values:
941− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1004+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
942− , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1005+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
943− , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1006+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
944− , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1007+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
945− ]
1008+ ]
946− , onUpgradeNeeded: Nothing
1009+ , onUpgradeNeeded: Nothing
947− }
1010+ }
1011+ let
948− let cb vdone vjump =
1012+ cb vdone vjump =
949 { onComplete: launchAff' do
1013 { onComplete: launchAff' do
950− putVar vdone unit
1014+ AVar.put unit vdone
951
1015
952− , onError: \error -> launchAff' do
1016+ , onError: \error -> launchAff' do
953 fail $ "unexpected error: " <> show error
1017 fail $ "unexpected error: " <> show error
954
1018
955 , onSuccess: \cursor -> launchAff' do
1019 , onSuccess: \cursor -> launchAff' do
956− jump <- takeVar vjump
1020+ jump <- AVar.take vjump
957− if jump
1021+ if jump then do
958− then do
959− IDBCursor.advance cursor 3
1022+ IDBCursor.advance cursor 3
960− else do
1023+ else do
961− let value = IDBCursor.value cursor
1024+ let value = IDBCursor.value cursor
962− value.pKey `shouldEqual` "pkey_3"
1025+ value.pKey `shouldEqual` "pkey_3"
963− value.iKey `shouldEqual` "ikey_3"
1026+ value.iKey `shouldEqual` "ikey_3"
964− IDBCursor.continue cursor none
1027+ IDBCursor.continue cursor none
965− putVar vjump false
1028+ AVar.put false vjump
966 }
1029 }
967− vdone <- makeVar
1030+ vdone <- AVar.empty
968− vjump <- makeVar' true
1031+ vjump <- AVar.new true
969− tx <- IDBDatabase.transaction db ["store"] ReadOnly
1032+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
970− store <- IDBTransaction.objectStore tx "store"
1033+ store <- IDBTransaction.objectStore tx "store"
971− IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
1034+ IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
972− takeVar vdone
1035+ AVar.take vdone
973− tearDown db
1036+ tearDown db
974−
1037+
975− it "delete() - remove a record from the object store" do
1038+ it "delete() - remove a record from the object store" do
976− { db } <- setup
1039+ { db } <- setup
977− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1040+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
978− , indexParams : IDBObjectStore.defaultParameters
1041+ , indexParams: IDBObjectStore.defaultParameters
979− , keyPath : []
1042+ , keyPath: []
1043+ , values:
980− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1044+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
981− , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1045+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
982− , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1046+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
983− , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1047+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
984− ]
1048+ ]
985− , onUpgradeNeeded: Nothing
1049+ , onUpgradeNeeded: Nothing
986− }
1050+ }
1051+ let
987− let cb vdone store =
1052+ cb vdone store =
988 { onComplete: launchAff' do
1053 { onComplete: launchAff' do
989 mval <- map _.pKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
1054 mval <- map _.pKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
990 mval `shouldEqual` (Nothing :: Maybe String)
1055 mval `shouldEqual` (Nothing :: Maybe String)
991− putVar vdone unit
1056+ AVar.put unit vdone
992
1057
993− , onError: \error -> launchAff' do
1058+ , onError: \error -> launchAff' do
994 fail $ "unexpected error: " <> show error
1059 fail $ "unexpected error: " <> show error
995
1060
996 , onSuccess: \cursor -> launchAff' do
1061 , onSuccess: \cursor -> launchAff' do
@@ -999,29 +1064,31 @@ main = runMocha do
999 IDBCursor.delete cursor
1064 IDBCursor.delete cursor
1000 IDBCursor.advance cursor 4
1065 IDBCursor.advance cursor 4
1001 }
1066 }
1002− vdone <- makeVar
1067+ vdone <- AVar.empty
1003− tx <- IDBDatabase.transaction db ["store"] ReadWrite
1068+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1004− store <- IDBTransaction.objectStore tx "store"
1069+ store <- IDBTransaction.objectStore tx "store"
1005− IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1070+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1006− takeVar vdone
1071+ AVar.take vdone
1007− tearDown db
1072+ tearDown db
1008−
1073+
1009− it "update() - modify a record in the object store" do
1074+ it "update() - modify a record in the object store" do
1010− { db } <- setup
1075+ { db } <- setup
1011− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1076+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1012− , indexParams : IDBObjectStore.defaultParameters
1077+ , indexParams: IDBObjectStore.defaultParameters
1013− , keyPath : []
1078+ , keyPath: []
1079+ , values:
1014− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1080+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1015− ]
1081+ ]
1016− , onUpgradeNeeded: Nothing
1082+ , onUpgradeNeeded: Nothing
1017− }
1083+ }
1084+ let
1018− let cb vdone store =
1085+ cb vdone store =
1019 { onComplete: launchAff' do
1086 { onComplete: launchAff' do
1020 mval <- map _.iKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
1087 mval <- map _.iKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
1021 mval `shouldEqual` (Just "patate")
1088 mval `shouldEqual` (Just "patate")
1022− putVar vdone unit
1089+ AVar.put unit vdone
1023
1090
1024− , onError: \error -> launchAff' do
1091+ , onError: \error -> launchAff' do
1025 fail $ "unexpected error: " <> show error
1092 fail $ "unexpected error: " <> show error
1026
1093
1027 , onSuccess: \cursor -> launchAff' do
1094 , onSuccess: \cursor -> launchAff' do
@@ -1031,41 +1098,44 @@ main = runMocha do
1031 key `shouldEqual` toKey "pkey_0"
1098 key `shouldEqual` toKey "pkey_0"
1032 IDBCursor.advance cursor 4
1099 IDBCursor.advance cursor 4
1033 }
1100 }
1034− vdone <- makeVar
1101+ vdone <- AVar.empty
1035− tx <- IDBDatabase.transaction db ["store"] ReadWrite
1102+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1036− store <- IDBTransaction.objectStore tx "store"
1103+ store <- IDBTransaction.objectStore tx "store"
1037− IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1104+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1038− takeVar vdone
1105+ AVar.take vdone
1039− tearDown db
1106+ tearDown db
1040−
1107+
1041− it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1108+ it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1042− { db } <- setup
1109+ { db } <- setup
1043− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1110+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1044− , indexParams : IDBObjectStore.defaultParameters
1111+ , indexParams: IDBObjectStore.defaultParameters
1045− , keyPath : []
1112+ , keyPath: []
1113+ , values:
1046− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1114+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1047− ]
1115+ ]
1048− , onUpgradeNeeded: Nothing
1116+ , onUpgradeNeeded: Nothing
1049− }
1117+ }
1118+ let
1050− let cb vdone =
1119+ cb vdone =
1051 { onComplete: launchAff' do
1120 { onComplete: launchAff' do
1052 fail $ "shouldn't complete"
1121 fail $ "shouldn't complete"
1053
1122
1054− , onError: \error -> launchAff' do
1123+ , onError: \error -> launchAff' do
1055 fail $ "unexpected error: " <> show error
1124 fail $ "unexpected error: " <> show error
1056
1125
1057 , onSuccess: \cursor -> launchAff' do
1126 , onSuccess: \cursor -> launchAff' do
1058 res <- attempt $ IDBCursor.update cursor "patate"
1127 res <- attempt $ IDBCursor.update cursor "patate"
1059 case res of
1128 case res of
1060 Left err -> do
1129 Left err -> do
1061− message err `shouldEqual` "ReadOnlyError"
1130+ name err `shouldEqual` "ReadOnlyError"
1062− putVar vdone unit
1131+ AVar.put unit vdone
1063 Right _ ->
1132 Right _ ->
1064 fail $ "expected ReadOnlyError"
1133 fail $ "expected ReadOnlyError"
1065 }
1134 }
1066− vdone <- makeVar
1135+ vdone <- AVar.empty
1067− tx <- IDBDatabase.transaction db ["store"] ReadOnly
1136+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
1068− store <- IDBTransaction.objectStore tx "store"
1137+ store <- IDBTransaction.objectStore tx "store"
1069− IDBObjectStore.openCursor store Nothing Next (cb vdone)
1138+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
1070− takeVar vdone
1139+ AVar.take vdone
1071− tearDown db
1140+ tearDown db
1141+
yarn.locknew file+81
@@ -0,0 +1,81 @@
1+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+# yarn lockfile v1
3+
4+
5+base64-arraybuffer-es6@^0.7.0:
6+ version "0.7.0"
7+ resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.7.0.tgz#dbe1e6c87b1bf1ca2875904461a7de40f21abc86"
8+ integrity sha512-ESyU/U1CFZDJUdr+neHRhNozeCv72Y7Vm0m1DCbjX3KBjT6eYocvAJlSk6+8+HkVwXlT1FNxhGW6q3UKAlCvvw==
9+
10+domexception@^1.0.1:
11+ version "1.0.1"
12+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
13+ integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
14+ dependencies:
15+ webidl-conversions "^4.0.2"
16+
17+fake-indexeddb@^4.0.1:
18+ version "4.0.1"
19+ resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-4.0.1.tgz#09bb2468e21d0832b2177e894765fb109edac8fb"
20+ integrity sha512-hFRyPmvEZILYgdcLBxVdHLik4Tj3gDTu/g7s9ZDOiU3sTNiGx+vEu1ri/AMsFJUZ/1sdRbAVrEcKndh3sViBcA==
21+ dependencies:
22+ realistic-structured-clone "^3.0.0"
23+
24+lodash@^4.7.0:
25+ version "4.17.21"
26+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
27+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
28+
29+punycode@^2.1.1:
30+ version "2.3.0"
31+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
32+ integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
33+
34+realistic-structured-clone@^3.0.0:
35+ version "3.0.0"
36+ resolved "https://registry.yarnpkg.com/realistic-structured-clone/-/realistic-structured-clone-3.0.0.tgz#7b518049ce2dad41ac32b421cd297075b00e3e35"
37+ integrity sha512-rOjh4nuWkAqf9PWu6JVpOWD4ndI+JHfgiZeMmujYcPi+fvILUu7g6l26TC1K5aBIp34nV+jE1cDO75EKOfHC5Q==
38+ dependencies:
39+ domexception "^1.0.1"
40+ typeson "^6.1.0"
41+ typeson-registry "^1.0.0-alpha.20"
42+
43+tr46@^2.1.0:
44+ version "2.1.0"
45+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
46+ integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==
47+ dependencies:
48+ punycode "^2.1.1"
49+
50+typeson-registry@^1.0.0-alpha.20:
51+ version "1.0.0-alpha.39"
52+ resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.39.tgz#9e0f5aabd5eebfcffd65a796487541196f4b1211"
53+ integrity sha512-NeGDEquhw+yfwNhguLPcZ9Oj0fzbADiX4R0WxvoY8nGhy98IbzQy1sezjoEFWOywOboj/DWehI+/aUlRVrJnnw==
54+ dependencies:
55+ base64-arraybuffer-es6 "^0.7.0"
56+ typeson "^6.0.0"
57+ whatwg-url "^8.4.0"
58+
59+typeson@^6.0.0, typeson@^6.1.0:
60+ version "6.1.0"
61+ resolved "https://registry.yarnpkg.com/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b"
62+ integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA==
63+
64+webidl-conversions@^4.0.2:
65+ version "4.0.2"
66+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
67+ integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
68+
69+webidl-conversions@^6.1.0:
70+ version "6.1.0"
71+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
72+ integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
73+
74+whatwg-url@^8.4.0:
75+ version "8.7.0"
76+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
77+ integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
78+ dependencies:
79+ lodash "^4.7.0"
80+ tr46 "^2.1.0"
81+ webidl-conversions "^6.1.0"