| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- //go:build js && wasm
- // +build js,wasm
- package idb
- import (
- "context"
- "errors"
- "sync"
- "syscall/js"
- "github.com/hack-pad/safejs"
- )
- // Factory lets applications asynchronously access the indexed databases. A typical program will call Global() to access window.indexedDB.
- type Factory struct {
- jsFactory safejs.Value
- }
- var (
- global *Factory
- globalErr error
- globalOnce sync.Once
- )
- // Global returns the global IndexedDB instance.
- // Can be called multiple times, will always return the same result (or error if one occurs).
- func Global() *Factory {
- globalOnce.Do(func() {
- var jsFactory safejs.Value
- jsFactory, globalErr = safejs.Global().Get("indexedDB")
- if globalErr != nil {
- return
- }
- var truthy bool
- truthy, globalErr = jsFactory.Truthy()
- if globalErr != nil {
- return
- }
- if truthy {
- global, globalErr = WrapFactory(safejs.Unsafe(jsFactory))
- } else {
- globalErr = errors.New("Global JS variable 'indexedDB' is not defined")
- }
- })
- if globalErr != nil {
- panic(globalErr)
- }
- return global
- }
- // WrapFactory wraps the given IDBFactory object
- func WrapFactory(jsFactory js.Value) (*Factory, error) {
- return &Factory{
- jsFactory: safejs.Safe(jsFactory),
- }, nil
- }
- // Open requests to open a connection to a database.
- func (f *Factory) Open(upgradeCtx context.Context, name string, version uint, upgrader Upgrader) (*OpenDBRequest, error) {
- args := []interface{}{name}
- if version > 0 {
- args = append(args, version)
- }
- reqValue, err := f.jsFactory.Call("open", args...)
- if err != nil {
- return nil, tryAsDOMException(err)
- }
- req := wrapRequest(nil, reqValue)
- return newOpenDBRequest(upgradeCtx, req, upgrader)
- }
- // DeleteDatabase requests the deletion of a database.
- func (f *Factory) DeleteDatabase(name string) (*AckRequest, error) {
- reqValue, err := f.jsFactory.Call("deleteDatabase", name)
- if err != nil {
- return nil, tryAsDOMException(err)
- }
- req := wrapRequest(nil, reqValue)
- return newAckRequest(req), nil
- }
- // CompareKeys compares two keys and returns a result indicating which one is greater in value.
- func (f *Factory) CompareKeys(a, b js.Value) (int, error) {
- compare, err := f.jsFactory.Call("cmp", a, b)
- if err != nil {
- return 0, tryAsDOMException(err)
- }
- return compare.Int()
- }
|