RangerMauve / hyper-sdk

Make your own hyper apps!
https://www.youtube.com/watch?v=HyHk4aImd_I&list=PL7sG5SCUNyeYx8wnfMOUpsh7rM_g0w_cu&index=20
MIT License
290 stars 46 forks source link

Storage not persisting on Chrome and Firefox #7

Closed RangerMauve closed 5 years ago

RangerMauve commented 5 years ago

Apparently there's an error: DOMException: "The operation failed because the requested database object could not be found. For example, an object store did not exist but was being opened."

Gonna figure this out on Monday.

ImVexed commented 5 years ago

This seems to stem from random-access-idb-mutable-file/lib/random-access-idb-mutable-file.js not being able to handle either the Dat folder or IDBMutableFile inside the folder being deleted from the Indexed DB storage in FireFox.

Chrome seems to not have it's Indexed DB populated regardless.

ImVexed commented 5 years ago

Repro: From a new create-react-app: yarn add dat-sdk

App.js

import React from 'react';
import './App.css';
import { getImage } from './p2p';

export default class extends React.Component {

  async componentDidMount() {
    this.setState({ img: await getImage('bklqtanmv35ek46ujnk0') })
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={this.state ? this.state.img : null} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

p2p.js

const { Hyperdrive } = require('dat-sdk')();

export const archive = Hyperdrive('dat://61382211b2ee66635949138ab0161e409b6788704954cb31739d6b7d4acc0162', { persist: true })

archive.on('error', console.error)

export async function getImage(uid) {
    return await fetchFile(uid, 'image.raw.webp');
}

async function fetchFile(uid, file) {
    const stream = archive.createReadStream(`/${uid}/${file}`)

    let chunks = [];

    const data = await new Promise((resolve, _) => {
        stream.on('data', function (chunk) {
            chunks.push(chunk)
        }).on('end', function () {
            resolve(URL.createObjectURL(new Blob(chunks, { type: 'image/webp' })))
        }).on('error', console.error)
    })

    return data;
}

Works initially in the browser loading an image, however, after you delete either the Dat folder or IDBMutableFile inside the Indexed DB tab of Firefox it will either fail silently or give the DOMException.

RangerMauve commented 5 years ago

Are you sure Chrome isn't persisting storage? It uses the filesystem API instead if IDB for persistence. It'd likely error out if it had trouble writing stuff, too.

I'm not sure how we can handle deleting parts of IndexedDB, I think the storage layer has a particular way of interacting with it, so there should probably be an API for deletion there instead of deleting it externally.

Does fully deleting IDB and refreshing the page help?

RangerMauve commented 5 years ago

Any luck with this?

RangerMauve commented 5 years ago

Gonna close this for now. Feel free to reopen if you have the issue again. 💜