我正在try 让持久性存储与WASM SQLite一起工作.

我在background.js文件中的代码是这样的

const worker = new Worker('./worker.js');
worker.postMessage({ loadSQLite: true });

但它从来没有通过工人的部分. 我得到以下错误.

enter image description here

Uncaught ReferenceError: Worker is not defined

所以在做了一些研究之后,我try 了一些可能的解决方案.有些人说你不能在工人中繁殖工人,有一个子工人解决方案,但对我不起作用(如果对你有效,请告诉我,但我无法让它起作用).

我认为worker.js中的代码并不重要,但我会在那里发布我想要做的事情.

worker.js

import sqlite3InitModule from './lib/@sqlite.org/sqlite-wasm/index.mjs';
const log = (...args) => console.log(...args);
const error = (...args) => console.error(...args);
console.log("worker loaded...");

//@JA - SQLite Database Setup
const start = function (sqlite3) {
    console.log(sqlite3);
    const capi = sqlite3.capi; // C-style API
    const oo = sqlite3.oo1; // High-level OO API
    console.log(`SQLite3 Version ${capi.sqlite3_libversion()} - ${capi.sqlite3_sourceid()}`);
    let db;
    if ('OpfsDb' in oo) {
        db = new oo.OpfsDb('/mydb.sqlite3');
        console.log('The OPFS is available.');
        console.log(`Persisted db = ${db.filename}`);
    } else {
        db = new oo.DB('/mydb.sqlite3', 'ct');
        console.log('The OPFS is not available.');
        console.log(`transient db = ${db.filename}`);
    }

    try{
        db.exec(`CREATE TABLE IF NOT EXISTS results (id INTEGER PRIMARY KEY AUTOINCREMENT, search_name TEXT, strategy_name TEXT, json_data TEXT)`);
    } finally {
        db.close();
    }
}

self.addEventListener('message', (event) => {
    if (event.data.loadSQLite) {
        // Load the SQLite library within the web worker
        sqlite3InitModule({
            print: log,
            printErr: error,
        }).then(function (sqlite3) {
            log('SQLite Done initializing.');
            try {
                start(sqlite3);
            } catch (e) {
                error('Exception:', e.message);
            }
        });
    }
});

如果我把它放在worker.js之外,这个代码就可以工作了,但是它是暂时的,这意味着数据库不会保存!

我的目标是让它使用OPFS进行持久存储,但这被证明是相当困难的,我遇到了障碍.如有任何帮助,我们不胜感激!

我的目标是The OPFS is available.

来自该资源:https://sqlite.org/wasm/doc/trunk/persistence.md

上面写着it must be in a service worker to work美元.我以为那名后台.js是一名服务人员,但显然不是,否则这个应该会在那里起作用.这就是为什么我要在那里创造一个服务工作者.

我的 list 文件在这里:

{
    "name" : "__MSG_appName__",
    "short_name": "__MSG_appShortName__",
    "description": "__MSG_appDescription__",
    "version" : "2.0.2",
    "version_name": "2.0.2",
    "manifest_version": 3,
    "default_locale": "en",
    "minimum_chrome_version": "88",
    "permissions": [
        "activeTab",
        "tabs",
        "storage",
        "scripting",
        "unlimitedStorage",
        "declarativeNetRequest",
        "declarativeNetRequestFeedback"
    ],
    "icons": {
        "16": "./assets/img/icon-16.png",
        "32": "./assets/img/icon-32.png",
        "48": "./assets/img/icon-48.png",
        "128": "./assets/img/icon-128.png"
    },
    "background":{
        "service_worker": "background.js",
        "type": "module"
    },
    "action":{
        "default_popup": "./popup.html",
        "default_icons": {
            "16": "./assets/img/icon-16.png",
            "32": "./assets/img/icon-32.png",
            "48": "./assets/img/icon-48.png",
            "128": "./assets/img/icon-128.png" 
        },
        "default_title": "__MSG_appName__"
    },
    "host_permissions": [
        "https://*.tradingview.com/*"
    ],
    "content_scripts": [
        {
            "all_frames": true,
            "matches": [
                "https://*.tradingview.com/*",
                "http://*.tradingtools.software/*"
            ],
            "css": [
                "./css/trading-view.css",
                "./lib/datetimepicker/jquery.datetimepicker.min.css"
            ],
            "js": [
                "./lib/jquery/jquery-3.6.0.min.js",
                "./lib/lodash/lodash.js",
                "./lib/luxon/non-es6-luxon.js",
                "./lib/datetimepicker/jquery.datetimepicker.full.min.js",
                "./js/classes/scanner.js",
                "./js/classes/dialogs.js",
                "./js/classes/queues.js",
                "./js/helpers/helpers.js",
                "./js/helpers/inputs.js",
                "./js/helpers/security.js",
                "./js/helpers/manipulators.js",
                "./js/helpers/strategy.js",
                "./js/helpers/license.js",
                "./js/globals/globals.js",
                "./js/content/tradingview-content-script.js"  
            ],
            "run_at": "document_idle"
        },
        {
            "all_frames": true,
            "matches":["https://*.tradingview.com/*","http://*.tradingtools.software/*"],
            "js":[ "./js/injectors/before.js" ],
            "run_at": "document_start"
        },
        {
            "all_frames": true,
            "matches":["https://*.tradingview.com/*","http://*.tradingtools.software/*"],
            "js":[ "./js/injectors/after.js" ],
            "run_at": "document_end"
        }
    ],
    "web_accessible_resources": [{
        "resources": ["/js/injectors/before_inject.js","/js/injectors/after_inject.js","/js/injectors/page-script.js","/assets/*","workers.js"],
        "matches": ["<all_urls>"]
    }],
    "content_security_policy": {
        "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'; worker-src 'self'",
        "sandbox": "sandbox allow-scripts; default-src 'self' 'wasm-unsafe-eval'; frame-src 'self'; worker-src 'self'"
      }
}

