@aiao/rxdb-adapter-sqliteai 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/dist/{RxDBAdapterSqliteai-Bebaerj4.js → RxDBAdapterSqliteai-DSoEdAS9.js} +12 -2
- package/dist/RxDBAdapterSqliteai.d.ts +6 -1
- package/dist/RxDBAdapterSqliteai.d.ts.map +1 -1
- package/dist/assets/sqlite3-opfs-async-proxy-jAvfsIBX.js +1 -0
- package/dist/assets/sqlite3-worker1-bundler-friendly-CIDbdn0f.js +5 -0
- package/dist/assets/sqliteai-test.worker-DhICqctS.js +32 -0
- package/dist/create_sqlite_client.d.ts +3 -2
- package/dist/create_sqlite_client.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/testing.js +2833 -297
- package/package.json +12 -7
- package/src/RxDBAdapterSqliteai.ts +11 -1
- package/src/create_sqlite_client.ts +5 -4
- package/dist/assets/sqlite3-opfs-async-proxy-CPArLPLU.js +0 -1
- package/dist/assets/sqlite3-worker1-bundler-friendly-C9ENWE60.js +0 -3
- package/dist/assets/sqliteai-test.worker-CTOPs2O0.js +0 -23
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiao/rxdb-adapter-sqliteai",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"description": "SQLiteAI adapter with vector and AI functions for Aiao RxDB.",
|
|
5
|
-
"homepage": "https://rxdb.
|
|
5
|
+
"homepage": "https://rxdb.aiao.io/docs/adapters/sqliteai",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/aiao-io/rxdb/issues"
|
|
8
8
|
},
|
|
@@ -57,14 +57,19 @@
|
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@sqliteai/sqlite-wasm": "3.50.4-wasm.1.0.0-sync.1.
|
|
61
|
-
"@aiao/rxdb": "0.0.
|
|
62
|
-
"@aiao/rxdb-adapter-sqlite-core": "0.0.26"
|
|
60
|
+
"@sqliteai/sqlite-wasm": "3.50.4-wasm.1.0.0-sync.1.2.0-vector.1.1.2-memory.1.3.5",
|
|
61
|
+
"@aiao/rxdb-adapter-sqlite-core": "^0.0.28"
|
|
63
62
|
},
|
|
64
63
|
"devDependencies": {
|
|
65
64
|
"comlink": "^4.4.2",
|
|
66
65
|
"ms": "^2.1.3",
|
|
67
|
-
"@aiao/rxdb-plugin-
|
|
68
|
-
"@aiao/rxdb-test": "0.0.
|
|
66
|
+
"@aiao/rxdb-plugin-working-tree": "0.0.28",
|
|
67
|
+
"@aiao/rxdb-test": "0.0.28",
|
|
68
|
+
"@aiao/rxdb-plugin-sync": "0.0.28",
|
|
69
|
+
"@aiao/rxdb-plugin-history": "0.0.28",
|
|
70
|
+
"@aiao/rxdb-plugin-querycache": "0.0.28"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"@aiao/rxdb": "^0.0.28"
|
|
69
74
|
}
|
|
70
75
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RxDB } from '@aiao/rxdb';
|
|
2
|
-
import { RxDBAdapterSqliteBase, type SqliteClientLike } from '@aiao/rxdb-adapter-sqlite-core';
|
|
2
|
+
import { RxDBAdapterSqliteBase, type SqliteBackupStorage, type SqliteClientLike } from '@aiao/rxdb-adapter-sqlite-core';
|
|
3
3
|
import { createSqliteClient } from './create_sqlite_client.js';
|
|
4
4
|
import { ADAPTER_NAME, type SqliteaiOptions } from './sqliteai.interface.js';
|
|
5
5
|
|
|
@@ -22,6 +22,16 @@ export class RxDBAdapterSqliteai extends RxDBAdapterSqliteBase {
|
|
|
22
22
|
this.#dbName = rxdb.config.dbName;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* 不开 OPFS 时是内存库;开 OPFS 时是持久化库。
|
|
27
|
+
* `opfsFallback: 'memory'` 会在 OPFS 打不开时静默落到内存,恢复目标不确定,报 `unsupported_combination`。
|
|
28
|
+
*/
|
|
29
|
+
protected override backupStorage(): SqliteBackupStorage {
|
|
30
|
+
if (!this.options.opfs) return { kind: 'memory', label: 'memory' };
|
|
31
|
+
if (this.options.opfsFallback === 'memory') return { kind: 'unsupported', field: 'opfsFallback', actual: 'memory' };
|
|
32
|
+
return this.persistentBackupStorage('opfs');
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
protected override async createClient(): Promise<SqliteClientLike> {
|
|
26
36
|
return createSqliteClient(this.#dbName, this.options);
|
|
27
37
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertLoadOptionsTransferable,
|
|
3
3
|
releaseComlinkProxy,
|
|
4
|
-
|
|
4
|
+
wrapWithComlinkEndpoint,
|
|
5
5
|
type SqliteClientLike
|
|
6
6
|
} from '@aiao/rxdb-adapter-sqlite-core';
|
|
7
7
|
import { SqliteaiOptions, type SqliteaiLoadOptions } from './sqliteai.interface.js';
|
|
@@ -10,8 +10,9 @@ import { SqliteaiClient } from './SqliteaiClient.js';
|
|
|
10
10
|
/**
|
|
11
11
|
* 创建 SqliteAI 客户端实例并完成初始化。
|
|
12
12
|
*
|
|
13
|
-
* 如果 `options` 中指定了 worker / sharedWorker,会通过 `
|
|
14
|
-
*
|
|
13
|
+
* 如果 `options` 中指定了 worker / sharedWorker,会通过 `wrapWithComlinkEndpoint` 为这次连接租用
|
|
14
|
+
* worker 的一条独立子端口;否则在主线程直接 new。释放后同一个 worker 可以再连:恢复先用一条连接写库,
|
|
15
|
+
* 之后的 `connect()` 再开一条。
|
|
15
16
|
*
|
|
16
17
|
* 返回类型是 {@link SqliteClientLike} 而非具体的 `SqliteaiClient`:worker 模式下拿到的是
|
|
17
18
|
* Comlink 远端代理,它把每个方法都 Promise 化,断言成实现类会让 `beginTransactionSql(): string`
|
|
@@ -37,7 +38,7 @@ export async function createSqliteClient(dbName: string, options: SqliteaiOption
|
|
|
37
38
|
|
|
38
39
|
assertLoadOptionsTransferable(loadOptions, options);
|
|
39
40
|
|
|
40
|
-
const client =
|
|
41
|
+
const client = await wrapWithComlinkEndpoint(new SqliteaiClient(), options);
|
|
41
42
|
try {
|
|
42
43
|
await client.init(dbName, loadOptions);
|
|
43
44
|
return client;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(function(){let e=(e,...t)=>postMessage({type:e,payload:t});globalThis.SharedArrayBuffer?globalThis.Atomics?!globalThis.FileSystemHandle||!globalThis.FileSystemDirectoryHandle||!globalThis.FileSystemFileHandle||!globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle||!navigator?.storage?.getDirectory?e(`opfs-unavailable`,`Missing required OPFS APIs.`):function(){let t=function(...e){throw Error(e.join(` `))};globalThis.window===globalThis?t(`This code cannot run from the main thread.`,`Load it as a Worker from a separate Worker.`):navigator?.storage?.getDirectory||t(`This API requires navigator.storage.getDirectory.`);let n=Object.create(null);n.verbose=1;let r={0:console.error.bind(console),1:console.warn.bind(console),2:console.log.bind(console)},i=(e,...t)=>{n.verbose>e&&r[e](`OPFS asyncer:`,...t)},a=(...e)=>i(2,...e),o=(...e)=>i(1,...e),s=(...e)=>i(0,...e),c=Object.create(null),l=new Set,u=function(e,t){let n=new URL(e,`file://irrelevant`).pathname;return t?n.split(`/`).filter(e=>!!e):n},d=async function(e,t=!1){let r=u(e,!0),i=r.pop(),a=n.rootDir;for(let e of r)e&&(a=await a.getDirectoryHandle(e,{create:!!t}));return[a,i]},f=async e=>{if(e.syncHandle){a(`Closing sync handle for`,e.filenameAbs);let t=e.syncHandle;return delete e.syncHandle,delete e.xLock,l.delete(e.fid),t.close()}},p=async e=>{try{await f(e)}catch(t){o(`closeSyncHandleNoThrow() ignoring:`,t,e)}},m=async()=>{if(l.size)for(let e of l){let t=c[e];await p(t),a(`Auto-unlocked`,e,t.filenameAbs)}},h=async e=>{if(e.releaseImplicitLocks&&l.has(e.fid))return p(e)};class g extends Error{constructor(e,...t){super([...t,`: `+e.name+`:`,e.message].join(` `),{cause:e}),this.name=`GetSyncHandleError`}}g.convertRc=(e,t)=>{if(e instanceof g){if(e.cause.name===`NoModificationAllowedError`||e.cause.name===`DOMException`&&e.cause.message.indexOf(`Access Handles cannot`)===0)return n.sq3Codes.SQLITE_BUSY;if(e.cause.name===`NotFoundError`)return n.sq3Codes.SQLITE_CANTOPEN}else if(e?.name===`NotFoundError`)return n.sq3Codes.SQLITE_CANTOPEN;return t};let _=async(e,t)=>{if(!e.syncHandle){let r=performance.now();a(`Acquiring sync handle for`,e.filenameAbs);let i=n.asyncIdleWaitTime*2,s=1,c=i;for(;;c=i*++s)try{e.syncHandle=await e.fileHandle.createSyncAccessHandle();break}catch(r){if(s===6)throw new g(r,`Error getting sync handle for`,t+`().`,6,`attempts failed.`,e.filenameAbs);o(`Error getting sync handle for`,t+`(). Waiting`,c,`ms and trying again.`,e.filenameAbs,r),Atomics.wait(n.sabOPView,n.opIds.retry,0,c)}a(`Got`,t+`() sync handle for`,e.filenameAbs,`in`,performance.now()-r,`ms`),e.xLock||(l.add(e.fid),a(`Acquired implicit lock for`,t+`()`,e.fid,e.filenameAbs))}return e.syncHandle},v=(e,t)=>{a(e+`() => notify(`,t,`)`),Atomics.store(n.sabOPView,n.opIds.rc,t),Atomics.notify(n.sabOPView,n.opIds.rc)},y=function(e,n){n.readOnly&&t(e+`(): File is read-only: `+n.filenameAbs)},b=!1,x={"opfs-async-shutdown":async()=>{b=!0,v(`opfs-async-shutdown`,0)},mkdir:async e=>{let t=0;try{await d(e+`/filepart`,!0)}catch(e){n.s11n.storeException(2,e),t=n.sq3Codes.SQLITE_IOERR}v(`mkdir`,t)},xAccess:async e=>{let t=0;try{let[t,n]=await d(e);await t.getFileHandle(n)}catch(e){n.s11n.storeException(2,e),t=n.sq3Codes.SQLITE_IOERR}v(`xAccess`,t)},xClose:async function(e){l.delete(e);let t=c[e],r=0;if(t){if(delete c[e],await f(t),t.deleteOnClose)try{await t.dirHandle.removeEntry(t.filenamePart)}catch(e){o(`Ignoring dirHandle.removeEntry() failure of`,t,e)}}else n.s11n.serialize(),r=n.sq3Codes.SQLITE_NOTFOUND;v(`xClose`,r)},xDelete:async function(...e){let t=await x.xDeleteNoWait(...e);v(`xDelete`,t)},xDeleteNoWait:async function(e,t=0,r=!1){let i=0;try{for(;e;){let[n,i]=await d(e,!1);if(!i||(await n.removeEntry(i,{recursive:r}),t!==4660))break;r=!1,e=u(e,!0),e.pop(),e=e.join(`/`)}}catch(e){n.s11n.storeException(2,e),i=n.sq3Codes.SQLITE_IOERR_DELETE}return i},xFileSize:async function(e){let t=c[e],r=0;try{let e=await(await _(t,`xFileSize`)).getSize();n.s11n.serialize(Number(e))}catch(e){n.s11n.storeException(1,e),r=g.convertRc(e,n.sq3Codes.SQLITE_IOERR)}await h(t),v(`xFileSize`,r)},xLock:async function(e,t){let r=c[e],i=0,a=r.xLock;if(r.xLock=t,!r.syncHandle)try{await _(r,`xLock`),l.delete(e)}catch(e){n.s11n.storeException(1,e),i=g.convertRc(e,n.sq3Codes.SQLITE_IOERR_LOCK),r.xLock=a}v(`xLock`,i)},xOpen:async function(e,t,r,i){let a=`xOpen`,o=n.sq3Codes.SQLITE_OPEN_CREATE&r;try{let s,l;try{[s,l]=await d(t,!!o)}catch(e){n.s11n.storeException(1,e),v(a,n.sq3Codes.SQLITE_NOTFOUND);return}if(n.opfsFlags.OPFS_UNLINK_BEFORE_OPEN&i)try{await s.removeEntry(l)}catch{}let u=await s.getFileHandle(l,{create:o}),f=Object.assign(Object.create(null),{fid:e,filenameAbs:t,filenamePart:l,dirHandle:s,fileHandle:u,sabView:n.sabFileBufView,readOnly:!o&&!!(n.sq3Codes.SQLITE_OPEN_READONLY&r),deleteOnClose:!!(n.sq3Codes.SQLITE_OPEN_DELETEONCLOSE&r)});f.releaseImplicitLocks=i&n.opfsFlags.OPFS_UNLOCK_ASAP||n.opfsFlags.defaultUnlockAsap,c[e]=f,v(a,0)}catch(e){s(a,e),n.s11n.storeException(1,e),v(a,n.sq3Codes.SQLITE_IOERR)}},xRead:async function(e,t,r){let i=0,a,o=c[e];try{a=(await _(o,`xRead`)).read(o.sabView.subarray(0,t),{at:Number(r)}),a<t&&(o.sabView.fill(0,a,t),i=n.sq3Codes.SQLITE_IOERR_SHORT_READ)}catch(e){s(`xRead() failed`,e,o),n.s11n.storeException(1,e),i=g.convertRc(e,n.sq3Codes.SQLITE_IOERR_READ)}await h(o),v(`xRead`,i)},xSync:async function(e,t){let r=c[e],i=0;if(!r.readOnly&&r.syncHandle)try{await r.syncHandle.flush()}catch(e){n.s11n.storeException(2,e),i=n.sq3Codes.SQLITE_IOERR_FSYNC}v(`xSync`,i)},xTruncate:async function(e,t){let r=0,i=c[e];try{y(`xTruncate`,i),await(await _(i,`xTruncate`)).truncate(t)}catch(e){s(`xTruncate():`,e,i),n.s11n.storeException(2,e),r=g.convertRc(e,n.sq3Codes.SQLITE_IOERR_TRUNCATE)}await h(i),v(`xTruncate`,r)},xUnlock:async function(e,t){let r=0,i=c[e];if(i.syncHandle&&n.sq3Codes.SQLITE_LOCK_NONE===t)try{await f(i)}catch(e){n.s11n.storeException(1,e),r=n.sq3Codes.SQLITE_IOERR_UNLOCK}v(`xUnlock`,r)},xWrite:async function(e,t,r){let i,a=c[e];try{y(`xWrite`,a),i=t===(await _(a,`xWrite`)).write(a.sabView.subarray(0,t),{at:Number(r)})?0:n.sq3Codes.SQLITE_IOERR_WRITE}catch(e){s(`xWrite():`,e,a),n.s11n.storeException(1,e),i=g.convertRc(e,n.sq3Codes.SQLITE_IOERR_WRITE)}await h(a),v(`xWrite`,i)}},S=()=>{if(n.s11n)return n.s11n;let e=new TextDecoder,r=new TextEncoder(`utf-8`),i=new Uint8Array(n.sabIO,n.sabS11nOffset,n.sabS11nSize),a=new DataView(n.sabIO,n.sabS11nOffset,n.sabS11nSize);n.s11n=Object.create(null);let o=Object.create(null);o.number={id:1,size:8,getter:`getFloat64`,setter:`setFloat64`},o.bigint={id:2,size:8,getter:`getBigInt64`,setter:`setBigInt64`},o.boolean={id:3,size:4,getter:`getInt32`,setter:`setInt32`},o.string={id:4};let s=e=>o[typeof e]||t(`Maintenance required: this value type cannot be serialized.`,e),c=e=>{switch(e){case o.number.id:return o.number;case o.bigint.id:return o.bigint;case o.boolean.id:return o.boolean;case o.string.id:return o.string;default:t(`Invalid type ID:`,e)}};return n.s11n.deserialize=function(t=!1){let r=i[0],o=r?[]:null;if(r){let t=[],s=1,l,u,d;for(l=0;l<r;++l,++s)t.push(c(i[s]));for(l=0;l<r;++l){let r=t[l];r.getter?(d=a[r.getter](s,n.littleEndian),s+=r.size):(u=a.getInt32(s,n.littleEndian),s+=4,d=e.decode(i.slice(s,s+u)),s+=u),o.push(d)}}return t&&(i[0]=0),o},n.s11n.serialize=function(...e){if(e.length){let t=[],o=0,c=1;for(i[0]=e.length&255;o<e.length;++o,++c)t.push(s(e[o])),i[c]=t[o].id;for(o=0;o<e.length;++o){let s=t[o];if(s.setter)a[s.setter](c,e[o],n.littleEndian),c+=s.size;else{let t=r.encode(e[o]);a.setInt32(c,t.byteLength,n.littleEndian),c+=4,i.set(t,c),c+=t.byteLength}}}else i[0]=0},n.s11n.storeException=n.asyncS11nExceptions?(e,t)=>{e<=n.asyncS11nExceptions&&n.s11n.serialize([t.name,`: `,t.message].join(``))}:()=>{},n.s11n},C=async function(){let e=Object.create(null);for(let t of Object.keys(n.opIds)){let r=x[t];if(!r)continue;let i=Object.create(null);e[n.opIds[t]]=i,i.key=t,i.f=r}for(;!b;)try{if(Atomics.wait(n.sabOPView,n.opIds.whichOp,0,n.asyncIdleWaitTime)!==`not-equal`){await m();continue}let r=Atomics.load(n.sabOPView,n.opIds.whichOp);Atomics.store(n.sabOPView,n.opIds.whichOp,0);let i=e[r]??t(`No waitLoop handler for whichOp #`,r),a=n.s11n.deserialize(!0)||[];i.f?await i.f(...a):s(`Missing callback for opId`,r)}catch(e){s(`in waitLoop():`,e)}};navigator.storage.getDirectory().then(function(r){n.rootDir=r,globalThis.onmessage=function({data:r}){switch(r.type){case`opfs-async-init`:{let i=r.args;for(let e in i)n[e]=i[e];n.verbose=i.verbose??1,n.sabOPView=new Int32Array(n.sabOP),n.sabFileBufView=new Uint8Array(n.sabIO,0,n.fileBufferSize),n.sabS11nView=new Uint8Array(n.sabIO,n.sabS11nOffset,n.sabS11nSize),Object.keys(x).forEach(e=>{Number.isFinite(n.opIds[e])||t(`Maintenance required: missing state.opIds[`,e,`]`)}),S(),a(`init state`,n),e(`opfs-async-inited`),C();break}case`opfs-async-restart`:b&&(o(`Restarting after opfs-async-shutdown. Might or might not work.`),b=!1,C())}},e(`opfs-async-loaded`)}).catch(e=>s(`error initializing OPFS asyncer:`,e))}():e(`opfs-unavailable`,`Missing Atomics API.`,`The server must emit the COOP/COEP response headers to enable that.`):e(`opfs-unavailable`,`Missing SharedArrayBuffer API.`,`The server must emit the COOP/COEP response headers to enable that.`)})();
|