git.iko.soy/purescript-indexed-DB
on master help sign in
29 files changed+1776−1856
since splitsnapshots
unifiedsplit
.gitignore+2 bower.json−44 deploy.sh−6 index.js+4 karma.browserstack.conf.js−91 karma.conf.js−25 package.json+10−37 packages.dhall+105 spago.dhall+42 src/Database/IndexedDB/Core.js+6−6 src/Database/IndexedDB/Core.purs+21−74 src/Database/IndexedDB/IDBCursor.js+10−10 src/Database/IndexedDB/IDBCursor.purs+75−85 src/Database/IndexedDB/IDBDatabase.js+11−11 src/Database/IndexedDB/IDBDatabase.purs+73−98 src/Database/IndexedDB/IDBFactory.js+2−2 src/Database/IndexedDB/IDBFactory.purs+22−33 src/Database/IndexedDB/IDBIndex.js+12−12 src/Database/IndexedDB/IDBIndex.purs+78−96 src/Database/IndexedDB/IDBKey/Internal.js+3−3 src/Database/IndexedDB/IDBKey/Internal.purs+90−106 src/Database/IndexedDB/IDBKeyRange.js+9−9 src/Database/IndexedDB/IDBKeyRange.purs+30−42 src/Database/IndexedDB/IDBObjectStore.js+12−12 src/Database/IndexedDB/IDBObjectStore.purs+58−76 src/Database/IndexedDB/IDBTransaction.js+9−9 src/Database/IndexedDB/IDBTransaction.purs+40−59 test/Main.purs+971−910 yarn.lock+81
.gitignore+2
@@ -77,3 +77,5 @@ releases
7777.purs*
7878.psa*
7979dist
80+.spago
81+test.js
bower.jsondeleted−44
@@ -1,44 +0,0 @@
1−{
2− "name": "purescript-indexeddb",
3− "description": "An API wrapper around IndexedDB",
4− "version": "4.0.0",
5− "authors": [
6− "Matthias Benkort <matthias.benkort@gmail.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": "^4.0.2",
29− "purescript-datetime": "^3.2.0",
30− "purescript-eff": "^3.1.0",
31− "purescript-exceptions": "^3.0.0",
32− "purescript-foreign": "^4.0.1",
33− "purescript-maybe": "^3.0.0",
34− "purescript-nullable": "^3.0.0",
35− "purescript-prelude": "^3.1.0",
36− "purescript-read": "^1.0.0"
37− },
38− "devDependencies": {
39− "purescript-now": "^3.0.0",
40− "purescript-psci-support": "^3.0.0",
41− "purescript-spec": "^2.0.0",
42− "purescript-spec-mocha": "^2.0.0"
43− }
44−}
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", "Firefox"],
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+10−37
@@ -1,42 +1,15 @@
11{
2− "name": "purescript-indexeddb",
3− "version": "3.0.0",
4− "description": "A wrapper around the IndexedDB API",
2+ "name": "purescript-indexed-DB",
3+ "version": "1.0.0",
4+ "main": "index.js",
5+ "repository": "https://github.com/ilyakooo0/purescript-indexed-DB.git",
6+ "author": "iko <mail@iko.soy>",
7+ "license": "MIT",
58 "scripts": {
6− "prepare:release": "mkdir -p releases/github && cp -r README.md LICENSE src bower.json releases/github",
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"
9+ "test": "spago build && node index.js"
3110 },
32− "repository": {
33− "type": "git",
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"
11+ "dependencies": {
12+ "fake-indexeddb": "^4.0.1"
4013 },
41− "homepage": "https://github.com/Truqu/purescript-indexeddb#readme"
14+ "type": "module"
4215}
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) {
33};
44
55
6−exports._showCursor = function _showCursor(cursor) {
6+export function _showCursor(cursor) {
77 return '(IDBCursor ' +
88 '{ direction: ' + cursor.direction +
99 ', key: ' + cursor.key +
@@ -11,7 +11,7 @@ exports._showCursor = function _showCursor(cursor) {
1111 ' })';
1212};
1313
14−exports._showDatabase = function _showDatabase(db) {
14+export function _showDatabase(db) {
1515 return '(IDBDatabase ' +
1616 '{ name: ' + db.name +
1717 ', objectStoreNames: [' + toArray(db.objectStoreNames).join(', ') + ']' +
@@ -19,7 +19,7 @@ exports._showDatabase = function _showDatabase(db) {
1919 ' })';
2020};
2121
22−exports._showIndex = function _showIndex(index) {
22+export function _showIndex(index) {
2323 return '(IDBIndex ' +
2424 '{ name: ' + index.name +
2525 ', keyPath: ' + index.keyPath +
@@ -28,7 +28,7 @@ exports._showIndex = function _showIndex(index) {
2828 ' })';
2929};
3030
31−exports._showKeyRange = function _showKeyRange(range) {
31+export function _showKeyRange(range) {
3232 return '(IDBKeyRange ' +
3333 '{ lower: ' + range.lower +
3434 ', upper: ' + range.upper +
@@ -37,7 +37,7 @@ exports._showKeyRange = function _showKeyRange(range) {
3737 ' })';
3838};
3939
40−exports._showObjectStore = function _showObjectStore(store) {
40+export function _showObjectStore(store) {
4141 return '(IDBObjectStore ' +
4242 '{ autoIncrement: ' + store.autoIncrement +
4343 ', indexNames: [' + toArray(store.indexNames).join(', ') + ']' +
@@ -46,7 +46,7 @@ exports._showObjectStore = function _showObjectStore(store) {
4646 ' })';
4747};
4848
49−exports._showTransaction = function _showTransaction(tx) {
49+export function _showTransaction(tx) {
5050 return '(IDBTransaction ' +
5151 '{ error: ' + tx.error +
5252 ', mode: ' + tx.mode +
src/Database/IndexedDB/Core.purs+21−74
@@ -2,10 +2,11 @@
22-- | those types.
33module Database.IndexedDB.Core
44 -- * Effects
5− ( IDB
5+ (
6+ -- IDB
67
7− -- * Types
8− , Database
8+ -- * Types
9+ Database
910 , Index
1011 , KeyCursor
1112 , KeyRange
@@ -30,23 +31,13 @@ module Database.IndexedDB.Core
3031 , module Database.IndexedDB.IDBKey
3132 ) where
3233
33−import Prelude (class Show)
34+import Prelude (class Show)
3435
35−import Control.Monad.Eff (kind Effect)
36−import Data.Maybe (Maybe(..))
37−import Data.String.Read (class Read)
36+import Data.Maybe (Maybe(..))
37+import Data.String.Read (class Read)
3838
3939import Database.IndexedDB.IDBKey
4040
41−
42−--------------------
43−-- Effects
44−--
45−
46−-- | IDB Effects, manifestation that something happened with the IndexedDB
47−foreign import data IDB :: Effect
48−
49−
5041--------------------
5142-- TYPES
5243--
@@ -55,35 +46,28 @@ foreign import data IDB :: Effect
5546-- | stores which hold the data stored in the database.
5647foreign import data Database :: Type
5748
58−
5949-- | An index allows looking up records in an object store using properties of the values
6050-- | in the object stores records.
6151foreign import data Index :: Type
6252
63−
6453-- | A key range is a continuous interval over some data type used for keys.
6554foreign import data KeyRange :: Type
6655
67−
6856-- | A cursor is used to iterate over a range of records in an index or an object store
6957-- | in a specific direction. A KeyCursor doesn't hold any value.
7058foreign import data KeyCursor :: Type
7159
72−
7360-- | A Transaction is used to interact with the data in a database.
7461-- | Whenever data is read or written to the database it is done by using a transaction.
7562foreign import data Transaction :: Type
7663
77−
7864-- | An object store is the primary storage mechanism for storing data in a database.
7965foreign import data ObjectStore :: Type
8066
81−
8267-- | A cursor is used to iterate over a range of records in an index or an object store
8368-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
8469foreign import data ValueCursor :: Type
8570
86−
8771-- | A cursor has a direction that determines whether it moves in monotonically
8872-- | increasing or decreasing order of the record keys when iterated, and if it
8973-- | skips duplicated values when iterating indexes.
@@ -95,7 +79,6 @@ data CursorDirection
9579 | Prev
9680 | PrevUnique
9781
98−
9982-- | If the source of a cursor is an object store, the effective object store of
10083-- | the cursor is that object store and the effective key of the cursor is the
10184-- | cursor’s position. If the source of a cursor is an index, the effective object
@@ -105,7 +88,6 @@ data CursorSource
10588 = ObjectStore ObjectStore
10689 | Index Index
10790
108−
10991-- | A key path is a list of strings that defines how to extract a key from a value.
11092-- | A valid key path is one of:
11193-- |
@@ -115,15 +97,13 @@ data CursorSource
11597-- | - A non-empty list containing only strings conforming to the above requirements.
11698type KeyPath = Array String
11799
118−
119100-- | A transaction has a mode that determines which types of interactions can be performed
120101-- | upon that transaction. The mode is set when the transaction is created and remains
121102-- | fixed for the life of the transaction.
122103data TransactionMode
123− = ReadOnly -- ^ The transaction is only allowed to read data.
124− | ReadWrite -- ^ The transaction is allowed to read, modify and delete data from existing object stores
125− | 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.
126−
104+ = ReadOnly -- ^ The transaction is only allowed to read data.
105+ | ReadWrite -- ^ The transaction is allowed to read, modify and delete data from existing object stores
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.
127107
128108--------------------
129109-- Classes
@@ -133,132 +113,104 @@ data TransactionMode
133113-- | specific attributes (see KeyCursor or CursorWithValue).
134114class (IDBCursor cursor) <= IDBConcreteCursor cursor
135115
136−
137116-- | Cursor objects implement the IDBCursor interface.
138117-- | There is only ever one IDBCursor instance representing a given cursor.
139118-- | There is no limit on how many cursors can be used at the same time.
140119class IDBCursor cursor
141120
142−
143121-- | The IDBDatabase interface represents a connection to a database.
144122class IDBDatabase db
145123
146−
147124-- | The IDBIndex interface represents an index handle.
148125-- | Any of these methods throw an "TransactionInactiveError" DOMException
149126-- | if called when the transaction is not active.
150127class IDBIndex index
151128
152−
153129-- | The IDBKeyRange interface represents a key range.
154130class IDBKeyRange range
155131
156−
157132-- | The IDBtransaction interface.
158133class IDBTransaction tx
159134
160−
161135-- | The IDBObjectStore interface represents an object store handle.
162136class IDBObjectStore store
163137
164−
165138--------------------
166139-- INSTANCES
167140--
168141
169142instance idbCursorKeyCursor :: IDBCursor KeyCursor
170143
171−
172144instance idbCursorValueCursor :: IDBCursor ValueCursor
173145
174−
175146instance idbConcreteCursorKeyCursor :: IDBConcreteCursor KeyCursor
176147
177−
178148instance idbConcreteCursorValueCursor :: IDBConcreteCursor ValueCursor
179149
180−
181150instance idbDatabaseDatabase :: IDBDatabase Database
182151
183−
184152instance idbIndexIndex :: IDBIndex Index
185153
186−
187154instance idbIndexObjectStore :: IDBIndex ObjectStore
188155
189−
190156instance idbKeyRangeKeyRange :: IDBKeyRange KeyRange
191157
192−
193158instance idbObjectStoreObjectStore :: IDBObjectStore ObjectStore
194159
195−
196160instance idbTransactionTransaction :: IDBTransaction Transaction
197161
198−
199162instance showKeyCursor :: Show KeyCursor where
200163 show = _showCursor
201164
202−
203165instance showValueCursor :: Show ValueCursor where
204166 show = _showCursor
205167
206−
207168instance showIndex :: Show Index where
208169 show = _showIndex
209170
210−
211171instance showKeyRange :: Show KeyRange where
212172 show = _showKeyRange
213173
214−
215174instance showObjectStore :: Show ObjectStore where
216175 show = _showObjectStore
217176
218−
219177instance showTransaction :: Show Transaction where
220178 show = _showTransaction
221179
222−
223180instance showDatabase :: Show Database where
224181 show = _showDatabase
225182
226−
227183instance showCursorDirection :: Show CursorDirection where
228184 show x =
229185 case x of
230− Next -> "next"
186+ Next -> "next"
231187 NextUnique -> "nextunique"
232− Prev -> "prev"
188+ Prev -> "prev"
233189 PrevUnique -> "prevunique"
234190
235−
236191instance showTransactionMode :: Show TransactionMode where
237192 show x =
238193 case x of
239− ReadOnly -> "readonly"
240− ReadWrite -> "readwrite"
194+ ReadOnly -> "readonly"
195+ ReadWrite -> "readwrite"
241196 VersionChange -> "versionchange"
242197
243−
244198instance readCursorDirection :: Read CursorDirection where
245199 read s =
246200 case s of
247− "next" -> Just Next
201+ "next" -> Just Next
248202 "nextunique" -> Just NextUnique
249− "prev" -> Just Prev
203+ "prev" -> Just Prev
250204 "prevunique" -> Just PrevUnique
251− _ -> Nothing
252−
205+ _ -> Nothing
253206
254207instance readTransactionMode :: Read TransactionMode where
255208 read s =
256209 case s of
257− "readonly" -> Just ReadOnly
258− "readwrite" -> Just ReadWrite
210+ "readonly" -> Just ReadOnly
211+ "readwrite" -> Just ReadWrite
259212 "versionchange" -> Just VersionChange
260− _ -> Nothing
261−
213+ _ -> Nothing
262214
263215--------------------
264216-- FFI
@@ -266,30 +218,25 @@ instance readTransactionMode :: Read TransactionMode where
266218
267219foreign import _showCursor
268220 :: forall cursor
269− . cursor
221+ . cursor
270222 -> String
271223
272−
273224foreign import _showDatabase
274225 :: Database
275226 -> String
276227
277−
278228foreign import _showIndex
279229 :: Index
280230 -> String
281231
282−
283232foreign import _showKeyRange
284233 :: KeyRange
285234 -> String
286235
287−
288236foreign import _showObjectStore
289237 :: ObjectStore
290238 -> String
291239
292−
293240foreign import _showTransaction
294241 :: Transaction
295242 -> String
src/Database/IndexedDB/IDBCursor.js+10−10
@@ -10,7 +10,7 @@ const successHandler = function successHandler(cb) {
1010 };
1111};
1212
13−exports._advance = function _advance(cursor, count) {
13+export function _advance(cursor, count) {
1414 return function aff(error, success) {
1515 try {
1616 cursor.advance(count);
@@ -25,7 +25,7 @@ exports._advance = function _advance(cursor, count) {
2525 };
2626};
2727
28−exports._continue = function _continue(cursor, key) {
28+export function _continue(cursor, key) {
2929 return function aff(error, success) {
3030 try {
3131 cursor.continue(key || undefined);
@@ -40,7 +40,7 @@ exports._continue = function _continue(cursor, key) {
4040 };
4141};
4242
43−exports._continuePrimaryKey = function _continuePrimaryKey(cursor, key, primaryKey) {
43+export function _continuePrimaryKey(cursor, key, primaryKey) {
4444 return function aff(error, success) {
4545 try {
4646 cursor.continuePrimaryKey(key, primaryKey);
@@ -55,7 +55,7 @@ exports._continuePrimaryKey = function _continuePrimaryKey(cursor, key, primaryK
5555 };
5656};
5757
58−exports._delete = function _delete(cursor) {
58+export function _delete(cursor) {
5959 return function aff(error, success) {
6060 try {
6161 const request = cursor.delete();
@@ -71,11 +71,11 @@ exports._delete = function _delete(cursor) {
7171 };
7272};
7373
74−exports._direction = function _direction(fromString, cursor) {
74+export function _direction(fromString, cursor) {
7575 return fromString(cursor.direction);
7676};
7777
78−exports._key = function _key(cursor) {
78+export function _key(cursor) {
7979 return function aff(error, success) {
8080 try {
8181 success(cursor.key);
@@ -89,7 +89,7 @@ exports._key = function _key(cursor) {
8989 };
9090};
9191
92−exports._primaryKey = function _primaryKey(cursor) {
92+export function _primaryKey(cursor) {
9393 return function aff(error, success) {
9494 try {
9595 success(cursor.primaryKey);
@@ -103,7 +103,7 @@ exports._primaryKey = function _primaryKey(cursor) {
103103 };
104104};
105105
106−exports._source = function _source(IDBObjectStore, IDBIndex, cursor) {
106+export function _source(IDBObjectStore, IDBIndex, cursor) {
107107 switch (cursor.source.constructor.name) {
108108 case 'IDBIndex':
109109 return IDBIndex(cursor.source);
@@ -123,7 +123,7 @@ exports._source = function _source(IDBObjectStore, IDBIndex, cursor) {
123123 }
124124};
125125
126−exports._update = function _update(cursor, value) {
126+export function _update(cursor, value) {
127127 return function aff(error, success) {
128128 try {
129129 const request = cursor.update(value);
@@ -139,6 +139,6 @@ exports._update = function _update(cursor, value) {
139139 };
140140};
141141
142−exports._value = function _value(cursor) {
142+export function _value(cursor) {
143143 return cursor.value;
144144};
src/Database/IndexedDB/IDBCursor.purs+75−85
@@ -16,20 +16,18 @@ module Database.IndexedDB.IDBCursor
1616 , value
1717 ) where
1818
19−import Prelude (Unit, ($), (>>>), (<<<), map)
20−
21−import Control.Monad.Aff (Aff)
22−import Control.Monad.Aff.Compat (fromEffFnAff, EffFnAff)
23−import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
24−import Data.Function.Uncurried as Fn
25−import Data.Function.Uncurried (Fn2, Fn3)
26−import Data.Maybe (Maybe)
27−import Data.Nullable (Nullable, toNullable)
28−import Data.String.Read (read)
29−
3019import Database.IndexedDB.Core
31−import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromKey)
3220
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)
3331
3432--------------------
3533-- INTERFACES
@@ -37,56 +35,58 @@ import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromK
3735
3836-- | Advances the cursor through the next count records in range.
3937advance
40− :: forall e cursor. (IDBCursor cursor)
41− => cursor
42− -> Int
43− -> Aff (idb :: IDB | e) Unit
38+ :: forall cursor
39+ . (IDBCursor cursor)
40+ => cursor
41+ -> Int
42+ -> Aff Unit
4443advance c =
45− fromEffFnAff <<< Fn.runFn2 _advance c
46−
44+ fromEffectFnAff <<< Fn.runFn2 _advance c
4745
4846-- | Advances the cursor to the next record in range matching or after key.
4947continue
50− :: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
51− => cursor
52− -> Maybe k
53− -> Aff (idb :: IDB | e) Unit
48+ :: forall k cursor
49+ . (IDBKey k)
50+ => (IDBCursor cursor)
51+ => cursor
52+ -> Maybe k
53+ -> Aff Unit
5454continue c mk =
55− fromEffFnAff $ Fn.runFn2 _continue c (toNullable $ map (toKey >>> unsafeFromKey) mk)
56−
55+ fromEffectFnAff $ Fn.runFn2 _continue c (toNullable $ map (toKey >>> unsafeFromKey) mk)
5756
5857-- | 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.
5958continuePrimaryKey
60− :: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
61− => cursor
62− -> k
63− -> k
64− -> Aff (idb :: IDB | e) Unit
59+ :: forall k cursor
60+ . (IDBKey k)
61+ => (IDBCursor cursor)
62+ => cursor
63+ -> k
64+ -> k
65+ -> Aff Unit
6566continuePrimaryKey c k1 k2 =
66− fromEffFnAff $ Fn.runFn3 _continuePrimaryKey c (unsafeFromKey $ toKey k1) (unsafeFromKey $ toKey k2)
67−
67+ fromEffectFnAff $ Fn.runFn3 _continuePrimaryKey c (unsafeFromKey $ toKey k1) (unsafeFromKey $ toKey k2)
6868
6969-- | Delete the record pointed at by the cursor with a new value.
7070delete
71− :: forall e cursor. (IDBCursor cursor)
72− => cursor
73− -> Aff (idb :: IDB | e) Unit
71+ :: forall cursor
72+ . (IDBCursor cursor)
73+ => cursor
74+ -> Aff Unit
7475delete =
75− fromEffFnAff <<< _delete
76−
76+ fromEffectFnAff <<< _delete
7777
7878-- | Update the record pointed at by the cursor with a new value.
7979-- |
8080-- | Throws a "DataError" DOMException if the effective object store uses
8181-- | in-line keys and the key would have changed.
8282update
83− :: forall val e cursor. (IDBCursor cursor)
84− => cursor
85− -> val
86− -> Aff (idb :: IDB | e) Key
83+ :: forall val cursor
84+ . (IDBCursor cursor)
85+ => cursor
86+ -> val
87+ -> Aff Key
8788update c =
88− map toKey <<< fromEffFnAff <<< Fn.runFn2 _update c <<< toForeign
89−
89+ map toKey <<< fromEffectFnAff <<< Fn.runFn2 _update c <<< unsafeToForeign
9090
9191--------------------
9292-- ATTRIBUTES
@@ -94,103 +94,93 @@ update c =
9494
9595-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
9696direction
97− :: forall cursor. (IDBConcreteCursor cursor)
97+ :: forall cursor
98+ . (IDBConcreteCursor cursor)
9899 => cursor
99100 -> CursorDirection
100101direction =
101102 Fn.runFn2 _direction (read >>> toNullable)
102103
103−
104104-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
105105-- | if the cursor is advancing or is finished.
106106key
107− :: forall e cursor. (IDBConcreteCursor cursor)
107+ :: forall cursor
108+ . (IDBConcreteCursor cursor)
108109 => cursor
109− -> Aff (idb :: IDB | e) Key
110+ -> Aff Key
110111key =
111− map toKey <<< fromEffFnAff <<< _key
112−
112+ map toKey <<< fromEffectFnAff <<< _key
113113
114114-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
115115-- | if the cursor is advancing or is finished.
116116primaryKey
117− :: forall e cursor. (IDBConcreteCursor cursor)
117+ :: forall cursor
118+ . (IDBConcreteCursor cursor)
118119 => cursor
119− -> Aff (idb :: IDB | e) Key
120+ -> Aff Key
120121primaryKey =
121− map toKey <<< fromEffFnAff <<< _primaryKey
122−
122+ map toKey <<< fromEffectFnAff <<< _primaryKey
123123
124124-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
125125source
126− :: forall cursor. (IDBConcreteCursor cursor)
126+ :: forall cursor
127+ . (IDBConcreteCursor cursor)
127128 => cursor
128129 -> CursorSource
129130source =
130131 Fn.runFn3 _source ObjectStore Index
131132
132−
133133value
134134 :: forall val
135− . ValueCursor
135+ . ValueCursor
136136 -> val
137137value =
138138 _value >>> unsafeFromForeign
139139
140−
141140--------------------
142141-- FFI
143142--
144143
145144foreign import _advance
146− :: forall cursor e
147− . Fn2 cursor Int (EffFnAff (idb :: IDB | e) Unit)
148−
145+ :: forall cursor
146+ . Fn2 cursor Int (EffectFnAff Unit)
149147
150148foreign import _continue
151− :: forall cursor e
152− . Fn2 cursor (Nullable Foreign) (EffFnAff (idb :: IDB | e) Unit)
153−
149+ :: forall cursor
150+ . Fn2 cursor (Nullable Foreign) (EffectFnAff Unit)
154151
155152foreign import _continuePrimaryKey
156− :: forall cursor e
157− . Fn3 cursor Foreign Foreign (EffFnAff (idb :: IDB | e) Unit)
158−
153+ :: forall cursor
154+ . Fn3 cursor Foreign Foreign (EffectFnAff Unit)
159155
160156foreign import _delete
161− :: forall cursor e
162− . cursor
163− -> (EffFnAff (idb :: IDB | e) Unit)
164−
157+ :: forall cursor
158+ . cursor
159+ -> (EffectFnAff Unit)
165160
166161foreign import _direction
167162 :: forall cursor
168− . Fn2 (String -> Nullable CursorDirection) cursor CursorDirection
169−
163+ . Fn2 (String -> Nullable CursorDirection) cursor CursorDirection
170164
171165foreign import _key
172− :: forall cursor e
173− . cursor
174− -> EffFnAff (idb :: IDB | e) Key
175−
166+ :: forall cursor
167+ . cursor
168+ -> EffectFnAff Key
176169
177170foreign import _primaryKey
178− :: forall cursor e
179− . cursor
180− -> EffFnAff (idb :: IDB | e) Key
181−
171+ :: forall cursor
172+ . cursor
173+ -> EffectFnAff Key
182174
183175foreign import _source
184176 :: forall cursor
185− . Fn3 (ObjectStore -> CursorSource) (Index -> CursorSource) cursor CursorSource
186−
177+ . Fn3 (ObjectStore -> CursorSource) (Index -> CursorSource) cursor CursorSource
187178
188179foreign import _update
189− :: forall cursor e
190− . Fn2 cursor Foreign (EffFnAff (idb :: IDB | e) Foreign)
191−
180+ :: forall cursor
181+ . Fn2 cursor Foreign (EffectFnAff Foreign)
192182
193183foreign import _value
194184 :: forall cursor val
195− . cursor
185+ . cursor
196186 -> val
src/Database/IndexedDB/IDBDatabase.js+11−11
@@ -3,7 +3,7 @@ const toArray = function toArray(xs) {
33};
44
55
6−exports._close = function _close(db) {
6+export function _close(db) {
77 return function aff(error, success) {
88 try {
99 db.close();
@@ -18,7 +18,7 @@ exports._close = function _close(db) {
1818 };
1919};
2020
21−exports._createObjectStore = function _createObjectStore(db, name, opts) {
21+export function _createObjectStore(db, name, opts) {
2222 return function aff(error, success) {
2323 var keyPath;
2424
@@ -52,7 +52,7 @@ exports._createObjectStore = function _createObjectStore(db, name, opts) {
5252 };
5353};
5454
55−exports._deleteObjectStore = function _deleteObjectStore(db, name) {
55+export function _deleteObjectStore(db, name) {
5656 return function aff(error, success) {
5757 try {
5858 db.deleteObjectStore(name);
@@ -67,15 +67,15 @@ exports._deleteObjectStore = function _deleteObjectStore(db, name) {
6767 };
6868};
6969
70−exports._name = function _name(db) {
70+export function _name(db) {
7171 return db.name;
7272};
7373
74−exports._objectStoreNames = function _objectStoreNames(db) {
74+export function _objectStoreNames(db) {
7575 return toArray(db.objectStoreNames);
7676};
7777
78−exports._onAbort = function _onAbort(db, f) {
78+export function _onAbort(db, f) {
7979 return function aff(error, success) {
8080 db.onabort = function onabort() {
8181 f();
@@ -88,7 +88,7 @@ exports._onAbort = function _onAbort(db, f) {
8888 };
8989};
9090
91−exports._onClose = function _onClose(db, f) {
91+export function _onClose(db, f) {
9292 return function aff(error, success) {
9393 db.onclose = function onclose() {
9494 f();
@@ -101,7 +101,7 @@ exports._onClose = function _onClose(db, f) {
101101 };
102102};
103103
104−exports._onError = function _onError(db, f) {
104+export function _onError(db, f) {
105105 return function aff(error, success) {
106106 db.onerror = function onerror(e) {
107107 f(e.target.error)();
@@ -114,7 +114,7 @@ exports._onError = function _onError(db, f) {
114114 };
115115};
116116
117−exports._onVersionChange = function _onVersionChange(db, f) {
117+export function _onVersionChange(db, f) {
118118 return function aff(error, success) {
119119 db.onversionchange = function onversionchange(e) {
120120 f({ oldVersion: e.oldVersion, newVersion: e.newVersion })();
@@ -127,7 +127,7 @@ exports._onVersionChange = function _onVersionChange(db, f) {
127127 };
128128};
129129
130−exports._transaction = function _transaction(db, stores, mode) {
130+export function _transaction(db, stores, mode) {
131131 return function aff(error, success) {
132132 var transaction;
133133 try {
@@ -144,6 +144,6 @@ exports._transaction = function _transaction(db, stores, mode) {
144144 };
145145};
146146
147−exports._version = function _version(db) {
147+export function _version(db) {
148148 return db.version;
149149};
src/Database/IndexedDB/IDBDatabase.purs+73−98
@@ -24,17 +24,15 @@ module Database.IndexedDB.IDBDatabase
2424 , onVersionChange
2525 ) where
2626
27−import Prelude (Unit, show, (<<<), ($))
28−
29−import Control.Monad.Aff (Aff)
30−import Control.Monad.Aff.Compat (fromEffFnAff, EffFnAff)
31−import Control.Monad.Eff (Eff)
32−import Control.Monad.Eff.Exception (Error)
33−import Data.Function.Uncurried as Fn
34−import Data.Function.Uncurried (Fn2, Fn3)
35−
3627import Database.IndexedDB.Core
3728
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, (<<<), ($))
3836
3937--------------------
4038-- TYPES
@@ -43,70 +41,67 @@ import Database.IndexedDB.Core
4341-- | Type alias for StoreName
4442type StoreName = String
4543
46−
4744-- | Options provided when creating an object store.
4845type ObjectStoreParameters =
49− { keyPath :: KeyPath
46+ { keyPath :: KeyPath
5047 , autoIncrement :: Boolean
5148 }
5249
53−
5450defaultParameters :: ObjectStoreParameters
5551defaultParameters =
56− { keyPath : []
57− , autoIncrement : false
52+ { keyPath: []
53+ , autoIncrement: false
5854 }
5955
60−
6156--------------------
6257-- INTERFACE
6358--
6459
6560-- | Closes the connection once all running transactions have finished.
6661close
67− :: forall e db. (IDBDatabase db)
62+ :: forall db
63+ . (IDBDatabase db)
6864 => db
69− -> Aff (idb :: IDB | e) Unit
65+ -> Aff Unit
7066close =
71− fromEffFnAff <<< _close
72−
67+ fromEffectFnAff <<< _close
7368
7469-- | Creates a new object store with the given name and options and returns a new IDBObjectStore.
7570-- |
7671-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction
7772createObjectStore
78− :: forall e db. (IDBDatabase db)
73+ :: forall db
74+ . (IDBDatabase db)
7975 => db
8076 -> StoreName
8177 -> ObjectStoreParameters
82− -> Aff (idb :: IDB | e) ObjectStore
78+ -> Aff ObjectStore
8379createObjectStore db name' opts =
84− fromEffFnAff $ Fn.runFn3 _createObjectStore db name' opts
85−
80+ fromEffectFnAff $ Fn.runFn3 _createObjectStore db name' opts
8681
8782-- | Deletes the object store with the given name.
8883-- |
8984-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
9085deleteObjectStore
91− :: forall e db. (IDBDatabase db)
86+ :: forall db
87+ . (IDBDatabase db)
9288 => db
9389 -> StoreName
94− -> Aff (idb :: IDB | e) ObjectStore
90+ -> Aff ObjectStore
9591deleteObjectStore db name' =
96− fromEffFnAff $ Fn.runFn2 _deleteObjectStore db name'
97−
92+ fromEffectFnAff $ Fn.runFn2 _deleteObjectStore db name'
9893
9994-- | Returns a new transaction with the given mode (ReadOnly|ReadWrite)
10095-- | and scope which in the form of an array of object store names.
10196transaction
102− :: forall e db. (IDBDatabase db)
97+ :: forall db
98+ . (IDBDatabase db)
10399 => db
104100 -> Array StoreName
105101 -> TransactionMode
106− -> Aff (idb :: IDB | e) Transaction
102+ -> Aff Transaction
107103transaction db stores mode' =
108− fromEffFnAff $ Fn.runFn3 _transaction db stores (show mode')
109−
104+ fromEffectFnAff $ Fn.runFn3 _transaction db stores (show mode')
110105
111106--------------------
112107-- ATTRIBUTES
@@ -114,127 +109,107 @@ transaction db stores mode' =
114109
115110-- | Returns the name of the database.
116111name
117− :: Database
118− -> String
112+ :: Database
113+ -> String
119114name =
120115 _name
121116
122−
123117-- | Returns a list of the names of object stores in the database.
124118objectStoreNames
125− :: Database
126− -> Array String
119+ :: Database
120+ -> Array String
127121objectStoreNames =
128122 _objectStoreNames
129123
130−
131124-- | Returns the version of the database.
132125version
133− :: Database
134− -> Int
126+ :: Database
127+ -> Int
135128version =
136129 _version
137130
138−
139131--------------------
140132-- EVENT HANDLERS
141133--
142134-- | Event handler for the `abort` event.
143135onAbort
144− :: forall e e'
145− . Database
146− -> Eff ( | e') Unit
147− -> Aff (idb :: IDB | e) Unit
136+ :: Database
137+ -> Effect Unit
138+ -> Aff Unit
148139onAbort db f =
149− fromEffFnAff $ Fn.runFn2 _onAbort db f
150−
140+ fromEffectFnAff $ Fn.runFn2 _onAbort db f
151141
152142-- | Event handler for the `close` event.
153143onClose
154− :: forall e e'
155− . Database
156− -> Eff ( | e') Unit
157− -> Aff (idb :: IDB | e) Unit
144+ :: Database
145+ -> Effect Unit
146+ -> Aff Unit
158147onClose db f =
159− fromEffFnAff $ Fn.runFn2 _onClose db f
160−
148+ fromEffectFnAff $ Fn.runFn2 _onClose db f
161149
162150-- | Event handler for the `error` event.
163151onError
164− :: forall e e'
165− . Database
166− -> (Error -> Eff ( | e') Unit)
167− -> Aff (idb :: IDB | e) Unit
152+ :: Database
153+ -> (Error -> Effect Unit)
154+ -> Aff Unit
168155onError db f =
169− fromEffFnAff $ Fn.runFn2 _onError db f
170−
156+ fromEffectFnAff $ Fn.runFn2 _onError db f
171157
172158-- | Event handler for the `versionchange` event.
173159onVersionChange
174− :: forall e e'
175− . Database
176− -> ({ oldVersion :: Int, newVersion :: Int }
177− -> Eff ( | e') Unit)
178− -> Aff (idb :: IDB | e) Unit
160+ :: Database
161+ -> ( { oldVersion :: Int, newVersion :: Int }
162+ -> Effect Unit
163+ )
164+ -> Aff Unit
179165onVersionChange db f =
180− fromEffFnAff $ Fn.runFn2 _onVersionChange db f
181−
166+ fromEffectFnAff $ Fn.runFn2 _onVersionChange db f
182167
183168--------------------
184169-- FFI
185170--
186171
187172foreign import _close
188− :: forall db e
189− . db
190− -> EffFnAff (idb :: IDB | e) Unit
191−
173+ :: forall db
174+ . db
175+ -> EffectFnAff Unit
192176
193177foreign import _createObjectStore
194− :: forall db e
195− . Fn3 db String { keyPath :: Array String, autoIncrement :: Boolean } (EffFnAff (idb :: IDB | e) ObjectStore)
196−
178+ :: forall db
179+ . Fn3 db String { keyPath :: Array String, autoIncrement :: Boolean } (EffectFnAff ObjectStore)
197180
198181foreign import _deleteObjectStore
199− :: forall db e
200− . Fn2 db String (EffFnAff (idb :: IDB | e) ObjectStore)
201−
182+ :: forall db
183+ . Fn2 db String (EffectFnAff ObjectStore)
202184
203185foreign import _name
204− :: Database
205− -> String
206−
186+ :: Database
187+ -> String
207188
208189foreign import _objectStoreNames
209− :: Database
210− -> Array String
211−
190+ :: Database
191+ -> Array String
212192
213193foreign import _onAbort
214− :: forall db e e'
215− . Fn2 db (Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
216−
194+ :: forall db
195+ . Fn2 db (Effect Unit) (EffectFnAff Unit)
217196
218197foreign import _onClose
219− :: forall db e e'
220− . Fn2 db (Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
221−
198+ :: forall db
199+ . Fn2 db (Effect Unit) (EffectFnAff Unit)
222200
223201foreign import _onError
224− :: forall db e e'
225− . Fn2 db (Error -> Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
226−
202+ :: forall db
203+ . Fn2 db (Error -> Effect Unit) (EffectFnAff Unit)
227204
228205foreign import _onVersionChange
229− :: forall db e e'
230− . Fn2 db ({ oldVersion :: Int, newVersion :: Int } -> Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
231−
206+ :: forall db
207+ . Fn2 db ({ oldVersion :: Int, newVersion :: Int } -> Effect Unit) (EffectFnAff Unit)
232208
233209foreign import _transaction
234− :: forall db e
235− . Fn3 db (Array String) String (EffFnAff (idb :: IDB | e) Transaction)
236−
210+ :: forall db
211+ . Fn3 db (Array String) String (EffectFnAff Transaction)
237212
238213foreign import _version
239− :: Database
240− -> Int
214+ :: Database
215+ -> Int
src/Database/IndexedDB/IDBFactory.js+2−2
@@ -18,7 +18,7 @@ const noOp3 = function noOp3() {
1818 return noOp2;
1919};
2020
21−exports._deleteDatabase = function _deleteDatabase(name) {
21+export function _deleteDatabase(name) {
2222 return function aff(error, success) {
2323 try {
2424 const request = indexedDB.deleteDatabase(name);
@@ -38,7 +38,7 @@ exports._deleteDatabase = function _deleteDatabase(name) {
3838 };
3939};
4040
41−exports._open = function _open(fromMaybe, name, mver, req) {
41+export function _open(fromMaybe, name, mver, req) {
4242 const ver = fromMaybe(undefined)(mver);
4343
4444 return function aff(error, success) {
src/Database/IndexedDB/IDBFactory.purs+22−33
@@ -12,37 +12,32 @@ module Database.IndexedDB.IDBFactory
1212 , open
1313 ) where
1414
15−import Prelude (Unit, ($), (<<<))
16−
17−import Control.Monad.Aff (Aff)
18−import Control.Monad.Aff.Compat (fromEffFnAff, EffFnAff)
19−import Control.Monad.Eff (Eff)
20−import Data.Function.Uncurried as Fn
21−import Data.Function.Uncurried (Fn4)
22−import Data.Maybe (Maybe, fromMaybe)
23−
2415import Database.IndexedDB.Core
2516
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, ($), (<<<))
2624
2725--------------------
2826-- TYPES
2927--
3028
3129-- Type alias for binding listeners to an initial open action.
32−type Callbacks e =
33− { onBlocked :: Maybe (Eff (| e) Unit)
34− , onUpgradeNeeded :: Maybe (Database -> Transaction -> { oldVersion :: Int } -> Eff (| e) Unit)
30+type Callbacks =
31+ { onBlocked :: Maybe (Effect Unit)
32+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> { oldVersion :: Int } -> Effect Unit)
3533 }
3634
37−
3835-- | Type alias for DatabaseName.
3936type DatabaseName = String
4037
41−
4238-- | Type alias for Version.
4339type Version = Int
4440
45−
4641--------------------
4742-- INTERFACE
4843--
@@ -51,12 +46,10 @@ type Version = Int
5146-- | and there are open connections that don’t close in response to a
5247-- | `versionchange` event, the request will be blocked until all they close.
5348deleteDatabase
54− :: forall e
55− . DatabaseName
56− -> Aff (idb :: IDB | e) Int
49+ :: DatabaseName
50+ -> Aff Int
5751deleteDatabase =
58− fromEffFnAff <<< _deleteDatabase
59−
52+ fromEffectFnAff <<< _deleteDatabase
6053
6154-- | Attempts to open a connection to the named database with the specified version.
6255-- | If the database already exists with a lower version and there are open connections
@@ -67,24 +60,20 @@ deleteDatabase =
6760-- | When the version isn't provided (`Nothing`), attempts to open a connection to the
6861-- | named database with the current version, or 1 if it does not already exist.
6962open
70− :: forall e e'
71− . DatabaseName
72− -> Maybe Version
73− -> Callbacks e'
74− -> Aff (idb :: IDB | e) Database
63+ :: DatabaseName
64+ -> Maybe Version
65+ -> Callbacks
66+ -> Aff Database
7567open name mver req =
76− fromEffFnAff $ Fn.runFn4 _open fromMaybe name mver req
77−
68+ fromEffectFnAff $ Fn.runFn4 _open fromMaybe name mver req
7869
7970--------------------
8071-- FFI
8172--
8273foreign import _deleteDatabase
83− :: forall e
84− . String
85− -> EffFnAff (idb :: IDB | e) Int
86−
74+ :: String
75+ -> EffectFnAff Int
8776
8877foreign import _open
89− :: forall a e e'
90− . Fn4 (a -> Maybe a -> a) String (Maybe Int) (Callbacks e') (EffFnAff (idb :: IDB | e) Database)
78+ :: forall a
79+ . Fn4 (a -> Maybe a -> a) String (Maybe Int) (Callbacks) (EffectFnAff Database)
src/Database/IndexedDB/IDBIndex.js+12−12
@@ -11,7 +11,7 @@ const successHandler = function successHandler(cb) {
1111};
1212
1313
14−exports._keyPath = function _keyPath(index) {
14+export function _keyPath(index) {
1515 const path = index.keyPath;
1616
1717 if (Array.isArray(path)) {
@@ -25,23 +25,23 @@ exports._keyPath = function _keyPath(index) {
2525 return [];
2626};
2727
28−exports._multiEntry = function _multiEntry(index) {
28+export function _multiEntry(index) {
2929 return index.multiEntry;
3030};
3131
32−exports._name = function _name(index) {
32+export function _name(index) {
3333 return index.name;
3434};
3535
36−exports._objectStore = function _objectStore(index) {
36+export function _objectStore(index) {
3737 return index.obectStore;
3838};
3939
40−exports._unique = function _unique(index) {
40+export function _unique(index) {
4141 return index.unique;
4242};
4343
44−exports._count = function _count(index, query) {
44+export function _count(index, query) {
4545 return function aff(error, success) {
4646 try {
4747 const request = index.count(query);
@@ -57,7 +57,7 @@ exports._count = function _count(index, query) {
5757 };
5858};
5959
60−exports._get = function _get(index, range) {
60+export function _get(index, range) {
6161 return function aff(error, success) {
6262 try {
6363 const request = index.get(range);
@@ -79,7 +79,7 @@ exports._get = function _get(index, range) {
7979 *
8080 * However, it may be doable to convert the result to some key / value structure with values of
8181 * different types.
82−exports._getAll = function _getAll(index, query, count) {
82+export function _getAll(index, query, count) {
8383 return function aff(error, success) {
8484 const request = index.getAll(query, count);
8585 request.onsuccess = successHandler(success);
@@ -88,7 +88,7 @@ exports._getAll = function _getAll(index, query, count) {
8888};
8989*/
9090
91−exports._getAllKeys = function _getAllKeys(index, range, count) {
91+export function _getAllKeys(index, range, count) {
9292 return function aff(error, success) {
9393 try {
9494 const request = index.getAllKeys(range, count || undefined);
@@ -104,7 +104,7 @@ exports._getAllKeys = function _getAllKeys(index, range, count) {
104104 };
105105};
106106
107−exports._getKey = function _getKey(index, range) {
107+export function _getKey(index, range) {
108108 return function aff(error, success) {
109109 try {
110110 const request = index.getKey(range);
@@ -120,7 +120,7 @@ exports._getKey = function _getKey(index, range) {
120120 };
121121};
122122
123−exports._openCursor = function _openCursor(index, query, dir, cb) {
123+export function _openCursor(index, query, dir, cb) {
124124 return function aff(error, success) {
125125 try {
126126 const request = index.openCursor(query, dir);
@@ -145,7 +145,7 @@ exports._openCursor = function _openCursor(index, query, dir, cb) {
145145 };
146146};
147147
148−exports._openKeyCursor = function _openKeyCursor(index, query, dir, cb) {
148+export function _openKeyCursor(index, query, dir, cb) {
149149 return function aff(error, success) {
150150 try {
151151 const request = index.openKeyCursor(query, dir);
src/Database/IndexedDB/IDBIndex.purs+78−96
@@ -20,205 +20,187 @@ module Database.IndexedDB.IDBIndex
2020 , unique
2121 ) where
2222
23−import Prelude (Unit, map, show, (<$>), (>>>), ($))
24−
25−import Control.Monad.Aff (Aff)
26−import Control.Monad.Aff.Compat (EffFnAff, fromEffFnAff)
27−import Control.Monad.Eff (Eff)
28−import Control.Monad.Eff.Exception (Error)
29−import Data.Foreign (Foreign, unsafeFromForeign)
30−import Data.Function.Uncurried as Fn
31−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
32−import Data.Maybe (Maybe)
33−import Data.Nullable (Nullable, toMaybe, toNullable)
34−
3523import Database.IndexedDB.Core
36−import Database.IndexedDB.IDBKey.Internal (Key, toKey)
3724
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, ($), (>>>))
3836
3937--------------------
4038-- TYPES
4139--
4240
4341-- | Callbacks to manipulate a cursor from an Open*Cursor call
44−type Callbacks cursor e =
45− { onSuccess :: cursor -> Eff ( | e) Unit
46− , onError :: Error -> Eff ( | e) Unit
47− , onComplete :: Eff ( | e) Unit
42+type Callbacks cursor =
43+ { onSuccess :: cursor -> Effect Unit
44+ , onError :: Error -> Effect Unit
45+ , onComplete :: Effect Unit
4846 }
4947
50−
5148--------------------
5249-- INTERFACES
5350--
5451
5552-- | Retrieves the number of records matching the key range in query.
5653count
57− :: forall e index. (IDBIndex index)
58− => index
54+ :: forall index
55+ . (IDBIndex index)
56+ => index
5957 -> Maybe KeyRange
60− -> Aff (idb :: IDB | e) Int
58+ -> Aff Int
6159count index range =
62− fromEffFnAff $ Fn.runFn2 _count index (toNullable range)
63−
60+ fromEffectFnAff $ Fn.runFn2 _count index (toNullable range)
6461
6562-- | Retrieves the value of the first record matching the given key range in query.
6663-- |
6764-- | NOTE
6865-- | The coercion from `a` to any type is unsafe and might throw a runtime error if incorrect.
6966get
70− :: forall a e index. (IDBIndex index)
67+ :: forall a index
68+ . (IDBIndex index)
7169 => index
7270 -> KeyRange
73− -> Aff (idb :: IDB | e) (Maybe a)
71+ -> Aff (Maybe a)
7472get index range =
75− map (toMaybe >>> map unsafeFromForeign) $ fromEffFnAff $ Fn.runFn2 _get index range
76−
73+ map (toMaybe >>> map unsafeFromForeign) $ fromEffectFnAff $ Fn.runFn2 _get index range
7774
7875-- | Retrieves the keys of records matching the given key range in query
7976-- | (up to the number given if given).
8077getAllKeys
81− :: forall e index. (IDBIndex index)
78+ :: forall index
79+ . (IDBIndex index)
8280 => index
8381 -> Maybe KeyRange
8482 -> Maybe Int
85− -> Aff (idb :: IDB | e) (Array Key)
83+ -> Aff (Array Key)
8684getAllKeys index range n =
87− map (map toKey) $ fromEffFnAff $ Fn.runFn3 _getAllKeys index (toNullable range) (toNullable n)
88−
85+ map (map toKey) $ fromEffectFnAff $ Fn.runFn3 _getAllKeys index (toNullable range) (toNullable n)
8986
9087-- | Retrieves the key of the first record matching the given key or key range in query.
9188getKey
92− :: forall e index. (IDBIndex index)
89+ :: forall index
90+ . (IDBIndex index)
9391 => index
9492 -> KeyRange
95− -> Aff (idb :: IDB | e) (Maybe Key)
93+ -> Aff (Maybe Key)
9694getKey index range =
97− map (toMaybe >>> map toKey) $ fromEffFnAff $ Fn.runFn2 _getKey index range
98−
95+ map (toMaybe >>> map toKey) $ fromEffectFnAff $ Fn.runFn2 _getKey index range
9996
10097-- | Opens a ValueCursor over the records matching query, ordered by direction.
10198-- | If query is `Nothing`, all records in index are matched.
10299openCursor
103− :: forall e e' index. (IDBIndex index)
104− => index
100+ :: forall index
101+ . (IDBIndex index)
102+ => index
105103 -> Maybe KeyRange
106104 -> CursorDirection
107− -> Callbacks ValueCursor e'
108− -> Aff (idb :: IDB | e) Unit
105+ -> Callbacks ValueCursor
106+ -> Aff Unit
109107openCursor index range dir cb =
110− fromEffFnAff $ Fn.runFn4 _openCursor index (toNullable range) (show dir) cb
111−
108+ fromEffectFnAff $ Fn.runFn4 _openCursor index (toNullable range) (show dir) cb
112109
113110-- | Opens a KeyCursor over the records matching query, ordered by direction.
114111-- | If query is `Nothing`, all records in index are matched.
115112openKeyCursor
116− :: forall e e' index. (IDBIndex index)
117− => index
118− -> Maybe KeyRange
119− -> CursorDirection
120− -> Callbacks KeyCursor e'
121− -> Aff (idb :: IDB | e) Unit
113+ :: forall index
114+ . (IDBIndex index)
115+ => index
116+ -> Maybe KeyRange
117+ -> CursorDirection
118+ -> Callbacks KeyCursor
119+ -> Aff Unit
122120openKeyCursor index range dir cb =
123− fromEffFnAff $ Fn.runFn4 _openKeyCursor index (toNullable range) (show dir) cb
124−
121+ fromEffectFnAff $ Fn.runFn4 _openKeyCursor index (toNullable range) (show dir) cb
125122
126123--------------------
127124-- ATTRIBUTES
128125--
129126-- | Returns the key path of the index.
130127keyPath
131− :: Index
132− -> KeyPath
128+ :: Index
129+ -> KeyPath
133130keyPath =
134131 _keyPath
135132
136−
137133-- | Returns true if the index's multiEntry flag is set.
138134multiEntry
139− :: Index
140− -> Boolean
135+ :: Index
136+ -> Boolean
141137multiEntry =
142138 _multiEntry
143139
144−
145140-- | Returns the name of the index.
146141name
147− :: Index
148− -> String
142+ :: Index
143+ -> String
149144name =
150145 _name
151146
152−
153147-- | Returns the IDBObjectStore the index belongs to.
154148objectStore
155− :: Index
156− -> ObjectStore
149+ :: Index
150+ -> ObjectStore
157151objectStore =
158152 _objectStore
159153
160−
161154-- | Returns true if the index's unique flag is set.
162155unique
163− :: Index
164− -> Boolean
156+ :: Index
157+ -> Boolean
165158unique =
166159 _unique
167160
168−
169161--------------------
170162-- FFI
171163--
172164foreign import _keyPath
173− :: Index
174− -> Array String
175−
165+ :: Index
166+ -> Array String
176167
177168foreign import _multiEntry
178− :: Index
179− -> Boolean
180−
169+ :: Index
170+ -> Boolean
181171
182172foreign import _name
183− :: Index
184− -> String
185−
173+ :: Index
174+ -> String
186175
187176foreign import _objectStore
188− :: Index
189− -> ObjectStore
190−
177+ :: Index
178+ -> ObjectStore
191179
192180foreign import _unique
193− :: Index
194− -> Boolean
195−
181+ :: Index
182+ -> Boolean
196183
197184foreign import _count
198− :: forall index e
199− . Fn2 index (Nullable KeyRange) (EffFnAff (idb :: IDB | e) Int)
200−
185+ :: forall index
186+ . Fn2 index (Nullable KeyRange) (EffectFnAff Int)
201187
202188foreign import _get
203− :: forall index e
204− . Fn2 index KeyRange (EffFnAff (idb :: IDB | e) (Nullable Foreign))
205−
189+ :: forall index
190+ . Fn2 index KeyRange (EffectFnAff (Nullable Foreign))
206191
207192foreign import _getAllKeys
208− :: forall index e
209− . Fn3 index (Nullable KeyRange) (Nullable Int) (EffFnAff (idb :: IDB | e) (Array Foreign))
210−
193+ :: forall index
194+ . Fn3 index (Nullable KeyRange) (Nullable Int) (EffectFnAff (Array Foreign))
211195
212196foreign import _getKey
213− :: forall index e
214− . Fn2 index KeyRange (EffFnAff (idb :: IDB | e) (Nullable Foreign))
215−
197+ :: forall index
198+ . Fn2 index KeyRange (EffectFnAff (Nullable Foreign))
216199
217200foreign import _openCursor
218− :: forall index e e'
219− . Fn4 index (Nullable KeyRange) String (Callbacks ValueCursor e') (EffFnAff (idb :: IDB | e) Unit)
220−
201+ :: forall index
202+ . Fn4 index (Nullable KeyRange) String (Callbacks ValueCursor) (EffectFnAff Unit)
221203
222204foreign import _openKeyCursor
223− :: forall index e e'
224− . Fn4 index (Nullable KeyRange) String (Callbacks KeyCursor e') (EffFnAff (idb :: IDB | e) Unit)
205+ :: forall index
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) {
22 return new Date(y, m, d, h, mi, s, ms);
33};
44
5−exports._readDateTime = function _readDateTime(parse, right, left, date) {
5+export function _readDateTime(parse, right, left, date) {
66 if (Object.getPrototypeOf(date) !== Date.prototype) {
77 return left(typeof date);
88 }
@@ -24,7 +24,7 @@ exports._readDateTime = function _readDateTime(parse, right, left, date) {
2424 return right(mdate);
2525};
2626
27−exports._unsafeReadDateTime = function _unsafeReadDateTime(parse, date) {
27+export function _unsafeReadDateTime(parse, date) {
2828 const y = date.getFullYear();
2929 const m = date.getMonth() + 1;
3030 const d = date.getDate();
src/Database/IndexedDB/IDBKey/Internal.purs+90−106
@@ -3,35 +3,36 @@
33-- | NOTE: Binary keys aren't supported yet.
44module Database.IndexedDB.IDBKey.Internal
55 ( Key
6− , class IDBKey, toKey , fromKey , unsafeFromKey
6+ , class IDBKey
7+ , toKey
8+ , fromKey
9+ , unsafeFromKey
710 , none
811 ) where
912
1013import Prelude
1114
12−import Control.Alt ((<|>))
13−import Control.Monad.Except (ExceptT(..), runExceptT)
14−import Data.Date as Date
15−import Data.DateTime (DateTime(..), Time(..))
16−import Data.Either (Either(..), either, isRight)
17−import Data.Enum (fromEnum, toEnum)
18−import Data.Foreign as Foreign
19−import Data.Foreign (Foreign, F)
20−import Data.Function.Uncurried as Fn
15+import Control.Alt ((<|>))
16+import Control.Monad.Except (ExceptT(..), runExceptT)
17+import Data.Date as Date
18+import Data.DateTime (DateTime(..), Time(..))
19+import Data.Either (Either(..), either, isRight)
20+import Data.Enum (fromEnum, toEnum)
21+import Foreign as Foreign
22+import Foreign (Foreign, F)
23+import Data.Function.Uncurried as Fn
2124import Data.Function.Uncurried (Fn2, Fn4, Fn7)
22−import Data.Identity (Identity(..))
23−import Data.List.NonEmpty (NonEmptyList(..))
24−import Data.List.Types (List(..))
25−import Data.Maybe (Maybe(..))
26−import Data.NonEmpty (NonEmpty(..))
27−import Data.Nullable (Nullable, toNullable)
28−import Data.Time as Time
29−import Data.Traversable (traverse)
30−
25+import Data.Identity (Identity(..))
26+import Data.List.NonEmpty (NonEmptyList(..))
27+import Data.List.Types (List(..))
28+import Data.Maybe (Maybe(..))
29+import Data.NonEmpty (NonEmpty(..))
30+import Data.Nullable (Nullable, toNullable)
31+import Data.Time as Time
32+import Data.Traversable (traverse)
3133
3234newtype Key = Key Foreign
3335
34−
3536--------------------
3637-- INTERFACES
3738--
@@ -39,100 +40,90 @@ newtype Key = Key Foreign
3940-- | to a known type (e.g if you only strings as keys, or perfectly knows the
4041-- | type of a given key).
4142class IDBKey a where
42− toKey :: a -> Key
43− fromKey :: Key -> F a
43+ toKey :: a -> Key
44+ fromKey :: Key -> F a
4445 unsafeFromKey :: Key -> a
4546
46−
4747none :: Maybe Key
4848none =
4949 Nothing
5050
51−
5251--------------------
5352-- INSTANCES
5453--
5554instance eqKey :: Eq Key where
5655 eq a b = (runExceptT >>> runIdentity >>> isRight) $
57− eq <$> ((fromKey a) :: F Int) <*> fromKey b
58− <|>
59− eq <$> ((fromKey a) :: F Number) <*> fromKey b
60− <|>
61− eq <$> ((fromKey a) :: F String) <*> fromKey b
62− <|>
63− eq <$> ((fromKey a) :: F DateTime) <*> fromKey b
64− <|>
65− eq <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
56+ eq <$> ((fromKey a) :: F Int) <*> fromKey b
57+ <|>
58+ eq <$> ((fromKey a) :: F Number) <*> fromKey b
59+ <|>
60+ eq <$> ((fromKey a) :: F String) <*> fromKey b
61+ <|>
62+ eq <$> ((fromKey a) :: F DateTime) <*> fromKey b
63+ <|>
64+ eq <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
6665 where
67− runIdentity :: forall a. Identity a -> a
68− runIdentity (Identity x) = x
69−
66+ runIdentity :: forall a. Identity a -> a
67+ runIdentity (Identity x) = x
7068
7169instance ordKey :: Ord Key where
72− compare a b = (runExceptT >>> runIdentity >>> either (const LT) id) $
73− compare <$> ((fromKey a) :: F Int) <*> fromKey b
74− <|>
75− compare <$> ((fromKey a) :: F Number) <*> fromKey b
76− <|>
77− compare <$> ((fromKey a) :: F String) <*> fromKey b
78− <|>
79− compare <$> ((fromKey a) :: F DateTime) <*> fromKey b
80− <|>
81− compare <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
70+ compare a b = (runExceptT >>> runIdentity >>> either (const LT) identity) $
71+ compare <$> ((fromKey a) :: F Int) <*> fromKey b
72+ <|>
73+ compare <$> ((fromKey a) :: F Number) <*> fromKey b
74+ <|>
75+ compare <$> ((fromKey a) :: F String) <*> fromKey b
76+ <|>
77+ compare <$> ((fromKey a) :: F DateTime) <*> fromKey b
78+ <|>
79+ compare <$> ((fromKey a) :: F (Array Key)) <*> fromKey b
8280 where
83− runIdentity :: forall a. Identity a -> a
84− runIdentity (Identity x) = x
85−
81+ runIdentity :: forall a. Identity a -> a
82+ runIdentity (Identity x) = x
8683
8784instance showKey :: Show Key where
8885 show a = (runExceptT >>> format) $
89− (show <$> (fromKey a :: F Int))
90− <|>
91− (show <$> (fromKey a :: F Number))
92− <|>
93− (show <$> (fromKey a :: F String))
94− <|>
95− (show <$> (fromKey a :: F DateTime))
96− <|>
97− (show <$> (fromKey a :: F (Array Key)))
86+ (show <$> (fromKey a :: F Int))
87+ <|>
88+ (show <$> (fromKey a :: F Number))
89+ <|>
90+ (show <$> (fromKey a :: F String))
91+ <|>
92+ (show <$> (fromKey a :: F DateTime))
93+ <|>
94+ (show <$> (fromKey a :: F (Array Key)))
9895 where
99− format :: forall a. Identity (Either a String) -> String
100− format (Identity x) =
101− either (const "(Key)") (\s -> "(Key " <> s <> ")") x
102−
96+ format :: forall a. Identity (Either a String) -> String
97+ format (Identity x) =
98+ either (const "(Key)") (\s -> "(Key " <> s <> ")") x
10399
104100instance idbKeyKey :: IDBKey Key where
105− toKey = id
106− fromKey = pure
107− unsafeFromKey = id
108−
101+ toKey = identity
102+ fromKey = pure
103+ unsafeFromKey = identity
109104
110105instance idbKeyForeign :: IDBKey Foreign where
111− toKey = Key
112− fromKey (Key f) = pure f
106+ toKey = Key
107+ fromKey (Key f) = pure f
113108 unsafeFromKey (Key f) = f
114109
115−
116110instance idbKeyInt :: IDBKey Int where
117− toKey = Foreign.toForeign >>> Key
118− fromKey (Key f) = Foreign.readInt f
111+ toKey = Foreign.unsafeToForeign >>> Key
112+ fromKey (Key f) = Foreign.readInt f
119113 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
120114
121−
122115instance idbKeyNumber :: IDBKey Number where
123− toKey = Foreign.toForeign >>> Key
124− fromKey (Key f) = Foreign.readNumber f
116+ toKey = Foreign.unsafeToForeign >>> Key
117+ fromKey (Key f) = Foreign.readNumber f
125118 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
126119
127−
128120instance idbKeyString :: IDBKey String where
129− toKey = Foreign.toForeign >>> Key
130− fromKey (Key f) = Foreign.readString f
121+ toKey = Foreign.unsafeToForeign >>> Key
122+ fromKey (Key f) = Foreign.readString f
131123 unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
132124
133−
134125instance idbKeyDate :: IDBKey DateTime where
135− toKey (DateTime d t) = Key $ Fn.runFn7 _dateTimeToForeign
126+ toKey (DateTime d t) = Key $ Fn.runFn7 _dateTimeToForeign
136127 (fromEnum $ Date.year d)
137128 (fromEnum $ Date.month d)
138129 (fromEnum $ Date.day d)
@@ -140,58 +131,51 @@ instance idbKeyDate :: IDBKey DateTime where
140131 (fromEnum $ Time.minute t)
141132 (fromEnum $ Time.second t)
142133 (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
144135 unsafeFromKey (Key f) = Fn.runFn2 _unsafeReadDateTime dateTime f
145136
146−
147137instance idbKeyArray :: IDBKey a => IDBKey (Array a) where
148− toKey = Foreign.toForeign >>> Key
149− fromKey (Key f) = Foreign.readArray f >>= traverse (Key >>> fromKey)
138+ toKey = Foreign.unsafeToForeign >>> Key
139+ fromKey (Key f) = Foreign.readArray f >>= traverse (Key >>> fromKey)
150140 unsafeFromKey (Key f) = map unsafeFromKey (Foreign.unsafeFromForeign f)
151141
152−
153142-- FFI constructor to build a DateTime from years, months, days, hours, minutes, seconds and millis
154143dateTime
155− :: Int -- ^ years
156− -> Int -- ^ months
157− -> Int -- ^ days
158− -> Int -- ^ hours
159− -> Int -- ^ minutes
160− -> Int -- ^ seconds
161− -> Int -- ^ milliseconds
162− -> Nullable DateTime
144+ :: Int -- ^ years
145+ -> Int -- ^ months
146+ -> Int -- ^ days
147+ -> Int -- ^ hours
148+ -> Int -- ^ minutes
149+ -> Int -- ^ seconds
150+ -> Int -- ^ milliseconds
151+ -> Nullable DateTime
163152dateTime y m d h mi s ms =
164153 toNullable $ DateTime
165− <$> (Date.canonicalDate <$> toEnum y <*> toEnum m <*> toEnum d)
166− <*> (Time <$> toEnum h <*> toEnum mi <*> toEnum s <*> toEnum ms)
167−
154+ <$> (Date.canonicalDate <$> toEnum y <*> toEnum m <*> toEnum d)
155+ <*> (Time <$> toEnum h <*> toEnum mi <*> toEnum s <*> toEnum ms)
168156
169157-- FFI constructor to convert a JS `Date` into a successful `F DateTime`
170158dateTimeF
171− :: DateTime
172− -> F DateTime
159+ :: DateTime
160+ -> F DateTime
173161dateTimeF =
174162 Right >>> Identity >>> ExceptT
175163
176−
177164-- FFI constructor to convert a string into an errored `F DateTime`
178165dateTimeE
179− :: String
180− -> F DateTime
166+ :: String
167+ -> F DateTime
181168dateTimeE =
182169 Foreign.TypeMismatch "Date" >>> flip NonEmpty Nil >>> NonEmptyList >>> Left >>> Identity >>> ExceptT
183170
184−
185171--------------------
186172-- FFI
187173--
188174foreign import _dateTimeToForeign
189− :: Fn7 Int Int Int Int Int Int Int Foreign
190−
175+ :: Fn7 Int Int Int Int Int Int Int Foreign
191176
192177foreign import _readDateTime
193− :: Fn4 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) (DateTime -> F DateTime) (String -> F DateTime) Foreign (F DateTime)
194−
178+ :: Fn4 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) (DateTime -> F DateTime) (String -> F DateTime) Foreign (F DateTime)
195179
196180foreign 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) {
22 try {
33 return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
44 } catch (e) {
@@ -6,34 +6,34 @@ exports._bound = function _bound(lower, upper, lowerOpen, upperOpen) {
66 }
77};
88
9−exports._includes = function _includes(range, key) {
9+export function _includes(range, key) {
1010 return range.includes(key);
1111};
1212
13−exports._lower = function _lower(range) {
13+export function _lower(range) {
1414 return range.lower;
1515};
1616
17−exports._lowerBound = function _lowerBound(lower, open) {
17+export function _lowerBound(lower, open) {
1818 return IDBKeyRange.lowerBound(lower, open);
1919};
2020
21−exports._lowerOpen = function _lowerOpen(range) {
21+export function _lowerOpen(range) {
2222 return range.lowerOpen;
2323};
2424
25−exports._only = function _only(key) {
25+export function _only(key) {
2626 return IDBKeyRange.only(key);
2727};
2828
29−exports._upper = function _upper(range) {
29+export function _upper(range) {
3030 return range.upper;
3131};
3232
33−exports._upperBound = function _upperBound(upper, open) {
33+export function _upperBound(upper, open) {
3434 return IDBKeyRange.upperBound(upper, open);
3535};
3636
37−exports._upperOpen = function _upperOpen(range) {
37+export function _upperOpen(range) {
3838 return range.upperOpen;
3939};
src/Database/IndexedDB/IDBKeyRange.purs+30−42
@@ -19,18 +19,17 @@ module Database.IndexedDB.IDBKeyRange
1919 , upperOpen
2020 ) where
2121
22−import Prelude (($), (>>>), map)
22+import Prelude (($), (>>>), map)
2323
24−import Data.Foreign (Foreign)
25−import Data.Function.Uncurried as Fn
26−import Data.Function.Uncurried (Fn2, Fn4)
27−import Data.Maybe (Maybe)
28−import Data.Nullable (Nullable, toMaybe)
24+import Foreign (Foreign)
25+import Data.Function.Uncurried as Fn
26+import Data.Function.Uncurried (Fn2, Fn4)
27+import Data.Maybe (Maybe)
28+import Data.Nullable (Nullable, toMaybe)
2929
30−import Database.IndexedDB.Core (class IDBKeyRange, KeyRange)
30+import Database.IndexedDB.Core (class IDBKeyRange, KeyRange)
3131import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromKey)
3232
33−
3433--------------------
3534-- TYPES
3635--
@@ -38,55 +37,54 @@ import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, toKey, unsafeFromK
3837-- | Type alias for open
3938type Open = Boolean
4039
41−
4240--------------------
4341-- CONSTRUCTORS
4442--
4543
4644-- | Returns a new IDBKeyRange spanning only key.
4745only
48− :: forall a. (IDBKey a)
49− => a
50− -> KeyRange
46+ :: forall a
47+ . (IDBKey a)
48+ => a
49+ -> KeyRange
5150only key =
5251 _only (unsafeFromKey $ toKey key)
5352
54−
5553-- | Returns a new IDBKeyRange starting at key with no upper bound.
5654-- | If `Open` is `true`, key is not included in the range.
5755lowerBound
58− :: forall a. (IDBKey a)
59− => a
60− -> Open
61− -> KeyRange
56+ :: forall a
57+ . (IDBKey a)
58+ => a
59+ -> Open
60+ -> KeyRange
6261lowerBound key open =
6362 Fn.runFn2 _lowerBound (unsafeFromKey $ toKey key) open
6463
65−
6664-- | Returns a new IDBKeyRange with no lower bound and ending at key.
6765-- | If `Open` is `true`, key is not included in the range.
6866upperBound
69− :: forall a. (IDBKey a)
70− => a
71− -> Open
72− -> KeyRange
67+ :: forall a
68+ . (IDBKey a)
69+ => a
70+ -> Open
71+ -> KeyRange
7372upperBound key open =
7473 Fn.runFn2 _upperBound (unsafeFromKey $ toKey key) open
7574
76−
7775-- | Returns a new IDBKeyRange spanning from `lower` to `upper`.
7876-- | If `lowerOpen` is `true`, `lower` is not included in the range.
7977-- | If `upperOpen` is `true`, `upper` is not included in the range.
8078-- |
8179-- | It throws a `DataError` if the bound is invalid.
8280bound
83− :: forall key. (IDBKey key)
84− => { lower :: key, upper :: key, lowerOpen :: Boolean, upperOpen :: Boolean }
85− -> Maybe KeyRange
81+ :: forall key
82+ . (IDBKey key)
83+ => { lower :: key, upper :: key, lowerOpen :: Boolean, upperOpen :: Boolean }
84+ -> Maybe KeyRange
8685bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
8786 toMaybe
88− $ Fn.runFn4 _bound (unsafeFromKey $ toKey key1) (unsafeFromKey $ toKey key2) open1 open2
89−
87+ $ Fn.runFn4 _bound (unsafeFromKey $ toKey key1) (unsafeFromKey $ toKey key2) open1 open2
9088
9189--------------------
9290-- INTERFACE
@@ -94,14 +92,15 @@ bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
9492
9593-- | Returns true if key is included in the range, and false otherwise.
9694includes
97− :: forall key range. (IDBKey key) => (IDBKeyRange range)
95+ :: forall key range
96+ . (IDBKey key)
97+ => (IDBKeyRange range)
9898 => range
9999 -> key
100100 -> Boolean
101101includes range =
102102 toKey >>> unsafeFromKey >>> Fn.runFn2 _includes range
103103
104−
105104--------------------
106105-- ATTRIBUTES
107106--
@@ -112,7 +111,6 @@ lower
112111lower =
113112 _lower >>> toMaybe >>> map toKey
114113
115−
116114-- | Returns upper bound if any.
117115upper
118116 :: KeyRange
@@ -120,7 +118,6 @@ upper
120118upper =
121119 _upper >>> toMaybe >>> map toKey
122120
123−
124121-- | Returns true if the lower open flag is set, false otherwise.
125122lowerOpen
126123 :: KeyRange
@@ -128,7 +125,6 @@ lowerOpen
128125lowerOpen =
129126 _lowerOpen
130127
131−
132128-- | Returns true if the upper open flag is set, false otherwise.
133129upperOpen
134130 :: KeyRange
@@ -136,7 +132,6 @@ upperOpen
136132upperOpen =
137133 _upperOpen
138134
139−
140135--------------------
141136-- FFI
142137--
@@ -148,35 +143,28 @@ foreign import _only
148143foreign import _lowerBound
149144 :: Fn2 Foreign Boolean KeyRange
150145
151−
152146foreign import _upperBound
153147 :: Fn2 Foreign Boolean KeyRange
154148
155−
156149foreign import _bound
157150 :: Fn4 Foreign Foreign Boolean Boolean (Nullable KeyRange)
158151
159−
160152foreign import _includes
161153 :: forall range
162− . Fn2 range Foreign Boolean
163−
154+ . Fn2 range Foreign Boolean
164155
165156foreign import _lower
166157 :: KeyRange
167158 -> Nullable Foreign
168159
169−
170160foreign import _upper
171161 :: KeyRange
172162 -> Nullable Foreign
173163
174−
175164foreign import _lowerOpen
176165 :: KeyRange
177166 -> Boolean
178167
179−
180168foreign import _upperOpen
181169 :: KeyRange
182170 -> Boolean
src/Database/IndexedDB/IDBObjectStore.js+12−12
@@ -15,7 +15,7 @@ const toArray = function toArray(xs) {
1515};
1616
1717
18−exports._add = function _add(store, value, key) {
18+export function _add(store, value, key) {
1919 return function aff(error, success) {
2020 try {
2121 const request = store.add(value, key || undefined);
@@ -31,11 +31,11 @@ exports._add = function _add(store, value, key) {
3131 };
3232};
3333
34−exports._autoIncrement = function _autoIncrement(store) {
34+export function _autoIncrement(store) {
3535 return store.autoIncrement;
3636};
3737
38−exports._clear = function _clear(store) {
38+export function _clear(store) {
3939 return function aff(error, success) {
4040 try {
4141 const request = store.clear();
@@ -51,7 +51,7 @@ exports._clear = function _clear(store) {
5151 };
5252};
5353
54−exports._createIndex = function _createIndex(store, name, path, params) {
54+export function _createIndex(store, name, path, params) {
5555 return function aff(error, success) {
5656 var keyPath;
5757
@@ -81,7 +81,7 @@ exports._createIndex = function _createIndex(store, name, path, params) {
8181 };
8282};
8383
84−exports._deleteIndex = function _deleteIndex(store, name) {
84+export function _deleteIndex(store, name) {
8585 return function aff(error, success) {
8686 try {
8787 store.deleteIndex(name);
@@ -96,7 +96,7 @@ exports._deleteIndex = function _deleteIndex(store, name) {
9696 };
9797};
9898
99−exports._delete = function _delete(store, query) {
99+export function _delete(store, query) {
100100 return function aff(error, success) {
101101 try {
102102 const request = store.delete(query);
@@ -112,7 +112,7 @@ exports._delete = function _delete(store, query) {
112112 };
113113};
114114
115−exports._index = function _index(store, name) {
115+export function _index(store, name) {
116116 return function aff(error, success) {
117117 try {
118118 const index = store.index(name);
@@ -127,11 +127,11 @@ exports._index = function _index(store, name) {
127127 };
128128};
129129
130−exports._indexNames = function _indexNames(store) {
130+export function _indexNames(store) {
131131 return toArray(store.indexNames);
132132};
133133
134−exports._keyPath = function _keyPath(store) {
134+export function _keyPath(store) {
135135 const path = store.keyPath;
136136
137137 if (Array.isArray(path)) {
@@ -145,11 +145,11 @@ exports._keyPath = function _keyPath(store) {
145145 return [];
146146};
147147
148−exports._name = function _name(store) {
148+export function _name(store) {
149149 return store.name;
150150};
151151
152−exports._put = function _put(store, value, key) {
152+export function _put(store, value, key) {
153153 return function aff(error, success) {
154154 try {
155155 const request = store.put(value, key || undefined);
@@ -165,6 +165,6 @@ exports._put = function _put(store, value, key) {
165165 };
166166};
167167
168−exports._transaction = function _transaction(store) {
168+export function _transaction(store) {
169169 return store.transaction;
170170};
src/Database/IndexedDB/IDBObjectStore.purs+58−76
@@ -25,19 +25,18 @@ module Database.IndexedDB.IDBObjectStore
2525 , module Database.IndexedDB.IDBIndex
2626 ) where
2727
28−import Prelude (Unit, map, ($), (<$>), (>>>), (<<<))
29−
30−import Control.Monad.Aff (Aff)
31−import Control.Monad.Aff.Compat (EffFnAff, fromEffFnAff)
32−import Data.Foreign (Foreign)
33−import Data.Function.Uncurried as Fn
34−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
35−import Data.Maybe (Maybe)
36−import Data.Nullable (Nullable, toNullable)
37−
3828import Database.IndexedDB.Core
39−import Database.IndexedDB.IDBIndex (count, get, getAllKeys, getKey, openCursor, openKeyCursor)
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)
34+import Database.IndexedDB.IDBIndex (count, get, getAllKeys, getKey, openCursor, openKeyCursor)
4035import 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, ($), (<$>), (>>>), (<<<))
4140
4241--------------------
4342-- TYPES
@@ -46,7 +45,6 @@ import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key, unsafeFromKey, toK
4645-- | Type alias for IndexName
4746type IndexName = String
4847
49−
5048-- | Flags to set on the index.
5149-- |
5250-- | An index has a `unique` flag. When this flag is set, the index enforces that no
@@ -61,18 +59,16 @@ type IndexName = String
6159-- | If the `multiEntry` flag is true, then the one record is added to the index for each
6260-- | of the subkeys.
6361type IndexParameters =
64− { unique :: Boolean
62+ { unique :: Boolean
6563 , multiEntry :: Boolean
6664 }
6765
68−
6966defaultParameters :: IndexParameters
7067defaultParameters =
71− { unique : false
72− , multiEntry : false
68+ { unique: false
69+ , multiEntry: false
7370 }
7471
75−
7672--------------------
7773-- INTERFACES
7874--
@@ -85,23 +81,24 @@ defaultParameters =
8581-- | If add() is used, and if a record with the key already exists the request will fail,
8682-- | with a "ConstraintError" DOMException.
8783add
88− :: forall e key val store. (IDBKey key) => (IDBObjectStore store)
84+ :: forall key val store
85+ . (IDBKey key)
86+ => (IDBObjectStore store)
8987 => store
9088 -> val
9189 -> Maybe key
92− -> Aff (idb :: IDB | e) Key
90+ -> Aff Key
9391add store value key =
94− map toKey $ fromEffFnAff $ Fn.runFn3 _add store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
95−
92+ map toKey $ fromEffectFnAff $ Fn.runFn3 _add store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
9693
9794-- | Deletes all records in store.
9895clear
99− :: forall e store. (IDBObjectStore store)
96+ :: forall store
97+ . (IDBObjectStore store)
10098 => store
101− -> Aff (idb :: IDB | e) Unit
99+ -> Aff Unit
102100clear =
103− fromEffFnAff <<< _clear
104−
101+ fromEffectFnAff <<< _clear
105102
106103-- | Creates a new index in store with the given name, keyPath and options and
107104-- | returns a new IDBIndex. If the keyPath and options define constraints that
@@ -110,47 +107,47 @@ clear =
110107-- |
111108-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
112109createIndex
113− :: forall e store. (IDBObjectStore store)
110+ :: forall store
111+ . (IDBObjectStore store)
114112 => store
115113 -> IndexName
116114 -> KeyPath
117115 -> IndexParameters
118− -> Aff (idb :: IDB | e) Index
116+ -> Aff Index
119117createIndex store name' path params =
120− fromEffFnAff $ Fn.runFn4 _createIndex store name' path params
121−
118+ fromEffectFnAff $ Fn.runFn4 _createIndex store name' path params
122119
123120-- | Deletes records in store with the given key or in the given key range in query.
124121delete
125− :: forall e store. (IDBObjectStore store)
122+ :: forall store
123+ . (IDBObjectStore store)
126124 => store
127125 -> KeyRange
128− -> Aff (idb :: IDB | e) Unit
126+ -> Aff Unit
129127delete store range =
130− fromEffFnAff $ Fn.runFn2 _delete store range
131−
128+ fromEffectFnAff $ Fn.runFn2 _delete store range
132129
133130-- | Deletes the index in store with the given name.
134131-- |
135132-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
136133deleteIndex
137− :: forall e store. (IDBObjectStore store)
134+ :: forall store
135+ . (IDBObjectStore store)
138136 => store
139137 -> IndexName
140− -> Aff (idb :: IDB | e) Unit
138+ -> Aff Unit
141139deleteIndex store name' =
142− fromEffFnAff $ Fn.runFn2 _deleteIndex store name'
143−
140+ fromEffectFnAff $ Fn.runFn2 _deleteIndex store name'
144141
145142-- | Returns an IDBIndex for the index named name in store.
146143index
147− :: forall e store. (IDBObjectStore store)
144+ :: forall store
145+ . (IDBObjectStore store)
148146 => store
149147 -> IndexName
150− -> Aff (idb :: IDB | e) Index
148+ -> Aff Index
151149index store name' =
152− fromEffFnAff $ Fn.runFn2 _index store name'
153−
150+ fromEffectFnAff $ Fn.runFn2 _index store name'
154151
155152-- | Adds or updates a record in store with the given value and key.
156153-- |
@@ -159,14 +156,15 @@ index store name' =
159156-- |
160157-- | If put() is used, any existing record with the key will be replaced.
161158put
162− :: forall e val key store. (IDBKey key) => (IDBObjectStore store)
159+ :: forall val key store
160+ . (IDBKey key)
161+ => (IDBObjectStore store)
163162 => store
164163 -> val
165164 -> Maybe key
166− -> Aff (idb :: IDB | e) Key
165+ -> Aff Key
167166put store value key =
168− map toKey $ fromEffFnAff $ Fn.runFn3 _put store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
169−
167+ map toKey $ fromEffectFnAff $ Fn.runFn3 _put store value (toNullable $ (toKey >>> unsafeFromKey) <$> key)
170168
171169--------------------
172170-- ATTRIBUTES
@@ -178,7 +176,6 @@ autoIncrement
178176autoIncrement =
179177 _autoIncrement
180178
181−
182179--| Returns a list of the names of indexes in the store.
183180indexNames
184181 :: ObjectStore
@@ -186,7 +183,6 @@ indexNames
186183indexNames =
187184 _indexNames
188185
189−
190186-- | Returns the key path of the store, or empty array if none
191187keyPath
192188 :: ObjectStore
@@ -194,7 +190,6 @@ keyPath
194190keyPath =
195191 _keyPath
196192
197−
198193-- | Returns the name of the store.
199194name
200195 :: ObjectStore
@@ -202,7 +197,6 @@ name
202197name =
203198 _name
204199
205−
206200-- | Returns the associated transaction.
207201transaction
208202 :: ObjectStore
@@ -210,65 +204,53 @@ transaction
210204transaction =
211205 _transaction
212206
213−
214207--------------------
215208-- FFI
216209--
217210foreign import _add
218− :: forall e val store
219− . Fn3 store val (Nullable Foreign) (EffFnAff (idb :: IDB | e) Foreign)
220−
211+ :: forall val store
212+ . Fn3 store val (Nullable Foreign) (EffectFnAff Foreign)
221213
222214foreign import _autoIncrement
223215 :: ObjectStore
224216 -> Boolean
225217
226−
227218foreign import _clear
228− :: forall e store
229− . store
230− -> EffFnAff (idb :: IDB | e) Unit
231−
219+ :: forall store
220+ . store
221+ -> EffectFnAff Unit
232222
233223foreign import _createIndex
234− :: forall e store
235− . Fn4 store String (Array String) { unique :: Boolean, multiEntry :: Boolean } (EffFnAff (idb :: IDB | e) Index)
236−
224+ :: forall store
225+ . Fn4 store String (Array String) { unique :: Boolean, multiEntry :: Boolean } (EffectFnAff Index)
237226
238227foreign import _delete
239− :: forall e store
240− . Fn2 store KeyRange (EffFnAff (idb :: IDB | e) Unit)
241−
228+ :: forall store
229+ . Fn2 store KeyRange (EffectFnAff Unit)
242230
243231foreign import _deleteIndex
244− :: forall e store
245− . Fn2 store String (EffFnAff (idb :: IDB | e) Unit)
246−
232+ :: forall store
233+ . Fn2 store String (EffectFnAff Unit)
247234
248235foreign import _index
249− :: forall e store
250− . Fn2 store String (EffFnAff (idb :: IDB | e) Index)
251−
236+ :: forall store
237+ . Fn2 store String (EffectFnAff Index)
252238
253239foreign import _indexNames
254240 :: ObjectStore
255241 -> Array String
256242
257−
258243foreign import _keyPath
259244 :: ObjectStore
260245 -> Array String
261246
262−
263247foreign import _name
264248 :: ObjectStore
265249 -> String
266250
267−
268251foreign import _put
269− :: forall e val store
270− . Fn3 store val (Nullable Foreign) (EffFnAff (idb :: IDB | e) Foreign)
271−
252+ :: forall val store
253+ . Fn3 store val (Nullable Foreign) (EffectFnAff Foreign)
272254
273255foreign import _transaction
274256 :: ObjectStore
src/Database/IndexedDB/IDBTransaction.js+9−9
@@ -1,4 +1,4 @@
1−exports._abort = function _abort(tx) {
1+export function _abort(tx) {
22 return function aff(error, success) {
33 try {
44 tx.abort();
@@ -13,17 +13,17 @@ exports._abort = function _abort(tx) {
1313 };
1414};
1515
16−exports._db = function _db(tx) {
16+export function _db(tx) {
1717 return tx.db;
1818};
1919
20−exports._error = function _error(tx) {
20+export function _error(tx) {
2121 return tx.error == null
2222 ? null
2323 : tx.error;
2424};
2525
26−exports._mode = function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
26+export function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
2727 if (tx.mode === 'readwrite') {
2828 return ReadWrite;
2929 } else if (tx.mode === 'versionchange') {
@@ -33,7 +33,7 @@ exports._mode = function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
3333 return ReadOnly;
3434};
3535
36−exports._objectStore = function _objectStore(tx, name) {
36+export function _objectStore(tx, name) {
3737 return function aff(error, success) {
3838 try {
3939 const store = tx.objectStore(name);
@@ -48,11 +48,11 @@ exports._objectStore = function _objectStore(tx, name) {
4848 };
4949};
5050
51−exports._objectStoreNames = function _objectStoreNames(tx) {
51+export function _objectStoreNames(tx) {
5252 return tx.objectStoreNames;
5353};
5454
55−exports._onAbort = function _onAbort(tx, f) {
55+export function _onAbort(tx, f) {
5656 return function aff(error, success) {
5757 tx.onabort = function onabort() {
5858 f();
@@ -65,7 +65,7 @@ exports._onAbort = function _onAbort(tx, f) {
6565 };
6666};
6767
68−exports._onComplete = function _onComplete(tx, f) {
68+export function _onComplete(tx, f) {
6969 return function aff(error, success) {
7070 tx.oncomplete = function oncomplete() {
7171 f();
@@ -78,7 +78,7 @@ exports._onComplete = function _onComplete(tx, f) {
7878 };
7979};
8080
81−exports._onError = function _onError(tx, f) {
81+export function _onError(tx, f) {
8282 return function aff(error, success) {
8383 tx.onerror = function onerror(e) {
8484 f(e.target.error)();
src/Database/IndexedDB/IDBTransaction.purs+40−59
@@ -14,19 +14,17 @@ module Database.IndexedDB.IDBTransaction
1414 , onError
1515 ) where
1616
17−import Prelude (Unit, ($), (<<<), (>>>))
18−
19−import Control.Monad.Aff (Aff)
20−import Control.Monad.Aff.Compat (EffFnAff, fromEffFnAff)
21−import Control.Monad.Eff (Eff)
22−import Control.Monad.Eff.Exception (Error)
23−import Data.Function.Uncurried as Fn
24−import Data.Function.Uncurried (Fn2, Fn4)
25−import Data.Maybe (Maybe)
26−import Data.Nullable (Nullable, toMaybe)
27−
2817import Database.IndexedDB.Core
2918
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, ($), (<<<), (>>>))
3028
3129--------------------
3230-- INTERFACES
@@ -35,21 +33,22 @@ import Database.IndexedDB.Core
3533-- | Aborts the transaction. All pending requests will fail with a "AbortError"
3634-- | DOMException and all changes made to the database will be reverted.
3735abort
38− :: forall e tx. (IDBTransaction tx)
36+ :: forall tx
37+ . (IDBTransaction tx)
3938 => tx
40− -> Aff (idb :: IDB | e) Unit
39+ -> Aff Unit
4140abort =
42− fromEffFnAff <<< _abort
41+ fromEffectFnAff <<< _abort
4342
4443-- | Returns an IDBObjectStore in the transaction's scope.
4544objectStore
46− :: forall e tx. (IDBTransaction tx)
45+ :: forall tx
46+ . (IDBTransaction tx)
4747 => tx
4848 -> String
49− -> Aff (idb :: IDB | e) ObjectStore
49+ -> Aff ObjectStore
5050objectStore tx name =
51− fromEffFnAff $ Fn.runFn2 _objectStore tx name
52−
51+ fromEffectFnAff $ Fn.runFn2 _objectStore tx name
5352
5453--------------------
5554-- ATTRIBUTES
@@ -62,7 +61,6 @@ db
6261db =
6362 _db
6463
65−
6664-- | If the transaction was aborted, returns the error (a DOMException) providing the reason.
6765error
6866 :: Transaction
@@ -70,7 +68,6 @@ error
7068error =
7169 _error >>> toMaybe
7270
73−
7471-- | Returns the mode the transaction was created with (`ReadOnly|ReadWrite`)
7572-- | , or `VersionChange` for an upgrade transaction.
7673mode
@@ -79,7 +76,6 @@ mode
7976mode =
8077 Fn.runFn4 _mode ReadOnly ReadWrite VersionChange
8178
82−
8379-- | Returns a list of the names of object stores in the transaction’s scope.
8480-- | For an upgrade transaction this is all object stores in the database.
8581objectStoreNames
@@ -88,85 +84,70 @@ objectStoreNames
8884objectStoreNames =
8985 _objectStoreNames
9086
91−
9287--------------------
9388-- EVENT HANDLERS
9489--
9590
9691-- | Event handler for the `abort` event.
9792onAbort
98− :: forall e e'
99− . Transaction
100− -> Eff ( | e') Unit
101− -> Aff (idb :: IDB | e) Unit
93+ :: Transaction
94+ -> Effect Unit
95+ -> Aff Unit
10296onAbort db' f =
103− fromEffFnAff $ Fn.runFn2 _onAbort db' f
104−
97+ fromEffectFnAff $ Fn.runFn2 _onAbort db' f
10598
10699-- | Event handler for the `complete` event.
107100onComplete
108− :: forall e e'
109− . Transaction
110− -> Eff ( | e') Unit
111− -> Aff (idb :: IDB | e) Unit
101+ :: Transaction
102+ -> Effect Unit
103+ -> Aff Unit
112104onComplete db' f =
113− fromEffFnAff $ Fn.runFn2 _onComplete db' f
114−
105+ fromEffectFnAff $ Fn.runFn2 _onComplete db' f
115106
116107-- | Event handler for the `error` event.
117108onError
118− :: forall e e'
119− . Transaction
120− -> (Error -> Eff ( | e') Unit)
121− -> Aff (idb :: IDB | e) Unit
109+ :: Transaction
110+ -> (Error -> Effect Unit)
111+ -> Aff Unit
122112onError db' f =
123− fromEffFnAff $ Fn.runFn2 _onError db' f
124−
113+ fromEffectFnAff $ Fn.runFn2 _onError db' f
125114
126115--------------------
127116-- FFI
128117--
129118
130119foreign import _abort
131− :: forall tx e
132− . tx
133− -> EffFnAff (idb :: IDB | e) Unit
134−
120+ :: forall tx
121+ . tx
122+ -> EffectFnAff Unit
135123
136124foreign import _db
137125 :: Transaction
138126 -> Database
139127
140−
141128foreign import _error
142129 :: Transaction
143130 -> (Nullable Error)
144131
145−
146132foreign import _mode
147133 :: Fn4 TransactionMode TransactionMode TransactionMode Transaction TransactionMode
148134
149−
150135foreign import _objectStoreNames
151136 :: Transaction
152137 -> Array String
153138
154−
155139foreign import _objectStore
156− :: forall tx e
157− . Fn2 tx String (EffFnAff (idb :: IDB | e) ObjectStore)
158−
140+ :: forall tx
141+ . Fn2 tx String (EffectFnAff ObjectStore)
159142
160143foreign import _onAbort
161− :: forall tx e e'
162− . Fn2 tx (Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
163−
144+ :: forall tx
145+ . Fn2 tx (Effect Unit) (EffectFnAff Unit)
164146
165147foreign import _onComplete
166− :: forall tx e e'
167− . Fn2 tx (Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
168−
148+ :: forall tx
149+ . Fn2 tx (Effect Unit) (EffectFnAff Unit)
169150
170151foreign import _onError
171− :: forall tx e e'
172− . Fn2 tx (Error -> Eff ( | e') Unit) (EffFnAff (idb :: IDB | e) Unit)
152+ :: forall tx
153+ . Fn2 tx (Error -> Effect Unit) (EffectFnAff Unit)
test/Main.purs+971−910
@@ -2,1004 +2,1060 @@ module Test.Main where
22
33import Prelude
44
5−import Control.Monad.Aff (Aff, launchAff, launchAff_, forkAff, delay, attempt)
6−import Control.Monad.Aff.AVar (AVAR, AVar, makeVar, makeEmptyVar, readVar, 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, name)
11−import Control.Monad.Eff.Now (NOW, now)
12−import Data.Date as Date
13−import Data.DateTime as DateTime
14−import Data.DateTime (DateTime(..), Time(..))
15−import Data.DateTime.Instant (toDateTime)
16−import Data.Either (Either(..))
17−import Data.Enum (toEnum)
18−import Data.Maybe (Maybe(..), isNothing, maybe)
19−import Data.Array (head, drop)
20−import Data.Time.Duration (Milliseconds(..))
21−import Data.Traversable (traverse)
22−import Data.Tuple (Tuple(..), uncurry)
23−import Test.Spec (describe, describeOnly, it)
24−import Test.Spec.Assertions (shouldEqual, fail)
25−import Test.Spec.Mocha (MOCHA, runMocha)
26−
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−
5+import Data.Array (head, drop)
6+import Data.Date as Date
7+import Data.DateTime (DateTime(..), Time(..))
8+import Data.DateTime.Instant (toDateTime)
9+import Data.Either (Either(..))
10+import Data.Enum (toEnum)
11+import Data.Maybe (Maybe(..), isNothing, maybe)
12+import Data.Time.Duration (Milliseconds(..))
13+import Data.Traversable (traverse)
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)
32+import Test.Spec (describe, it)
33+import Test.Spec.Assertions (shouldEqual, fail)
34+import Test.Spec.Reporter (consoleReporter)
35+import Test.Spec.Runner (runSpec)
3736
3837infixr 7 Tuple as :+:
3938
40−launchAff' :: forall a e. Aff e a -> Eff e Unit
39+launchAff' :: forall a. Aff a -> Effect Unit
4140launchAff' =
42− launchAff_
43−
44−
45−modifyVar :: forall eff a. (a -> a) -> AVar a -> Aff (avar :: AVAR | eff) Unit
46−modifyVar fn v = do
47− val <- takeVar v
48− putVar (fn val) v
49−
50−
51−-- main :: forall eff. Eff (now :: NOW, mocha :: MOCHA, idb :: IDB, exception :: EXCEPTION, avar :: AVAR | eff) Unit
52−main = runMocha do
53− describe "IDBFactory" do
54− let
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
47+
48+main :: Effect Unit
49+main = do
50+ launchAff_ $ runSpec [ consoleReporter ] $ do
51+ describe "IDBFactory" do
52+ let
5553 tearDown name version db = do
5654 IDBDatabase.close db
5755 version' <- IDBFactory.deleteDatabase name
56+ liftEffect $ log $ show version'
5857 version' `shouldEqual` version
5958
60− it "open default" do
61− let name = "db-default"
59+ it "open default" do
60+ let
61+ name = "db-default"
6262 version = 1
63− db <- IDBFactory.open name Nothing
64− { onUpgradeNeeded : Nothing
65− , onBlocked : Nothing
66− }
67− IDBDatabase.name db `shouldEqual` name
68− tearDown name version db
69−
63+ db <- IDBFactory.open name Nothing
64+ { onUpgradeNeeded: Nothing
65+ , onBlocked: Nothing
66+ }
67+ IDBDatabase.name db `shouldEqual` name
68+ tearDown name version db
7069
71− it "open specific version" do
72− let name = "db-specific"
70+ it "open specific version" do
71+ let
72+ name = "db-specific"
7373 version = 14
74− db <- IDBFactory.open name (Just version)
75− { onUpgradeNeeded : Nothing
76− , onBlocked : Nothing
77− }
78− IDBDatabase.name db `shouldEqual` name
79− tearDown name version db
80−
74+ db <- IDBFactory.open name (Just version)
75+ { onUpgradeNeeded: Nothing
76+ , onBlocked: Nothing
77+ }
78+ IDBDatabase.name db `shouldEqual` name
79+ tearDown name version db
8180
82− it "open specific version -> close -> open latest" do
83− let name = "db-latest"
81+ it "open specific version -> close -> open latest" do
82+ let
83+ name = "db-latest"
8484 version = 14
85− db01 <- IDBFactory.open name (Just version)
86− { onUpgradeNeeded : Nothing
87− , onBlocked : Nothing
88− }
89− IDBDatabase.name db01 `shouldEqual` name
90− IDBDatabase.close db01
91− db02 <- IDBFactory.open name Nothing
92− { onUpgradeNeeded : Nothing
93− , onBlocked : Nothing
94− }
95− tearDown name version db02
96−
97− it "open + onUpgradeNeed" do
98− let name = "db-upgrade-needed"
85+ db01 <- IDBFactory.open name (Just version)
86+ { onUpgradeNeeded: Nothing
87+ , onBlocked: Nothing
88+ }
89+ IDBDatabase.name db01 `shouldEqual` name
90+ IDBDatabase.close db01
91+ db02 <- IDBFactory.open name Nothing
92+ { onUpgradeNeeded: Nothing
93+ , onBlocked: Nothing
94+ }
95+ tearDown name version db02
96+
97+ it "open + onUpgradeNeed" do
98+ let
99+ name = "db-upgrade-needed"
99100 version = 1
100101 callback (Tuple varName varVersion) db _ { oldVersion } = do
101− _ <- launchAff $ modifyVar (const $ IDBDatabase.name db) varName
102− _ <- launchAff $ modifyVar (const $ oldVersion) varVersion
102+ _ <- launchAff $ modifyAVar (const $ IDBDatabase.name db) varName
103+ _ <- launchAff $ modifyAVar (const $ oldVersion) varVersion
103104 pure unit
104− varName <- makeVar "-"
105− varVersion <- makeVar (-1)
106− db <- IDBFactory.open name Nothing
107− { onUpgradeNeeded : Just (callback (Tuple varName varVersion))
108− , onBlocked : Nothing
109− }
110− name' <- readVar varName
111− version' <- readVar varVersion
112− name' `shouldEqual` name
113− version' `shouldEqual` 0
114− tearDown name version db
115−
116− it "open + onBlocked" do
117− let name = "db-blocked"
105+ varName <- AVar.new "-"
106+ varVersion <- AVar.new (-1)
107+ db <- IDBFactory.open name Nothing
108+ { onUpgradeNeeded: Just (callback (Tuple varName varVersion))
109+ , onBlocked: Nothing
110+ }
111+ name' <- AVar.read varName
112+ version' <- AVar.read varVersion
113+ name' `shouldEqual` name
114+ version' `shouldEqual` 0
115+ tearDown name version db
116+
117+ it "open + onBlocked" do
118+ let
119+ name = "db-blocked"
118120 version = 14
119121 callback var = do
120− _ <- launchAff $ modifyVar (const $ "db-blocked") var
122+ _ <- launchAff $ modifyAVar (const $ "db-blocked") var
121123 pure unit
122124
123− var <- makeVar "-"
124− db01 <- IDBFactory.open name Nothing
125− { onUpgradeNeeded : Nothing
126− , onBlocked : Nothing
127− }
128− _ <- forkAff do
129− delay (Milliseconds 100.0)
130− IDBDatabase.close db01
125+ var <- AVar.new "-"
126+ db01 <- IDBFactory.open name Nothing
127+ { onUpgradeNeeded: Nothing
128+ , onBlocked: Nothing
129+ }
130+ _ <- forkAff do
131+ delay (Milliseconds 100.0)
132+ IDBDatabase.close db01
131133
132− db02 <- IDBFactory.open name (Just version)
133− { onUpgradeNeeded : Nothing
134− , onBlocked : Just (callback var)
135− }
136− name' <- readVar var
137− name' `shouldEqual` name
138− tearDown name version db02
139−
140− describe "IDBKeyRange" do
141− it "only(int)" do
142− let key = 14
134+ db02 <- IDBFactory.open name (Just version)
135+ { onUpgradeNeeded: Nothing
136+ , onBlocked: Just (callback var)
137+ }
138+ name' <- AVar.read var
139+ name' `shouldEqual` name
140+ tearDown name version db02
141+
142+ describe "IDBKeyRange" do
143+ it "only(int)" do
144+ let
145+ key = 14
143146 range = IDBKeyRange.only key
144− IDBKeyRange.includes range (toKey key) `shouldEqual` true
147+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
145148
146− it "only(string)" do
147− let key = "patate"
149+ it "only(string)" do
150+ let
151+ key = "patate"
148152 range = IDBKeyRange.only key
149− IDBKeyRange.includes range (toKey key) `shouldEqual` true
153+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
150154
151− it "only(float)" do
152− let key = 14.42
155+ it "only(float)" do
156+ let
157+ key = 14.42
153158 range = IDBKeyRange.only key
154− IDBKeyRange.includes range (toKey key) `shouldEqual` true
159+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
155160
156− it "only(date)" do
157− let mkey = DateTime
161+ it "only(date)" do
162+ let
163+ mkey = DateTime
158164 <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
159165 <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
160166
161− case mkey of
162− Nothing ->
163− fail "unable to create datetime"
164− Just key -> do
165− let range = IDBKeyRange.only key
166− IDBKeyRange.includes range (toKey key) `shouldEqual` true
167+ case mkey of
168+ Nothing ->
169+ fail "unable to create datetime"
170+ Just key -> do
171+ let range = IDBKeyRange.only key
172+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
167173
168− it "only([int])" do
169− let key = [14, 42]
174+ it "only([int])" do
175+ let
176+ key = [ 14, 42 ]
170177 range = IDBKeyRange.only key
171− IDBKeyRange.includes range (toKey key) `shouldEqual` true
178+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
172179
173− it "only([string])" do
174− let key = ["patate", "autruche"]
180+ it "only([string])" do
181+ let
182+ key = [ "patate", "autruche" ]
175183 range = IDBKeyRange.only key
176− IDBKeyRange.includes range (toKey key) `shouldEqual` true
184+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
177185
178− it "lowerBound(14, open)" do
179− let key = 14
180− open = true
186+ it "lowerBound(14, open)" do
187+ let
188+ key = 14
189+ open = true
181190 range = IDBKeyRange.lowerBound key open
182− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
183− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
184− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
185−
186− it "lowerBound(14, close)" do
187− let key = 14
188− open = false
191+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
192+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
193+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
194+
195+ it "lowerBound(14, close)" do
196+ let
197+ key = 14
198+ open = false
189199 range = IDBKeyRange.lowerBound key open
190− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
191− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
192− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
193−
194− it "upperBound(14, open)" do
195− let key = 14
196− open = true
200+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
201+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
202+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
203+
204+ it "upperBound(14, open)" do
205+ let
206+ key = 14
207+ open = true
197208 range = IDBKeyRange.upperBound key open
198− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
199− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
200− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
201−
202− it "upperBound(14, close)" do
203− let key = 14
204− open = false
209+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
210+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
211+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
212+
213+ it "upperBound(14, close)" do
214+ let
215+ key = 14
216+ open = false
205217 range = IDBKeyRange.upperBound key open
206− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
207− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
208− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
209−
210− it "bound(42, 14, open, open) => Nothing" do
211− let lower = 42
212− upper = 14
218+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
219+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
220+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
221+
222+ it "bound(42, 14, open, open) => Nothing" do
223+ let
224+ lower = 42
225+ upper = 14
213226 lowerOpen = true
214227 upperOpen = true
215− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
216− isNothing mrange `shouldEqual` true
228+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
229+ isNothing mrange `shouldEqual` true
217230
218− it "bound(14, 42, open, open)" do
219− let lower = 14
220− upper = 42
231+ it "bound(14, 42, open, open)" do
232+ let
233+ lower = 14
234+ upper = 42
221235 lowerOpen = true
222236 upperOpen = true
223− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
224− case mrange of
225− Nothing ->
226− fail "invalid range provided"
227− Just range -> do
228− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
229− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
230− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
231− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
232− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
233− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
234−
235− it "bound(14, 42, open, close)" do
236− let lower = 14
237− upper = 42
237+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
238+ case mrange of
239+ Nothing ->
240+ fail "invalid range provided"
241+ Just range -> do
242+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
243+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
244+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
245+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
246+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
247+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
248+
249+ it "bound(14, 42, open, close)" do
250+ let
251+ lower = 14
252+ upper = 42
238253 lowerOpen = true
239254 upperOpen = false
240− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
241− case mrange of
242− Nothing ->
243− fail "invalid range provided"
244− Just range -> do
245− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
246− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
247− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
248− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
249− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
250− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
251−
252− it "bound(14, 42, close, open)" do
253− let lower = 14
254− upper = 42
255+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
256+ case mrange of
257+ Nothing ->
258+ fail "invalid range provided"
259+ Just range -> do
260+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
261+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
262+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
263+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
264+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
265+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
266+
267+ it "bound(14, 42, close, open)" do
268+ let
269+ lower = 14
270+ upper = 42
255271 lowerOpen = false
256272 upperOpen = true
257− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
258− case mrange of
259− Nothing ->
260− fail "invalid range provided"
261− Just range -> do
262− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
263− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
264− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
265− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
266− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
267− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
268−
269− it "bound(14, 42, close, close)" do
270− let lower = 14
271− upper = 42
273+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
274+ case mrange of
275+ Nothing ->
276+ fail "invalid range provided"
277+ Just range -> do
278+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
279+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
280+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
281+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
282+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
283+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
284+
285+ it "bound(14, 42, close, close)" do
286+ let
287+ lower = 14
288+ upper = 42
272289 lowerOpen = false
273290 upperOpen = false
274− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
275− case mrange of
276− Nothing ->
277− fail "invalid range provided"
278− Just range -> do
279− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
280− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
281− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
282− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
283− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
284− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
285−
286− it "can access attributes of a range" do
287− let range = IDBKeyRange.lowerBound 14 false
288− IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
289− IDBKeyRange.upper range `shouldEqual` none
290− IDBKeyRange.lowerOpen range `shouldEqual` false
291− IDBKeyRange.upperOpen range `shouldEqual` true
292−
293− describe "IDBDatabase" do
294− let
291+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
292+ case mrange of
293+ Nothing ->
294+ fail "invalid range provided"
295+ Just range -> do
296+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
297+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
298+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
299+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
300+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
301+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
302+
303+ it "can access attributes of a range" do
304+ let range = IDBKeyRange.lowerBound 14 false
305+ IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
306+ IDBKeyRange.upper range `shouldEqual` none
307+ IDBKeyRange.lowerOpen range `shouldEqual` false
308+ IDBKeyRange.upperOpen range `shouldEqual` true
309+
310+ describe "IDBDatabase" do
311+ let
295312 tearDown db = do
296313 IDBDatabase.close db
297314 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
298315 pure unit
299316
300317 setup storeParams = do
301− let onUpgradeNeeded var db _ _ = launchAff' do
302− store <- IDBDatabase.createObjectStore db "store" storeParams
303− _ <- putVar { db, store } var
304− pure unit
305−
306− var <- makeEmptyVar
307− db <- IDBFactory.open "db" Nothing
308− { onUpgradeNeeded : Just (onUpgradeNeeded var)
309− , onBlocked : Nothing
318+ let
319+ onUpgradeNeeded var db _ _ = launchAff' do
320+ store <- IDBDatabase.createObjectStore db "store" storeParams
321+ _ <- AVar.put { db, store } var
322+ pure unit
323+
324+ var <- AVar.empty
325+ _ <- IDBFactory.open "db" Nothing
326+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
327+ , onBlocked: Nothing
310328 }
311329
312− takeVar var
313−
314− it "createObjectStore (keyPath: [], autoIncrement: true)" do
315− { db, store } <- setup { keyPath: [], autoIncrement: true }
316− IDBObjectStore.name store `shouldEqual` "store"
317− IDBObjectStore.keyPath store `shouldEqual` []
318− IDBObjectStore.autoIncrement store `shouldEqual` true
319− IDBObjectStore.indexNames store `shouldEqual` []
320− tearDown db
321−
322− it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
323− { db, store } <- setup { keyPath: ["patate"], autoIncrement: true }
324− IDBObjectStore.name store `shouldEqual` "store"
325− IDBObjectStore.keyPath store `shouldEqual` ["patate"]
326− IDBObjectStore.autoIncrement store `shouldEqual` true
327− IDBObjectStore.indexNames store `shouldEqual` []
328− tearDown db
329−
330− it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
331− { db, store } <- setup { keyPath: ["patate", "autruche"], autoIncrement: false }
332− IDBObjectStore.name store `shouldEqual` "store"
333− IDBObjectStore.keyPath store `shouldEqual` ["patate", "autruche"]
334− IDBObjectStore.autoIncrement store `shouldEqual` false
335− IDBObjectStore.indexNames store `shouldEqual` []
336− tearDown db
337−
338− it "deleteObjectStore" do
339− let onUpgradeNeeded var db _ _ = launchAff' do
330+ AVar.take var
331+
332+ it "createObjectStore (keyPath: [], autoIncrement: true)" do
333+ { db, store } <- setup { keyPath: [], autoIncrement: true }
334+ IDBObjectStore.name store `shouldEqual` "store"
335+ IDBObjectStore.keyPath store `shouldEqual` []
336+ IDBObjectStore.autoIncrement store `shouldEqual` true
337+ IDBObjectStore.indexNames store `shouldEqual` []
338+ tearDown db
339+
340+ it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
341+ { db, store } <- setup { keyPath: [ "patate" ], autoIncrement: true }
342+ IDBObjectStore.name store `shouldEqual` "store"
343+ IDBObjectStore.keyPath store `shouldEqual` [ "patate" ]
344+ IDBObjectStore.autoIncrement store `shouldEqual` true
345+ IDBObjectStore.indexNames store `shouldEqual` []
346+ tearDown db
347+
348+ it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
349+ { db, store } <- setup { keyPath: [ "patate", "autruche" ], autoIncrement: false }
350+ IDBObjectStore.name store `shouldEqual` "store"
351+ IDBObjectStore.keyPath store `shouldEqual` [ "patate", "autruche" ]
352+ IDBObjectStore.autoIncrement store `shouldEqual` false
353+ IDBObjectStore.indexNames store `shouldEqual` []
354+ tearDown db
355+
356+ it "deleteObjectStore" do
357+ let
358+ onUpgradeNeeded var db _ _ = launchAff' do
340359 _ <- IDBDatabase.deleteObjectStore db "store"
341− putVar true var
342−
343− var <- makeEmptyVar
344− { db, store } <- setup IDBDatabase.defaultParameters
345− IDBDatabase.close db
346− db' <- IDBFactory.open "db" (Just 999) { onUpgradeNeeded : Just (onUpgradeNeeded var)
347− , onBlocked : Nothing
348− }
349− deleted <- takeVar var
350− deleted `shouldEqual` true
351− tearDown db'
352−
360+ AVar.put true var
361+
362+ var <- AVar.empty
363+ { db } <- setup IDBDatabase.defaultParameters
364+ IDBDatabase.close db
365+ db' <- IDBFactory.open "db" (Just 999)
366+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
367+ , onBlocked: Nothing
368+ }
369+ deleted <- AVar.take var
370+ deleted `shouldEqual` true
371+ tearDown db'
353372
354− describe "IDBObjectStore" do
355− let
373+ describe "IDBObjectStore" do
374+ let
356375 tearDown db = do
357376 IDBDatabase.close db
358377 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
359378 pure unit
360379
361380 setup { storeParams, onUpgradeNeeded } = do
362− let onUpgradeNeeded' var db _ _ = launchAff' do
363− store <- IDBDatabase.createObjectStore db "store" storeParams
364− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure store)
365− putVar { db, store } var
366−
367− var <- makeEmptyVar
368− db <- IDBFactory.open "db" Nothing
369− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
370− , onBlocked : Nothing
381+ let
382+ onUpgradeNeeded' var db _ _ = launchAff' do
383+ store <- IDBDatabase.createObjectStore db "store" storeParams
384+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure store)
385+ AVar.put { db, store } var
386+
387+ var <- AVar.empty
388+ _ <- IDBFactory.open "db" Nothing
389+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
390+ , onBlocked: Nothing
371391 }
372392
373− takeVar var
374−
375− it "add()" do
376− date <- liftEff $ toDateTime <$> now
377− { db } <- setup
378− { storeParams: { autoIncrement: true, keyPath: [] }
379− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
380− -- no key
381− key <- IDBObjectStore.add store "patate" none
382− (toKey 1) `shouldEqual` key
383−
384− -- int key
385− key' <- IDBObjectStore.add store "patate" (Just 14)
386− (toKey 14) `shouldEqual` key'
387−
388− -- number key
389− key'' <- IDBObjectStore.add store "patate" (Just 14.42)
390− (toKey 14.42) `shouldEqual` key''
391−
392− -- string key
393− key''' <- IDBObjectStore.add store "patate" (Just "key")
394− (toKey "key") `shouldEqual` key'''
395−
396− -- date key
397− key'''' <- IDBObjectStore.add store "patate" (Just date)
398− (toKey date) `shouldEqual` key''''
399−
400− -- array key
401− key''''' <- IDBObjectStore.add store "patate" (Just $ toKey [14, 42])
402− (toKey [14, 42]) `shouldEqual` key'''''
403− }
404− tearDown db
405−
406− it "clear()" do
407− { db } <- setup
408− { storeParams: IDBDatabase.defaultParameters
409− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
410− key <- IDBObjectStore.add store "patate" (Just 14)
411− _ <- IDBObjectStore.clear store
412− val <- IDBObjectStore.get store (IDBKeyRange.only key)
413− val `shouldEqual` (Nothing :: Maybe String)
414− }
415− tearDown db
416−
417− it "count()" do
418− { db } <- setup
419− { storeParams: IDBDatabase.defaultParameters
420− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
421− _ <- IDBObjectStore.add store "patate" (Just 14)
422− _ <- IDBObjectStore.add store "autruche" (Just 42)
423− n <- IDBObjectStore.count store Nothing
424− n `shouldEqual` 2
425− }
426− tearDown db
427−
428− it "getKey()" do
429− { db } <- setup
430− { storeParams: IDBDatabase.defaultParameters
431− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
432− key <- IDBObjectStore.add store "patate" (Just 14)
433− mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
434− mkey `shouldEqual` (Just key)
435−
436− mkey' <- IDBObjectStore.getKey store (IDBKeyRange.only 42)
437− mkey' `shouldEqual` none
393+ AVar.take var
394+
395+ it "add()" do
396+ date <- liftEffect $ toDateTime <$> now
397+ { db } <- setup
398+ { storeParams: { autoIncrement: true, keyPath: [] }
399+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
400+ -- no key
401+ key <- IDBObjectStore.add store "patate" none
402+ (toKey 1) `shouldEqual` key
403+
404+ -- int key
405+ key' <- IDBObjectStore.add store "patate" (Just 14)
406+ (toKey 14) `shouldEqual` key'
407+
408+ -- number key
409+ key'' <- IDBObjectStore.add store "patate" (Just 14.42)
410+ (toKey 14.42) `shouldEqual` key''
411+
412+ -- string key
413+ key''' <- IDBObjectStore.add store "patate" (Just "key")
414+ (toKey "key") `shouldEqual` key'''
415+
416+ -- date key
417+ key'''' <- IDBObjectStore.add store "patate" (Just date)
418+ (toKey date) `shouldEqual` key''''
419+
420+ -- array key
421+ key''''' <- IDBObjectStore.add store "patate" (Just $ toKey [ 14, 42 ])
422+ (toKey [ 14, 42 ]) `shouldEqual` key'''''
423+ }
424+ tearDown db
425+
426+ it "clear()" do
427+ { db } <- setup
428+ { storeParams: IDBDatabase.defaultParameters
429+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
430+ key <- IDBObjectStore.add store "patate" (Just 14)
431+ _ <- IDBObjectStore.clear store
432+ val <- IDBObjectStore.get store (IDBKeyRange.only key)
433+ val `shouldEqual` (Nothing :: Maybe String)
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+ }
459+ tearDown db
460+
461+ it "getAllKeys()" do
462+ { db } <- setup
463+ { storeParams: IDBDatabase.defaultParameters
464+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
465+ key1 <- IDBObjectStore.add store "patate" (Just 14)
466+ key2 <- IDBObjectStore.add store "autruche" (Just 42)
467+ key3 <- IDBObjectStore.add store 14 (Just 1337)
468+
469+ -- no bounds
470+ keys <- IDBObjectStore.getAllKeys store Nothing Nothing
471+ keys `shouldEqual` [ key1, key2, key3 ]
472+
473+ -- lower bound
474+ keys' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
475+ keys' `shouldEqual` [ key2, key3 ]
476+
477+ -- upper bound
478+ keys'' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
479+ keys'' `shouldEqual` [ key1, key2 ]
480+
481+ -- count
482+ keys''' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
483+ keys''' `shouldEqual` [ key1, key2 ]
438484 }
439− tearDown db
440−
441− it "getAllKeys()" do
442− { db } <- setup
443− { storeParams: IDBDatabase.defaultParameters
444− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
445− key1 <- IDBObjectStore.add store "patate" (Just 14)
446− key2 <- IDBObjectStore.add store "autruche" (Just 42)
447− key3 <- IDBObjectStore.add store 14 (Just 1337)
448−
449− -- no bounds
450− keys <- IDBObjectStore.getAllKeys store Nothing Nothing
451− keys `shouldEqual` [key1, key2, key3]
452−
453− -- lower bound
454− keys' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
455− keys' `shouldEqual` [key2, key3]
456−
457− -- upper bound
458− keys'' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
459− keys'' `shouldEqual` [key1, key2]
460−
461− -- count
462− keys''' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
463− keys''' `shouldEqual` [key1, key2]
464− }
465− tearDown db
466−
467− it "openCursor()" do
468− let cb =
469− { onSuccess : const $ pure unit
470− , onError : show >>> fail >>> launchAff'
485+ tearDown db
486+
487+ it "openCursor()" do
488+ let
489+ cb =
490+ { onSuccess: const $ pure unit
491+ , onError: show >>> fail >>> launchAff'
471492 , onComplete: pure unit
472493 }
473− { db } <- setup
474− { storeParams: IDBDatabase.defaultParameters
475− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
476− _ <- IDBObjectStore.openCursor store Nothing Next cb
477− _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
478− _ <- IDBObjectStore.openCursor store Nothing Prev cb
479− _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
480− _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
481− pure unit
482− }
483− tearDown db
494+ { db } <- setup
495+ { storeParams: IDBDatabase.defaultParameters
496+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
497+ _ <- IDBObjectStore.openCursor store Nothing Next cb
498+ _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
499+ _ <- IDBObjectStore.openCursor store Nothing Prev cb
500+ _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
501+ _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
502+ pure unit
503+ }
504+ tearDown db
484505
485− it "openKeyCursor()" do
486− let cb =
487− { onSuccess : const $ pure unit
488− , onError : show >>> fail >>> launchAff'
506+ it "openKeyCursor()" do
507+ let
508+ cb =
509+ { onSuccess: const $ pure unit
510+ , onError: show >>> fail >>> launchAff'
489511 , onComplete: pure unit
490512 }
491− { db } <- setup
492− { storeParams: IDBDatabase.defaultParameters
493− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
494− _ <- IDBObjectStore.openKeyCursor store Nothing Next cb
495− _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique cb
496− _ <- IDBObjectStore.openKeyCursor store Nothing Prev cb
497− _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique cb
498− _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
499− pure unit
500− }
501− tearDown db
513+ { db } <- setup
514+ { storeParams: IDBDatabase.defaultParameters
515+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
516+ _ <- IDBObjectStore.openKeyCursor store Nothing Next cb
517+ _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique cb
518+ _ <- IDBObjectStore.openKeyCursor store Nothing Prev cb
519+ _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique cb
520+ _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
521+ pure unit
522+ }
523+ tearDown db
502524
503− describe "IDBIndex" do
504− let
525+ describe "IDBIndex" do
526+ let
505527 tearDown db = do
506528 IDBDatabase.close db
507529 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
508530 pure unit
509531
510− setup :: forall value e e'.
511− { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
512− , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
513− , values :: Array (Tuple value (Maybe Key))
514− , keyPath :: Array String
515− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Eff (idb :: IDB, avar :: AVAR, exception :: EXCEPTION | e') Unit)
516− } -> Aff (idb :: IDB, avar :: AVAR | e) { db :: Database, index :: Index, store :: ObjectStore }
532+ setup
533+ :: forall value
534+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
535+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
536+ , values :: Array (Tuple value (Maybe Key))
537+ , keyPath :: Array String
538+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
539+ }
540+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
517541 setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
518− let onUpgradeNeeded' var db tx _ = launchAff' do
519− store <- IDBDatabase.createObjectStore db "store" storeParams
520− _ <- traverse (uncurry (IDBObjectStore.add store)) values
521− index <- IDBObjectStore.createIndex store "index" keyPath indexParams
522− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
523− putVar { db, index, store } var
524−
525− var <- makeEmptyVar
526− db <- IDBFactory.open "db" Nothing
527− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
528− , onBlocked : Nothing
542+ let
543+ onUpgradeNeeded' var db tx _ = launchAff' do
544+ store <- IDBDatabase.createObjectStore db "store" storeParams
545+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
546+ index <- IDBObjectStore.createIndex store "index" keyPath indexParams
547+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
548+ AVar.put { db, index, store } var
549+
550+ var <- AVar.empty
551+ _ <- IDBFactory.open "db" Nothing
552+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
553+ , onBlocked: Nothing
529554 }
530− takeVar var
531−
532−
533− it "returns an IDBIndex and the properties are set correctly" do
534− { db, index } <- setup
535− { storeParams : IDBDatabase.defaultParameters
536− , indexParams : IDBObjectStore.defaultParameters
537− , onUpgradeNeeded : Nothing
538− , keyPath : []
539− , values : []
540− }
541− IDBIndex.name index `shouldEqual` "index"
542− IDBIndex.keyPath index `shouldEqual` []
543− IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
544− IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
545− tearDown db
546−
547− it "attempt to create an index that requires unique values on an object store already contains duplicates" do
548− let onAbort var = launchAff' (putVar true var)
549− txVar <- makeEmptyVar
550− dbVar <- makeEmptyVar
551− res <- attempt $ setup
552− { storeParams : IDBDatabase.defaultParameters
553− , indexParams : { unique : true
554− , multiEntry : false
555− }
556− , keyPath : ["indexedProperty"]
557− , values : [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
558− , { indexedProperty: "bar" } :+: (Just $ toKey 2)
559− ]
560− , onUpgradeNeeded : Just $ \db tx _ -> launchAff' do
561− IDBTransaction.onAbort tx (onAbort txVar)
562− IDBDatabase.onAbort db (onAbort dbVar)
563− }
564− case res of
565− Right _ ->
566− fail "expected abort"
567− _ -> do
568− shouldEqual true =<< takeVar txVar
569− shouldEqual true =<< takeVar dbVar
570−
571−
572− it "the index is usable right after being made" do
573− { db } <- setup
574− { storeParams : { keyPath : ["key"]
575− , autoIncrement : false
576− }
577− , indexParams : IDBObjectStore.defaultParameters
578− , keyPath : ["indexedProperty"]
579− , values : [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
580− , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
581− , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
582− ]
583− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
584− val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
585− ((\r -> r.key) <$> val) `shouldEqual` (Just $ toKey "key2")
586− }
587− tearDown db
588−
589− it "empty keyPath" do
590− { db } <- setup
591− { storeParams : IDBDatabase.defaultParameters
592− , indexParams : IDBObjectStore.defaultParameters
593− , keyPath : []
594− , values : [ "object_1" :+: (Just $ toKey 1)
595− , "object_2" :+: (Just $ toKey 2)
596− , "object_3" :+: (Just $ toKey 3)
597− ]
598− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
599− val <- IDBIndex.get index (IDBKeyRange.only "object_3")
600− val `shouldEqual` (Just "object_3")
601− }
602− tearDown db
603−
604− it "index can be valid keys [date]" do
605− date <- liftEff $ toDateTime <$> now
606− { db } <- setup
607− { storeParams : { keyPath: ["key"]
608− , autoIncrement: false
609− }
610− , indexParams : IDBObjectStore.defaultParameters
611− , keyPath : ["i"]
612− , values : [ { key: "date", i: (toKey date) } :+: Nothing
613− ]
614− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
615− val <- IDBIndex.get index (IDBKeyRange.only date)
616− ((\r -> r.key) <$> val) `shouldEqual` (Just "date")
617− }
618− tearDown db
619−
620− it "index can be valid keys [num]" do
621− let num = 14
622− { db } <- setup
623− { storeParams : { keyPath: ["key"]
624− , autoIncrement: false
625− }
626− , indexParams : IDBObjectStore.defaultParameters
627− , keyPath : ["i"]
628− , values : [ { key: "num", i: (toKey num) } :+: Nothing
629− ]
630− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
631− val <- IDBIndex.get index (IDBKeyRange.only num)
632− ((\r -> r.key) <$> val) `shouldEqual` (Just "num")
633− }
634− tearDown db
635−
636− it "index can be valid keys [array]" do
637− let array = ["patate", "autruche"]
638− { db } <- setup
639− { storeParams : { keyPath: ["key"]
640− , autoIncrement: false
641− }
642− , indexParams : IDBObjectStore.defaultParameters
643− , keyPath : ["i"]
644− , values : [ { key: "array", i: (toKey array) } :+: Nothing
645− ]
646− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
647− val <- IDBIndex.get index (IDBKeyRange.only array)
648− ((\r -> r.key) <$> val) `shouldEqual` (Just "array")
649− }
650− tearDown db
651−
652− it "openKeyCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
653− res <- attempt $ setup
654− { storeParams : { keyPath: ["key"], autoIncrement: false }
655− , indexParams : IDBObjectStore.defaultParameters
656− , keyPath : ["indexedProperty"]
657− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
658− ]
659− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
660− let cb =
661− { onSuccess : const $ pure unit
662− , onError : show >>> fail >>> launchAff'
555+ AVar.take var
556+
557+ it "returns an IDBIndex and the properties are set correctly" do
558+ { db, index } <- setup
559+ { storeParams: IDBDatabase.defaultParameters
560+ , indexParams: IDBObjectStore.defaultParameters
561+ , onUpgradeNeeded: Nothing
562+ , keyPath: []
563+ , values: []
564+ }
565+ IDBIndex.name index `shouldEqual` "index"
566+ IDBIndex.keyPath index `shouldEqual` []
567+ IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
568+ IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
569+ tearDown db
570+
571+ it "attempt to create an index that requires unique values on an object store already contains duplicates" do
572+ let onAbort var = launchAff' (AVar.put true var)
573+ txVar <- AVar.empty
574+ dbVar <- AVar.empty
575+ res <- attempt $ setup
576+ { storeParams: IDBDatabase.defaultParameters
577+ , indexParams:
578+ { unique: true
579+ , multiEntry: false
580+ }
581+ , keyPath: [ "indexedProperty" ]
582+ , values:
583+ [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
584+ , { indexedProperty: "bar" } :+: (Just $ toKey 2)
585+ ]
586+ , onUpgradeNeeded: Just $ \db tx _ -> launchAff' do
587+ IDBTransaction.onAbort tx (onAbort txVar)
588+ IDBDatabase.onAbort db (onAbort dbVar)
589+ }
590+ case res of
591+ Right _ ->
592+ fail "expected abort"
593+ _ -> do
594+ shouldEqual true =<< AVar.take txVar
595+ shouldEqual true =<< AVar.take dbVar
596+
597+ it "the index is usable right after being made" do
598+ { db } <- setup
599+ { storeParams:
600+ { keyPath: [ "key" ]
601+ , autoIncrement: false
602+ }
603+ , indexParams: IDBObjectStore.defaultParameters
604+ , keyPath: [ "indexedProperty" ]
605+ , values:
606+ [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
607+ , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
608+ , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
609+ ]
610+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
611+ val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
612+ ((\r -> r.key) <$> val) `shouldEqual` (Just $ toKey "key2")
613+ }
614+ tearDown db
615+
616+ it "empty keyPath" do
617+ { db } <- setup
618+ { storeParams: IDBDatabase.defaultParameters
619+ , indexParams: IDBObjectStore.defaultParameters
620+ , keyPath: []
621+ , values:
622+ [ "object_1" :+: (Just $ toKey 1)
623+ , "object_2" :+: (Just $ toKey 2)
624+ , "object_3" :+: (Just $ toKey 3)
625+ ]
626+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
627+ val <- IDBIndex.get index (IDBKeyRange.only "object_3")
628+ val `shouldEqual` (Just "object_3")
629+ }
630+ tearDown db
631+
632+ it "index can be valid keys [date]" do
633+ date <- liftEffect $ toDateTime <$> now
634+ { db } <- setup
635+ { storeParams:
636+ { keyPath: [ "key" ]
637+ , autoIncrement: false
638+ }
639+ , indexParams: IDBObjectStore.defaultParameters
640+ , keyPath: [ "i" ]
641+ , values:
642+ [ { key: "date", i: (toKey date) } :+: Nothing
643+ ]
644+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
645+ val <- IDBIndex.get index (IDBKeyRange.only date)
646+ ((\r -> r.key) <$> val) `shouldEqual` (Just "date")
647+ }
648+ tearDown db
649+
650+ it "index can be valid keys [num]" do
651+ let num = 14
652+ { db } <- setup
653+ { storeParams:
654+ { keyPath: [ "key" ]
655+ , autoIncrement: false
656+ }
657+ , indexParams: IDBObjectStore.defaultParameters
658+ , keyPath: [ "i" ]
659+ , values:
660+ [ { key: "num", i: (toKey num) } :+: Nothing
661+ ]
662+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
663+ val <- IDBIndex.get index (IDBKeyRange.only num)
664+ ((\r -> r.key) <$> val) `shouldEqual` (Just "num")
665+ }
666+ tearDown db
667+
668+ it "index can be valid keys [array]" do
669+ let array = [ "patate", "autruche" ]
670+ { db } <- setup
671+ { storeParams:
672+ { keyPath: [ "key" ]
673+ , autoIncrement: false
674+ }
675+ , indexParams: IDBObjectStore.defaultParameters
676+ , keyPath: [ "i" ]
677+ , values:
678+ [ { key: "array", i: (toKey array) } :+: Nothing
679+ ]
680+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
681+ val <- IDBIndex.get index (IDBKeyRange.only array)
682+ ((\r -> r.key) <$> val) `shouldEqual` (Just "array")
683+ }
684+ tearDown db
685+
686+ it "openKeyCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
687+ res <- attempt $ setup
688+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
689+ , indexParams: IDBObjectStore.defaultParameters
690+ , keyPath: [ "indexedProperty" ]
691+ , values:
692+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
693+ ]
694+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
695+ let
696+ cb =
697+ { onSuccess: const $ pure unit
698+ , onError: show >>> fail >>> launchAff'
663699 , onComplete: pure unit
664700 }
665− IDBTransaction.onAbort tx (pure unit)
666− IDBDatabase.onAbort db (pure unit)
667− IDBTransaction.abort tx
668− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
669− case cursor of
670− Right _ -> fail "expected InvalidStateError"
671− Left err -> name err `shouldEqual` "InvalidStateError"
672− }
673− case res of
674− Right _ -> fail "expected InvalidStateError"
675− _ -> pure unit
676−
677− it "openKeyCursor() - throw TransactionInactiveError on aborted transaction" do
678− { db } <- setup
679− { storeParams : { keyPath: ["key"], autoIncrement: false }
680− , indexParams : IDBObjectStore.defaultParameters
681− , keyPath : ["indexedProperty"]
682− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
683− ]
684− , onUpgradeNeeded : Nothing
685− }
686− let cb =
687− { onSuccess : const $ pure unit
688− , onError : show >>> fail >>> launchAff'
701+ IDBTransaction.onAbort tx (pure unit)
702+ IDBDatabase.onAbort db (pure unit)
703+ IDBTransaction.abort tx
704+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
705+ case cursor of
706+ Right _ -> fail "expected InvalidStateError"
707+ Left err -> name err `shouldEqual` "InvalidStateError"
708+ }
709+ case res of
710+ Right _ -> fail "expected InvalidStateError"
711+ _ -> pure unit
712+
713+ it "openKeyCursor() - throw TransactionInactiveError on aborted transaction" do
714+ { db } <- setup
715+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
716+ , indexParams: IDBObjectStore.defaultParameters
717+ , keyPath: [ "indexedProperty" ]
718+ , values:
719+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
720+ ]
721+ , onUpgradeNeeded: Nothing
722+ }
723+ let
724+ cb =
725+ { onSuccess: const $ pure unit
726+ , onError: show >>> fail >>> launchAff'
689727 , onComplete: pure unit
690728 }
691− tx <- IDBDatabase.transaction db ["store"] ReadOnly
692− store <- IDBTransaction.objectStore tx "store"
693− index <- IDBObjectStore.index store "index"
694− IDBTransaction.onAbort tx (pure unit)
695− IDBTransaction.abort tx
696− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
697− case cursor of
698− Right _ -> fail "expected TransactionInactiveError"
699− Left err -> name err `shouldEqual` "TransactionInactiveError"
700−
701− tearDown db
702−
703− it "openKeyCursor() - throw InvalidStateError when the index is deleted" do
704− { db } <- setup
705− { storeParams : { keyPath: ["key"], autoIncrement: false }
706− , indexParams : IDBObjectStore.defaultParameters
707− , keyPath : ["indexedProperty"]
708− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
709− ]
710− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
711− let cb =
712− { onSuccess : const $ pure unit
713− , onError : show >>> fail >>> launchAff'
729+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
730+ store <- IDBTransaction.objectStore tx "store"
731+ index <- IDBObjectStore.index store "index"
732+ IDBTransaction.onAbort tx (pure unit)
733+ IDBTransaction.abort tx
734+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
735+ case cursor of
736+ Right _ -> fail "expected TransactionInactiveError"
737+ Left err -> name err `shouldEqual` "TransactionInactiveError"
738+
739+ tearDown db
740+
741+ it "openKeyCursor() - throw InvalidStateError when the index is deleted" do
742+ { db } <- setup
743+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
744+ , indexParams: IDBObjectStore.defaultParameters
745+ , keyPath: [ "indexedProperty" ]
746+ , values:
747+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
748+ ]
749+ , onUpgradeNeeded: Just $ \_ tx index -> launchAff' do
750+ let
751+ cb =
752+ { onSuccess: const $ pure unit
753+ , onError: show >>> fail >>> launchAff'
714754 , onComplete: pure unit
715755 }
716− store <- IDBTransaction.objectStore tx "store"
717− IDBObjectStore.deleteIndex store "index"
718− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
719− case cursor of
720− Right _ -> fail "expected InvalidStateError"
721− Left err -> name err `shouldEqual` "InvalidStateError"
722− }
723−
724− tearDown db
725−
726− it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
727− res <- attempt $ setup
728− { storeParams : { keyPath: ["key"], autoIncrement: false }
729− , indexParams : IDBObjectStore.defaultParameters
730− , keyPath : ["indexedProperty"]
731− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
732− ]
733− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
734− let cb =
735− { onSuccess : const $ pure unit
736− , onError : show >>> fail >>> launchAff'
756+ store <- IDBTransaction.objectStore tx "store"
757+ IDBObjectStore.deleteIndex store "index"
758+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
759+ case cursor of
760+ Right _ -> fail "expected InvalidStateError"
761+ Left err -> name err `shouldEqual` "InvalidStateError"
762+ }
763+
764+ tearDown db
765+
766+ it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
767+ res <- attempt $ setup
768+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
769+ , indexParams: IDBObjectStore.defaultParameters
770+ , keyPath: [ "indexedProperty" ]
771+ , values:
772+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
773+ ]
774+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
775+ let
776+ cb =
777+ { onSuccess: const $ pure unit
778+ , onError: show >>> fail >>> launchAff'
737779 , onComplete: pure unit
738780 }
739− IDBTransaction.onAbort tx (pure unit)
740− IDBDatabase.onAbort db (pure unit)
741− IDBTransaction.abort tx
742− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
743− case cursor of
744− Right _ -> fail "expected InvalidStateError"
745− Left err -> name err `shouldEqual` "InvalidStateError"
746− }
747− case res of
748− Right _ -> fail "expected InvalidStateError"
749− _ -> pure unit
750−
751− it "openCursor() - throw TransactionInactiveError on aborted transaction" do
752− { db } <- setup
753− { storeParams : { keyPath: ["key"], autoIncrement: false }
754− , indexParams : IDBObjectStore.defaultParameters
755− , keyPath : ["indexedProperty"]
756− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
757− ]
758− , onUpgradeNeeded : Nothing
759− }
760− let cb =
761− { onSuccess : const $ pure unit
762− , onError : show >>> fail >>> launchAff'
781+ IDBTransaction.onAbort tx (pure unit)
782+ IDBDatabase.onAbort db (pure unit)
783+ IDBTransaction.abort tx
784+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
785+ case cursor of
786+ Right _ -> fail "expected InvalidStateError"
787+ Left err -> name err `shouldEqual` "InvalidStateError"
788+ }
789+ case res of
790+ Right _ -> fail "expected InvalidStateError"
791+ _ -> pure unit
792+
793+ it "openCursor() - throw TransactionInactiveError on aborted transaction" do
794+ { db } <- setup
795+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
796+ , indexParams: IDBObjectStore.defaultParameters
797+ , keyPath: [ "indexedProperty" ]
798+ , values:
799+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
800+ ]
801+ , onUpgradeNeeded: Nothing
802+ }
803+ let
804+ cb =
805+ { onSuccess: const $ pure unit
806+ , onError: show >>> fail >>> launchAff'
763807 , onComplete: pure unit
764808 }
765− tx <- IDBDatabase.transaction db ["store"] ReadOnly
766− store <- IDBTransaction.objectStore tx "store"
767− index <- IDBObjectStore.index store "index"
768− IDBTransaction.onAbort tx (pure unit)
769− IDBTransaction.abort tx
770− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
771− case cursor of
772− Right _ -> fail "expected TransactionInactiveError"
773− Left err -> name err `shouldEqual` "TransactionInactiveError"
774−
775− tearDown db
776−
777− it "openCursor() - throw InvalidStateError when the index is deleted" do
778− { db } <- setup
779− { storeParams : { keyPath: ["key"], autoIncrement: false }
780− , indexParams : IDBObjectStore.defaultParameters
781− , keyPath : ["indexedProperty"]
782− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
783− ]
784− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
785− let cb =
786− { onSuccess : const $ pure unit
787− , onError : show >>> fail >>> launchAff'
809+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
810+ store <- IDBTransaction.objectStore tx "store"
811+ index <- IDBObjectStore.index store "index"
812+ IDBTransaction.onAbort tx (pure unit)
813+ IDBTransaction.abort tx
814+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
815+ case cursor of
816+ Right _ -> fail "expected TransactionInactiveError"
817+ Left err -> name err `shouldEqual` "TransactionInactiveError"
818+
819+ tearDown db
820+
821+ it "openCursor() - throw InvalidStateError when the index is deleted" do
822+ { db } <- setup
823+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
824+ , indexParams: IDBObjectStore.defaultParameters
825+ , keyPath: [ "indexedProperty" ]
826+ , values:
827+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
828+ ]
829+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
830+ let
831+ cb =
832+ { onSuccess: const $ pure unit
833+ , onError: show >>> fail >>> launchAff'
788834 , onComplete: pure unit
789835 }
790− store <- IDBTransaction.objectStore tx "store"
791− IDBObjectStore.deleteIndex store "index"
792− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
793− case cursor of
794− Right _ -> fail "expected InvalidStateError"
795− Left err -> name err `shouldEqual` "InvalidStateError"
796− }
797−
798− tearDown db
799−
800− it "getKey() - multiEntry - adding keys" do
801− { db } <- setup
802− { storeParams : IDBDatabase.defaultParameters
803− , indexParams : { unique: false, multiEntry: true }
804− , keyPath : ["name"]
805− , values : [ { name: ["patate", "autruche"] } :+: (Just $ toKey 1)
806− , { name: ["bob"] } :+: (Just $ toKey 2)
807− ]
808− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
809− key <- IDBIndex.getKey index (IDBKeyRange.only "patate")
810− key `shouldEqual` (Just $ toKey 1)
811−
812− key' <- IDBIndex.getKey index (IDBKeyRange.only "autruche")
813− key' `shouldEqual` (Just $ toKey 1)
814−
815− key'' <- IDBIndex.getKey index (IDBKeyRange.only "bob")
816− key'' `shouldEqual` (Just $ toKey 2)
817− }
818− tearDown db
819−
820−
821− it "get() - returns the record with the first key in the range" do
822− { db } <- setup
823− { storeParams : { keyPath: ["key"], autoIncrement: false }
824− , indexParams : IDBObjectStore.defaultParameters
825− , keyPath : ["indexedProperty"]
826− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
827− , { key: 42, indexedProperty: "autruche" } :+: Nothing
828− , { key: 1337, indexedProperty: "baguette" } :+: Nothing
829− ]
830− , onUpgradeNeeded : Nothing
831− }
832−
833− tx <- IDBDatabase.transaction db ["store"] ReadOnly
834− store <- IDBTransaction.objectStore tx "store"
835− index <- IDBObjectStore.index store "index"
836− val <- IDBIndex.get index (IDBKeyRange.lowerBound "autruche" false)
837− ((\r -> r.key) <$> val) `shouldEqual` (Just 42)
838−
839− tearDown db
840−
841− describe "IDBCursor" do
842− let
836+ store <- IDBTransaction.objectStore tx "store"
837+ IDBObjectStore.deleteIndex store "index"
838+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
839+ case cursor of
840+ Right _ -> fail "expected InvalidStateError"
841+ Left err -> name err `shouldEqual` "InvalidStateError"
842+ }
843+
844+ tearDown db
845+
846+ it "getKey() - multiEntry - adding keys" do
847+ { db } <- setup
848+ { storeParams: IDBDatabase.defaultParameters
849+ , indexParams: { unique: false, multiEntry: true }
850+ , keyPath: [ "name" ]
851+ , values:
852+ [ { name: [ "patate", "autruche" ] } :+: (Just $ toKey 1)
853+ , { name: [ "bob" ] } :+: (Just $ toKey 2)
854+ ]
855+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
856+ key <- IDBIndex.getKey index (IDBKeyRange.only "patate")
857+ key `shouldEqual` (Just $ toKey 1)
858+
859+ key' <- IDBIndex.getKey index (IDBKeyRange.only "autruche")
860+ key' `shouldEqual` (Just $ toKey 1)
861+
862+ key'' <- IDBIndex.getKey index (IDBKeyRange.only "bob")
863+ key'' `shouldEqual` (Just $ toKey 2)
864+ }
865+ tearDown db
866+
867+ it "get() - returns the record with the first key in the range" do
868+ { db } <- setup
869+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
870+ , indexParams: IDBObjectStore.defaultParameters
871+ , keyPath: [ "indexedProperty" ]
872+ , values:
873+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
874+ , { key: 42, indexedProperty: "autruche" } :+: Nothing
875+ , { key: 1337, indexedProperty: "baguette" } :+: Nothing
876+ ]
877+ , onUpgradeNeeded: Nothing
878+ }
879+
880+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
881+ store <- IDBTransaction.objectStore tx "store"
882+ index <- IDBObjectStore.index store "index"
883+ val <- IDBIndex.get index (IDBKeyRange.lowerBound "autruche" false)
884+ ((\r -> r.key) <$> val) `shouldEqual` (Just 42)
885+
886+ tearDown db
887+
888+ describe "IDBCursor" do
889+ let
843890 tearDown db = do
844891 IDBDatabase.close db
845892 _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
846893 pure unit
847894
848− setup :: forall value e e'.
849− { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
850− , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
851− , values :: Array (Tuple value (Maybe Key))
852− , keyPath :: Array String
853− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Eff (idb :: IDB, avar :: AVAR, exception :: EXCEPTION | e') Unit)
854− } -> Aff (idb :: IDB, avar :: AVAR | e) { db :: Database, index :: Index, store :: ObjectStore }
895+ setup
896+ :: forall value
897+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
898+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
899+ , values :: Array (Tuple value (Maybe Key))
900+ , keyPath :: Array String
901+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
902+ }
903+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
855904 setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
856− let onUpgradeNeeded' var db tx _ = launchAff' do
857− store <- IDBDatabase.createObjectStore db "store" storeParams
858− _ <- traverse (uncurry (IDBObjectStore.add store)) values
859− index <- IDBObjectStore.createIndex store "index" keyPath indexParams
860− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
861− putVar { db, index, store } var
862−
863− var <- makeEmptyVar
864− db <- IDBFactory.open "db" Nothing
865− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
866− , onBlocked : Nothing
905+ let
906+ onUpgradeNeeded' var db tx _ = launchAff' do
907+ store <- IDBDatabase.createObjectStore db "store" storeParams
908+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
909+ index <- IDBObjectStore.createIndex store "index" keyPath indexParams
910+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
911+ AVar.put { db, index, store } var
912+
913+ var <- AVar.empty
914+ db <- IDBFactory.open "db" Nothing
915+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
916+ , onBlocked: Nothing
867917 }
868− takeVar var
869−
870− it "continue() - iterate to the next record" do
871− { db } <- setup
872− { storeParams : IDBDatabase.defaultParameters
873− , indexParams : IDBObjectStore.defaultParameters
874− , keyPath : []
875− , values : [ "cupcake" :+: (Just $ toKey 4)
876− , "pancake" :+: (Just $ toKey 2)
877− , "pie" :+: (Just $ toKey 1)
878− , "pie" :+: (Just $ toKey 3)
879− ]
880− , onUpgradeNeeded: Nothing
881− }
882− let cb vdone vvals =
918+ AVar.take var
919+
920+ it "continue() - iterate to the next record" do
921+ { db } <- setup
922+ { storeParams: IDBDatabase.defaultParameters
923+ , indexParams: IDBObjectStore.defaultParameters
924+ , keyPath: []
925+ , values:
926+ [ "cupcake" :+: (Just $ toKey 4)
927+ , "pancake" :+: (Just $ toKey 2)
928+ , "pie" :+: (Just $ toKey 1)
929+ , "pie" :+: (Just $ toKey 3)
930+ ]
931+ , onUpgradeNeeded: Nothing
932+ }
933+ let
934+ cb vdone vvals =
883935 { onComplete: launchAff' do
884− putVar unit vdone
936+ AVar.put unit vdone
885937
886− , onError: \error -> launchAff' do
938+ , onError: \error -> launchAff' do
887939 fail $ "unexpected error: " <> show error
888940
889941 , onSuccess: \cursor -> launchAff' do
890− vals <- takeVar vvals
942+ vals <- AVar.take vvals
891943 pure (IDBCursor.value cursor) >>= shouldEqual (maybe "" _.v $ head vals)
892− IDBCursor.primaryKey cursor >>= shouldEqual (maybe (toKey 0) _.k $ head vals)
893− putVar (drop 1 vals) vvals
944+ IDBCursor.primaryKey cursor >>= shouldEqual (maybe (toKey 0) _.k $ head vals)
945+ AVar.put (drop 1 vals) vvals
894946 IDBCursor.continue cursor none
895947 }
896− vdone <- makeEmptyVar
897− vvals <- makeVar
898− [ { v: "pie" , k: toKey 1 }
899− , { v: "pancake", k: toKey 2 }
900− , { v: "pie" , k: toKey 3 }
901− , { v: "cupcake", k: toKey 4 }
902− ]
903− tx <- IDBDatabase.transaction db ["store"] ReadOnly
904− store <- IDBTransaction.objectStore tx "store"
905− IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
906− takeVar vdone
907− tearDown db
908−
909− it "continue() - attempt to iterate in the wrong direction" do
910− { db } <- setup
911− { storeParams : IDBDatabase.defaultParameters
912− , indexParams : IDBObjectStore.defaultParameters
913− , keyPath : []
914− , values : [ "cupcake" :+: (Just $ toKey 4)
915− , "pancake" :+: (Just $ toKey 2)
916− , "pie" :+: (Just $ toKey 1)
917− , "pie" :+: (Just $ toKey 3)
918− ]
919− , onUpgradeNeeded: Nothing
920− }
921− let cb vdone =
948+ vdone <- AVar.empty
949+ vvals <- AVar.new
950+ [ { v: "pie", k: toKey 1 }
951+ , { v: "pancake", k: toKey 2 }
952+ , { v: "pie", k: toKey 3 }
953+ , { v: "cupcake", k: toKey 4 }
954+ ]
955+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
956+ store <- IDBTransaction.objectStore tx "store"
957+ IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
958+ AVar.take vdone
959+ tearDown db
960+
961+ it "continue() - attempt to iterate in the wrong direction" do
962+ { db } <- setup
963+ { storeParams: IDBDatabase.defaultParameters
964+ , indexParams: IDBObjectStore.defaultParameters
965+ , keyPath: []
966+ , values:
967+ [ "cupcake" :+: (Just $ toKey 4)
968+ , "pancake" :+: (Just $ toKey 2)
969+ , "pie" :+: (Just $ toKey 1)
970+ , "pie" :+: (Just $ toKey 3)
971+ ]
972+ , onUpgradeNeeded: Nothing
973+ }
974+ let
975+ cb vdone =
922976 { onComplete: launchAff' do
923977 fail $ "shouldn't complete"
924978
925− , onError: \error -> launchAff' do
979+ , onError: \error -> launchAff' do
926980 fail $ "unexpected error: " <> show error
927981
928982 , onSuccess: \cursor -> launchAff' do
929983 res <- attempt $ IDBCursor.continue cursor (Just 1)
930984 case res of
931− Left err -> do
985+ Left err -> do
932986 name err `shouldEqual` "DataError"
933− putVar unit vdone
987+ AVar.put unit vdone
934988 Right _ -> do
935989 fail "expected continue to fail"
936990 }
937− vdone <- makeEmptyVar
938− tx <- IDBDatabase.transaction db ["store"] ReadOnly
939− store <- IDBTransaction.objectStore tx "store"
940− IDBObjectStore.openCursor store Nothing Next (cb vdone)
941− takeVar vdone
942− tearDown db
943−
944−
945− it "advance() - iterate cursor number of times specified by count" do
946− { db } <- setup
947− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
948− , indexParams : IDBObjectStore.defaultParameters
949− , keyPath : []
950− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
951− , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
952− , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
953− , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
954− ]
955− , onUpgradeNeeded: Nothing
956− }
957− let cb vdone vjump =
991+ vdone <- AVar.empty
992+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
993+ store <- IDBTransaction.objectStore tx "store"
994+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
995+ AVar.take vdone
996+ tearDown db
997+
998+ it "advance() - iterate cursor number of times specified by count" do
999+ { db } <- setup
1000+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1001+ , indexParams: IDBObjectStore.defaultParameters
1002+ , keyPath: []
1003+ , values:
1004+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1005+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1006+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1007+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1008+ ]
1009+ , onUpgradeNeeded: Nothing
1010+ }
1011+ let
1012+ cb vdone vjump =
9581013 { onComplete: launchAff' do
959− putVar unit vdone
1014+ AVar.put unit vdone
9601015
961− , onError: \error -> launchAff' do
1016+ , onError: \error -> launchAff' do
9621017 fail $ "unexpected error: " <> show error
9631018
9641019 , onSuccess: \cursor -> launchAff' do
965− jump <- takeVar vjump
966− if jump
967− then do
968− IDBCursor.advance cursor 3
969− else do
970− let value = IDBCursor.value cursor
971− value.pKey `shouldEqual` "pkey_3"
972− value.iKey `shouldEqual` "ikey_3"
973− IDBCursor.continue cursor none
974− putVar false vjump
1020+ jump <- AVar.take vjump
1021+ if jump then do
1022+ IDBCursor.advance cursor 3
1023+ else do
1024+ let value = IDBCursor.value cursor
1025+ value.pKey `shouldEqual` "pkey_3"
1026+ value.iKey `shouldEqual` "ikey_3"
1027+ IDBCursor.continue cursor none
1028+ AVar.put false vjump
9751029 }
976− vdone <- makeEmptyVar
977− vjump <- makeVar true
978− tx <- IDBDatabase.transaction db ["store"] ReadOnly
979− store <- IDBTransaction.objectStore tx "store"
980− IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
981− takeVar vdone
982− tearDown db
983−
984− it "delete() - remove a record from the object store" do
985− { db } <- setup
986− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
987− , indexParams : IDBObjectStore.defaultParameters
988− , keyPath : []
989− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
990− , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
991− , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
992− , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
993− ]
994− , onUpgradeNeeded: Nothing
995− }
996− let cb vdone store =
1030+ vdone <- AVar.empty
1031+ vjump <- AVar.new true
1032+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
1033+ store <- IDBTransaction.objectStore tx "store"
1034+ IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
1035+ AVar.take vdone
1036+ tearDown db
1037+
1038+ it "delete() - remove a record from the object store" do
1039+ { db } <- setup
1040+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1041+ , indexParams: IDBObjectStore.defaultParameters
1042+ , keyPath: []
1043+ , values:
1044+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1045+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1046+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1047+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1048+ ]
1049+ , onUpgradeNeeded: Nothing
1050+ }
1051+ let
1052+ cb vdone store =
9971053 { onComplete: launchAff' do
9981054 mval <- map _.pKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
9991055 mval `shouldEqual` (Nothing :: Maybe String)
1000− putVar unit vdone
1056+ AVar.put unit vdone
10011057
1002− , onError: \error -> launchAff' do
1058+ , onError: \error -> launchAff' do
10031059 fail $ "unexpected error: " <> show error
10041060
10051061 , onSuccess: \cursor -> launchAff' do
@@ -1008,29 +1064,31 @@ main = runMocha do
10081064 IDBCursor.delete cursor
10091065 IDBCursor.advance cursor 4
10101066 }
1011− vdone <- makeEmptyVar
1012− tx <- IDBDatabase.transaction db ["store"] ReadWrite
1013− store <- IDBTransaction.objectStore tx "store"
1014− IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1015− takeVar vdone
1016− tearDown db
1017−
1018− it "update() - modify a record in the object store" do
1019− { db } <- setup
1020− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1021− , indexParams : IDBObjectStore.defaultParameters
1022− , keyPath : []
1023− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1024− ]
1025− , onUpgradeNeeded: Nothing
1026− }
1027− let cb vdone store =
1067+ vdone <- AVar.empty
1068+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1069+ store <- IDBTransaction.objectStore tx "store"
1070+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1071+ AVar.take vdone
1072+ tearDown db
1073+
1074+ it "update() - modify a record in the object store" do
1075+ { db } <- setup
1076+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1077+ , indexParams: IDBObjectStore.defaultParameters
1078+ , keyPath: []
1079+ , values:
1080+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1081+ ]
1082+ , onUpgradeNeeded: Nothing
1083+ }
1084+ let
1085+ cb vdone store =
10281086 { onComplete: launchAff' do
10291087 mval <- map _.iKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
10301088 mval `shouldEqual` (Just "patate")
1031− putVar unit vdone
1089+ AVar.put unit vdone
10321090
1033− , onError: \error -> launchAff' do
1091+ , onError: \error -> launchAff' do
10341092 fail $ "unexpected error: " <> show error
10351093
10361094 , onSuccess: \cursor -> launchAff' do
@@ -1040,27 +1098,29 @@ main = runMocha do
10401098 key `shouldEqual` toKey "pkey_0"
10411099 IDBCursor.advance cursor 4
10421100 }
1043− vdone <- makeEmptyVar
1044− tx <- IDBDatabase.transaction db ["store"] ReadWrite
1045− store <- IDBTransaction.objectStore tx "store"
1046− IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1047− takeVar vdone
1048− tearDown db
1049−
1050− it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1051− { db } <- setup
1052− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1053− , indexParams : IDBObjectStore.defaultParameters
1054− , keyPath : []
1055− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1056− ]
1057− , onUpgradeNeeded: Nothing
1058− }
1059− let cb vdone =
1101+ vdone <- AVar.empty
1102+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1103+ store <- IDBTransaction.objectStore tx "store"
1104+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1105+ AVar.take vdone
1106+ tearDown db
1107+
1108+ it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1109+ { db } <- setup
1110+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1111+ , indexParams: IDBObjectStore.defaultParameters
1112+ , keyPath: []
1113+ , values:
1114+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1115+ ]
1116+ , onUpgradeNeeded: Nothing
1117+ }
1118+ let
1119+ cb vdone =
10601120 { onComplete: launchAff' do
10611121 fail $ "shouldn't complete"
10621122
1063− , onError: \error -> launchAff' do
1123+ , onError: \error -> launchAff' do
10641124 fail $ "unexpected error: " <> show error
10651125
10661126 , onSuccess: \cursor -> launchAff' do
@@ -1068,13 +1128,14 @@ main = runMocha do
10681128 case res of
10691129 Left err -> do
10701130 name err `shouldEqual` "ReadOnlyError"
1071− putVar unit vdone
1131+ AVar.put unit vdone
10721132 Right _ ->
10731133 fail $ "expected ReadOnlyError"
10741134 }
1075− vdone <- makeEmptyVar
1076− tx <- IDBDatabase.transaction db ["store"] ReadOnly
1077− store <- IDBTransaction.objectStore tx "store"
1078− IDBObjectStore.openCursor store Nothing Next (cb vdone)
1079− takeVar vdone
1080− tearDown db
1135+ vdone <- AVar.empty
1136+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
1137+ store <- IDBTransaction.objectStore tx "store"
1138+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
1139+ AVar.take vdone
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"