推荐答案

您不能从扩展服务Worker启动Worker,但可以在offscreen document内创建Worker

至于在Chrome扩展中使用OPFS运行SQLite,您可以使用屏幕外文档来实现.这里有一个例子.

您还可以克隆此存储库并运行示例-https://github.com/clmnin/sqlite-opfs-mv3

Manifest.json

{
  "manifest_version": 3,
  "name": "MV3 Sqlite OPFS Example",
  "version": "1",
  "description": "MV3 Sqlite OPFS Example",
  "background": {
    "service_worker": "index.js",
    "type": "module"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self' 'wasm-unsafe-eval'"
  },
  "permissions": [
    "offscreen"
  ]
}

后台服务工作者

Index.ts

console.log('bg ready');

let creating: Promise<void> | null;
async function setupOffscreenDocument(path: string) {
  // Check all windows controlled by the service worker to see if one
  // of them is the offscreen document with the given path
  if (await chrome.offscreen.hasDocument?.()) return;

  // create offscreen document
  if (creating) {
    await creating;
  } else {
    creating = chrome.offscreen.createDocument({
      url: chrome.runtime.getURL(path),
      reasons: [
        chrome.offscreen.Reason.WORKERS || chrome.offscreen.Reason.BLOBS,
      ],
      justification: "To run web worker to run sqlite",
    });
    await creating;
    creating = null;
  }
}

setupOffscreenDocument("Index.html");

屏幕外文档

Index.html

<!DOCTYPE html>
<script type="module" src="./Index.ts"></script>

Index.ts

const worker = new Worker(
  new URL("./工作簿.js", import.meta.url),
  { type: "module" },
);
worker.onmessage = function ({ data }) {
  switch (data.type) {
    case 'log':
      console.log(`Message: ${data.payload.args}`);
      break;
    default:
      console.log(`ERROR: Unhandled message: ${data.type}`);
  }
};

工作簿.js

import sqlite3InitModule from '@sqlite.org/sqlite-wasm';

const logHtml = function (cssClass, ...args) {
  postMessage({
    type: 'log',
    payload: { cssClass, args },
  });
};

const log = (...args) => logHtml('', ...args);
const error = (...args) => logHtml('error', ...args);

const start = function (sqlite3) {
  const capi = sqlite3.capi; // C-style API
  const oo = sqlite3.oo1; // High-level OO API
  log('SQLite3 version', capi.sqlite3_libversion(), capi.sqlite3_sourceid());
  let db;
  if ('OpfsDb' in oo) {
    db = new oo.OpfsDb('/mydb.sqlite3');
    log('The OPFS is available.');
    log('Persisted db =', db.filename);
  } else {
    db = new oo.DB('/mydb.sqlite3', 'ct');
    log('The OPFS is not available.');
    log('transient db =', db.filename);
  }

  try {
    log('Create a table...');
    db.exec('CREATE TABLE IF NOT EXISTS t(a,b)');
    log('Insert some data using exec()...');
    let i;
    for (i = 20; i <= 25; ++i) {
      db.exec({
        sql: 'INSERT INTO t(a,b) VALUES (?,?)',
        bind: [i, i * 2],
      });
    }
    log("Query data with exec() using rowMode 'array'...");
    db.exec({
      sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
      rowMode: 'array', // 'array' (default), 'object', or 'stmt'
      callback: function (row) {
        log('row ', ++this.counter, '=', row);
      }.bind({ counter: 0 }),
    });
  } finally {
    db.close();
  }
};

log('Loading and initializing sqlite3 module...');
sqlite3InitModule({
  print: log,
  printErr: error,
}).then(function (sqlite3) {
  log('Done initializing. Running demo...');
  try {
    start(sqlite3);
  } catch (e) {
    error('Exception:', e.message);
  }
});

Javascript相关问答推荐

如何在react + react路由域名中使用DeliverBrowserRouter?

Fastify错误:CORS策略已阻止从起源api-dev.example.com上的MLhttp请求

如何在不使用类型化数组的情况下将32位浮点数按位转换为整值?

如何解决CORS政策的问题

通过嵌套模型对象进行Mongoose搜索

如何粗体匹配的字母时输入搜索框使用javascript?

为什么当我解析一个promise时,输出处于挂起状态?

有没有可能使滑动img动画以更快的速度连续?

setcallback是什么时候放到macrotask队列上的?

Angular 中的类型错误上不存在获取属性

使用POST请求时,Req.Body为空

为什么123[';toString';].long返回1?

当我在Reaction中创建一个输入列表时,我的输入行为异常

如何使用<;Link>;执行与JS Reaction中的";window.Location=/GameOverDied;";类似的操作?

我想使用GAS和HTML将从Electron 表格中获得的信息插入到文本字段的初始值中

P5JS-绘制不重叠的圆

Pevent触发material 用户界面数据网格中的自动保存

谷歌饼图3D切片

bootstrap S JS赢得了REACT中的函数/加载

Chrome上的印度时区名S有问题吗?