@aztec/sqlite3mc-wasm 5.0.0-rc.1 → 5.0.0-rc.2

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.
@@ -1,4 +1,4 @@
1
- /*
1
+ /* @preserve
2
2
  2022-09-16
3
3
 
4
4
  The author disclaims copyright to this source code. In place of a
@@ -46,10 +46,19 @@
46
46
  theFunc().then(...) is not compatible with the change to
47
47
  synchronous, but we do do not use those APIs that way. i.e. we don't
48
48
  _need_ to change anything for this, but at some point (after Chrome
49
- versions (approximately) 104-107 are extinct) should change our
49
+ versions (approximately) 104-107 are extinct) we should change our
50
50
  usage of those methods to remove the "await".
51
51
  */
52
+
52
53
  "use strict";
54
+ const urlParams = new URL(globalThis.location.href).searchParams;
55
+ const vfsName = urlParams.get('vfs');
56
+ if( !vfsName ){
57
+ throw new Error("Expecting vfs=opfs|opfs-wl URL argument for this worker");
58
+ }
59
+
60
+ const workerId = (Math.random() * 10000000) | 0;
61
+ const isWebLocker = 'opfs-wl'===urlParams.get('vfs');
53
62
  const wPost = (type,...args)=>postMessage({type, payload:args});
54
63
  const installAsyncProxy = function(){
55
64
  const toss = function(...args){throw new Error(args.join(' '))};
@@ -64,6 +73,110 @@ const installAsyncProxy = function(){
64
73
  const state = Object.create(null);
65
74
 
66
75
 
76
+ const initS11n = function(){
77
+
78
+ if(state.s11n) return state.s11n;
79
+ const textDecoder = new TextDecoder(),
80
+ textEncoder = new TextEncoder('utf-8'),
81
+ viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
82
+ viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
83
+ state.s11n = Object.create(null);
84
+
85
+ const TypeIds = Object.create(null);
86
+ TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
87
+ TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
88
+ TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
89
+ TypeIds.string = { id: 4 };
90
+
91
+ const getTypeId = (v)=>(
92
+ TypeIds[typeof v]
93
+ || toss("Maintenance required: this value type cannot be serialized.",v)
94
+ );
95
+ const getTypeIdById = (tid)=>{
96
+ switch(tid){
97
+ case TypeIds.number.id: return TypeIds.number;
98
+ case TypeIds.bigint.id: return TypeIds.bigint;
99
+ case TypeIds.boolean.id: return TypeIds.boolean;
100
+ case TypeIds.string.id: return TypeIds.string;
101
+ default: toss("Invalid type ID:",tid);
102
+ }
103
+ };
104
+
105
+
106
+ state.s11n.deserialize = function(clear=false){
107
+ const t = performance.now();
108
+ const argc = viewU8[0];
109
+ const rc = argc ? [] : null;
110
+ if(argc){
111
+ const typeIds = [];
112
+ let offset = 1, i, n, v;
113
+ for(i = 0; i < argc; ++i, ++offset){
114
+ typeIds.push(getTypeIdById(viewU8[offset]));
115
+ }
116
+ for(i = 0; i < argc; ++i){
117
+ const t = typeIds[i];
118
+ if(t.getter){
119
+ v = viewDV[t.getter](offset, state.littleEndian);
120
+ offset += t.size;
121
+ }else{
122
+ n = viewDV.getInt32(offset, state.littleEndian);
123
+ offset += 4;
124
+ v = textDecoder.decode(viewU8.slice(offset, offset+n));
125
+ offset += n;
126
+ }
127
+ rc.push(v);
128
+ }
129
+ }
130
+ if(clear) viewU8[0] = 0;
131
+
132
+ return rc;
133
+ };
134
+
135
+
136
+ state.s11n.serialize = function(...args){
137
+ const t = performance.now();
138
+ if(args.length){
139
+
140
+ const typeIds = [];
141
+ let i = 0, offset = 1;
142
+ viewU8[0] = args.length & 0xff ;
143
+ for(; i < args.length; ++i, ++offset){
144
+
145
+ typeIds.push(getTypeId(args[i]));
146
+ viewU8[offset] = typeIds[i].id;
147
+ }
148
+ for(i = 0; i < args.length; ++i) {
149
+
150
+ const t = typeIds[i];
151
+ if(t.setter){
152
+ viewDV[t.setter](offset, args[i], state.littleEndian);
153
+ offset += t.size;
154
+ }else{
155
+ const s = textEncoder.encode(args[i]);
156
+ viewDV.setInt32(offset, s.byteLength, state.littleEndian);
157
+ offset += 4;
158
+ viewU8.set(s, offset);
159
+ offset += s.byteLength;
160
+ }
161
+ }
162
+
163
+ }else{
164
+ viewU8[0] = 0;
165
+ }
166
+ };
167
+
168
+ state.s11n.storeException = state.asyncS11nExceptions
169
+ ? ((priority,e)=>{
170
+ if(priority<=state.asyncS11nExceptions){
171
+ state.s11n.serialize([e.name,': ',e.message].join(""));
172
+ }
173
+ })
174
+ : ()=>{};
175
+
176
+ return state.s11n;
177
+ };
178
+
179
+
67
180
  state.verbose = 1;
68
181
 
69
182
  const loggers = {
@@ -72,7 +185,7 @@ const installAsyncProxy = function(){
72
185
  2:console.log.bind(console)
73
186
  };
74
187
  const logImpl = (level,...args)=>{
75
- if(state.verbose>level) loggers[level]("OPFS asyncer:",...args);
188
+ if(state.verbose>level) loggers[level](vfsName+' async-proxy',workerId+":",...args);
76
189
  };
77
190
  const log = (...args)=>logImpl(2, ...args);
78
191
  const warn = (...args)=>logImpl(1, ...args);
@@ -175,12 +288,12 @@ const installAsyncProxy = function(){
175
288
  };
176
289
 
177
290
 
178
- const getSyncHandle = async (fh,opName)=>{
291
+ const getSyncHandle = async (fh, opName, baseWaitTime, maxTries = 6)=>{
179
292
  if(!fh.syncHandle){
180
293
  const t = performance.now();
181
294
  log("Acquiring sync handle for",fh.filenameAbs);
182
- const maxTries = 6,
183
- msBase = state.asyncIdleWaitTime * 2;
295
+ const msBase = baseWaitTime ?? (state.asyncIdleWaitTime * 2);
296
+ maxTries ??= 6;
184
297
  let i = 1, ms = msBase;
185
298
  for(; true; ms = msBase * ++i){
186
299
  try {
@@ -309,24 +422,7 @@ const installAsyncProxy = function(){
309
422
  await releaseImplicitLock(fh);
310
423
  storeAndNotify('xFileSize', rc);
311
424
  },
312
- xLock: async function(fid,
313
- lockType){
314
- const fh = __openFiles[fid];
315
- let rc = 0;
316
- const oldLockType = fh.xLock;
317
- fh.xLock = lockType;
318
- if( !fh.syncHandle ){
319
- try {
320
- await getSyncHandle(fh,'xLock');
321
- __implicitLocks.delete(fid);
322
- }catch(e){
323
- state.s11n.storeException(1,e);
324
- rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK);
325
- fh.xLock = oldLockType;
326
- }
327
- }
328
- storeAndNotify('xLock',rc);
329
- },
425
+
330
426
  xOpen: async function(fid, filename,
331
427
  flags,
332
428
  opfsFlags){
@@ -384,7 +480,7 @@ const installAsyncProxy = function(){
384
480
  rc = state.sq3Codes.SQLITE_IOERR_SHORT_READ;
385
481
  }
386
482
  }catch(e){
387
- error("xRead() failed",e,fh);
483
+
388
484
  state.s11n.storeException(1,e);
389
485
  rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_READ);
390
486
  }
@@ -411,28 +507,13 @@ const installAsyncProxy = function(){
411
507
  affirmNotRO('xTruncate', fh);
412
508
  await (await getSyncHandle(fh,'xTruncate')).truncate(size);
413
509
  }catch(e){
414
- error("xTruncate():",e,fh);
510
+
415
511
  state.s11n.storeException(2,e);
416
512
  rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_TRUNCATE);
417
513
  }
418
514
  await releaseImplicitLock(fh);
419
515
  storeAndNotify('xTruncate',rc);
420
516
  },
421
- xUnlock: async function(fid,
422
- lockType){
423
- let rc = 0;
424
- const fh = __openFiles[fid];
425
- if( fh.syncHandle
426
- && state.sq3Codes.SQLITE_LOCK_NONE===lockType
427
- ){
428
- try { await closeSyncHandle(fh) }
429
- catch(e){
430
- state.s11n.storeException(1,e);
431
- rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
432
- }
433
- }
434
- storeAndNotify('xUnlock',rc);
435
- },
436
517
  xWrite: async function(fid,n,offset64){
437
518
  let rc;
438
519
  const fh = __openFiles[fid];
@@ -444,7 +525,7 @@ const installAsyncProxy = function(){
444
525
  {at: Number(offset64)})
445
526
  ) ? 0 : state.sq3Codes.SQLITE_IOERR_WRITE;
446
527
  }catch(e){
447
- error("xWrite():",e,fh);
528
+
448
529
  state.s11n.storeException(1,e);
449
530
  rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_WRITE);
450
531
  }
@@ -453,131 +534,201 @@ const installAsyncProxy = function(){
453
534
  }
454
535
  };
455
536
 
456
- const initS11n = ()=>{
537
+ if( isWebLocker ){
457
538
 
458
- if(state.s11n) return state.s11n;
459
- const textDecoder = new TextDecoder(),
460
- textEncoder = new TextEncoder('utf-8'),
461
- viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
462
- viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
463
- state.s11n = Object.create(null);
464
- const TypeIds = Object.create(null);
465
- TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
466
- TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
467
- TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
468
- TypeIds.string = { id: 4 };
469
- const getTypeId = (v)=>(
470
- TypeIds[typeof v]
471
- || toss("Maintenance required: this value type cannot be serialized.",v)
472
- );
473
- const getTypeIdById = (tid)=>{
474
- switch(tid){
475
- case TypeIds.number.id: return TypeIds.number;
476
- case TypeIds.bigint.id: return TypeIds.bigint;
477
- case TypeIds.boolean.id: return TypeIds.boolean;
478
- case TypeIds.string.id: return TypeIds.string;
479
- default: toss("Invalid type ID:",tid);
480
- }
481
- };
482
- state.s11n.deserialize = function(clear=false){
483
- const argc = viewU8[0];
484
- const rc = argc ? [] : null;
485
- if(argc){
486
- const typeIds = [];
487
- let offset = 1, i, n, v;
488
- for(i = 0; i < argc; ++i, ++offset){
489
- typeIds.push(getTypeIdById(viewU8[offset]));
539
+
540
+ const __activeWebLocks = Object.create(null);
541
+
542
+ vfsAsyncImpls.xLock = async function(fid,
543
+ lockType,
544
+ isFromUnlock){
545
+ const whichOp = isFromUnlock ? 'xUnlock' : 'xLock';
546
+ const fh = __openFiles[fid];
547
+
548
+ const requestedMode = (lockType >= state.sq3Codes.SQLITE_LOCK_RESERVED)
549
+ ? 'exclusive' : 'shared';
550
+ const existing = __activeWebLocks[fid];
551
+ if( existing ){
552
+ if( existing.mode === requestedMode
553
+ || (existing.mode === 'exclusive'
554
+ && requestedMode === 'shared') ) {
555
+ fh.xLock = lockType;
556
+ storeAndNotify(whichOp, 0);
557
+
558
+ return 0 ;
490
559
  }
491
- for(i = 0; i < argc; ++i){
492
- const t = typeIds[i];
493
- if(t.getter){
494
- v = viewDV[t.getter](offset, state.littleEndian);
495
- offset += t.size;
496
- }else{
497
- n = viewDV.getInt32(offset, state.littleEndian);
498
- offset += 4;
499
- v = textDecoder.decode(viewU8.slice(offset, offset+n));
500
- offset += n;
560
+
561
+ await closeSyncHandle(fh);
562
+ existing.resolveRelease();
563
+ delete __activeWebLocks[fid];
564
+ }
565
+
566
+ const lockName = "sqlite3-vfs-opfs:" + fh.filenameAbs;
567
+ const oldLockType = fh.xLock;
568
+ return new Promise((resolveWaitLoop) => {
569
+
570
+ navigator.locks.request(lockName, { mode: requestedMode }, async (lock) => {
571
+
572
+ __implicitLocks.delete(fid);
573
+ let rc = 0;
574
+ try{
575
+ fh.xLock = lockType;
576
+ await getSyncHandle(fh, 'xLock', state.asyncIdleWaitTime, 5);
577
+ }catch(e){
578
+ fh.xLock = oldLockType;
579
+ state.s11n.storeException(1, e);
580
+ rc = GetSyncHandleError.convertRc(e, state.sq3Codes.SQLITE_BUSY);
501
581
  }
502
- rc.push(v);
503
- }
582
+ const releasePromise = rc
583
+ ? undefined
584
+ : new Promise((resolveRelease) => {
585
+ __activeWebLocks[fid] = { mode: requestedMode, resolveRelease };
586
+ });
587
+ storeAndNotify(whichOp, rc) ;
588
+ resolveWaitLoop(0) ;
589
+ await releasePromise ;
590
+ });
591
+ });
592
+ };
593
+
594
+
595
+ const wlCloseHandle = async(fh)=>{
596
+ let rc = 0;
597
+ try{
598
+
599
+ await closeSyncHandle(fh);
600
+ }catch(e){
601
+ state.s11n.storeException(1,e);
602
+ rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
504
603
  }
505
- if(clear) viewU8[0] = 0;
506
-
507
604
  return rc;
508
605
  };
509
- state.s11n.serialize = function(...args){
510
- if(args.length){
606
+
607
+ vfsAsyncImpls.xUnlock = async function(fid,
608
+ lockType){
609
+ const fh = __openFiles[fid];
610
+ const existing = __activeWebLocks[fid];
611
+ if( !existing ){
612
+ const rc = await wlCloseHandle(fh);
613
+ storeAndNotify('xUnlock', rc);
614
+ return rc;
615
+ }
616
+
617
+ let rc = 0;
618
+ if( lockType === state.sq3Codes.SQLITE_LOCK_NONE ){
511
619
 
512
- const typeIds = [];
513
- let i = 0, offset = 1;
514
- viewU8[0] = args.length & 0xff ;
515
- for(; i < args.length; ++i, ++offset){
516
-
517
- typeIds.push(getTypeId(args[i]));
518
- viewU8[offset] = typeIds[i].id;
519
- }
520
- for(i = 0; i < args.length; ++i) {
521
-
522
- const t = typeIds[i];
523
- if(t.setter){
524
- viewDV[t.setter](offset, args[i], state.littleEndian);
525
- offset += t.size;
526
- }else{
527
- const s = textEncoder.encode(args[i]);
528
- viewDV.setInt32(offset, s.byteLength, state.littleEndian);
529
- offset += 4;
530
- viewU8.set(s, offset);
531
- offset += s.byteLength;
532
- }
533
- }
620
+ rc = await wlCloseHandle(fh);
621
+ existing.resolveRelease();
622
+ delete __activeWebLocks[fid];
623
+ fh.xLock = lockType;
624
+ }else if( lockType === state.sq3Codes.SQLITE_LOCK_SHARED
625
+ && existing.mode === 'exclusive' ){
534
626
 
627
+ rc = await wlCloseHandle(fh);
628
+ if( 0===rc ){
629
+ fh.xLock = lockType;
630
+ existing.resolveRelease();
631
+ delete __activeWebLocks[fid];
632
+ return vfsAsyncImpls.xLock(fid, lockType, true);
633
+ }
535
634
  }else{
536
- viewU8[0] = 0;
635
+
636
+ error("xUnlock() unhandled condition", fh);
637
+ }
638
+ storeAndNotify('xUnlock', rc);
639
+ return 0;
640
+ }
641
+
642
+ }else{
643
+
644
+
645
+ vfsAsyncImpls.xLock = async function(fid,
646
+ lockType){
647
+ const fh = __openFiles[fid];
648
+ let rc = 0;
649
+ const oldLockType = fh.xLock;
650
+ fh.xLock = lockType;
651
+ if( !fh.syncHandle ){
652
+ try {
653
+ await getSyncHandle(fh,'xLock');
654
+ __implicitLocks.delete(fid);
655
+ }catch(e){
656
+ state.s11n.storeException(1,e);
657
+ rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK);
658
+ fh.xLock = oldLockType;
659
+ }
537
660
  }
661
+ storeAndNotify('xLock',rc);
538
662
  };
539
663
 
540
- state.s11n.storeException = state.asyncS11nExceptions
541
- ? ((priority,e)=>{
542
- if(priority<=state.asyncS11nExceptions){
543
- state.s11n.serialize([e.name,': ',e.message].join(""));
664
+ vfsAsyncImpls.xUnlock = async function(fid,
665
+ lockType){
666
+ let rc = 0;
667
+ const fh = __openFiles[fid];
668
+ if( fh.syncHandle
669
+ && state.sq3Codes.SQLITE_LOCK_NONE===lockType
670
+ ){
671
+ try { await closeSyncHandle(fh) }
672
+ catch(e){
673
+ state.s11n.storeException(1,e);
674
+ rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
544
675
  }
545
- })
546
- : ()=>{};
676
+ }
677
+ storeAndNotify('xUnlock',rc);
678
+ }
547
679
 
548
- return state.s11n;
549
- };
680
+ }
550
681
 
551
682
  const waitLoop = async function f(){
552
- const opHandlers = Object.create(null);
553
- for(let k of Object.keys(state.opIds)){
554
- const vi = vfsAsyncImpls[k];
555
- if(!vi) continue;
556
- const o = Object.create(null);
557
- opHandlers[state.opIds[k]] = o;
558
- o.key = k;
559
- o.f = vi;
683
+ if( !f.inited ){
684
+ f.inited = true;
685
+ f.opHandlers = Object.create(null);
686
+ for(let k of Object.keys(state.opIds)){
687
+ const vi = vfsAsyncImpls[k];
688
+ if(!vi) continue;
689
+ const o = Object.create(null);
690
+ f.opHandlers[state.opIds[k]] = o;
691
+ o.key = k;
692
+ o.f = vi;
693
+ }
560
694
  }
695
+ const opIds = state.opIds;
696
+ const opView = state.sabOPView;
697
+ const slotWhichOp = opIds.whichOp;
698
+ const idleWaitTime = state.asyncIdleWaitTime;
699
+ const hasWaitAsync = !!Atomics.waitAsync;
561
700
  while(!flagAsyncShutdown){
562
701
  try {
563
- if('not-equal'!==Atomics.wait(
564
- state.sabOPView, state.opIds.whichOp, 0, state.asyncIdleWaitTime
565
- )){
702
+ let opId;
703
+ if( hasWaitAsync ){
704
+ opId = Atomics.load(opView, slotWhichOp);
705
+ if( 0===opId ){
706
+ const rv = Atomics.waitAsync(opView, slotWhichOp, 0,
707
+ idleWaitTime);
708
+ if( rv.async ) await rv.value;
709
+ await releaseImplicitLocks();
710
+ continue;
711
+ }
712
+ }else{
566
713
 
567
- await releaseImplicitLocks();
568
- continue;
714
+ if('not-equal'!==Atomics.wait(
715
+ state.sabOPView, slotWhichOp, 0, state.asyncIdleWaitTime
716
+ )){
717
+
718
+ await releaseImplicitLocks();
719
+ continue;
720
+ }
721
+ opId = Atomics.load(state.sabOPView, slotWhichOp);
569
722
  }
570
- const opId = Atomics.load(state.sabOPView, state.opIds.whichOp);
571
- Atomics.store(state.sabOPView, state.opIds.whichOp, 0);
572
- const hnd = opHandlers[opId] ?? toss("No waitLoop handler for whichOp #",opId);
723
+ Atomics.store(opView, slotWhichOp, 0);
724
+ const hnd = f.opHandlers[opId]?.f ?? toss("No waitLoop handler for whichOp #",opId);
573
725
  const args = state.s11n.deserialize(
574
726
  true
575
727
  ) || [];
576
728
 
577
- if(hnd.f) await hnd.f(...args);
578
- else error("Missing callback for opId",opId);
729
+ await hnd(...args);
579
730
  }catch(e){
580
- error('in waitLoop():',e);
731
+ error('in waitLoop():', e);
581
732
  }
582
733
  }
583
734
  };
@@ -585,6 +736,7 @@ const installAsyncProxy = function(){
585
736
  navigator.storage.getDirectory().then(function(d){
586
737
  state.rootDir = d;
587
738
  globalThis.onmessage = function({data}){
739
+
588
740
  switch(data.type){
589
741
  case 'opfs-async-init':{
590
742
 
@@ -600,6 +752,7 @@ const installAsyncProxy = function(){
600
752
  }
601
753
  });
602
754
  initS11n();
755
+
603
756
  log("init state",state);
604
757
  wPost('opfs-async-inited');
605
758
  waitLoop();
@@ -611,22 +764,27 @@ const installAsyncProxy = function(){
611
764
  flagAsyncShutdown = false;
612
765
  waitLoop();
613
766
  }
614
- break;
767
+ break;
615
768
  }
616
769
  };
617
770
  wPost('opfs-async-loaded');
618
771
  }).catch((e)=>error("error initializing OPFS asyncer:",e));
619
772
  };
620
- if(!globalThis.SharedArrayBuffer){
773
+ if(globalThis.window === globalThis){
774
+ wPost('opfs-unavailable',
775
+ "This code cannot run from the main thread.",
776
+ "Load it as a Worker from a separate Worker.");
777
+ }else if(!globalThis.SharedArrayBuffer){
621
778
  wPost('opfs-unavailable', "Missing SharedArrayBuffer API.",
622
779
  "The server must emit the COOP/COEP response headers to enable that.");
623
780
  }else if(!globalThis.Atomics){
624
781
  wPost('opfs-unavailable', "Missing Atomics API.",
625
782
  "The server must emit the COOP/COEP response headers to enable that.");
783
+ }else if(isWebLocker && !globalThis.Atomics.waitAsync){
784
+ wPost('opfs-unavailable',"Missing required Atomics.waitSync() for "+vfsName);
626
785
  }else if(!globalThis.FileSystemHandle ||
627
786
  !globalThis.FileSystemDirectoryHandle ||
628
- !globalThis.FileSystemFileHandle ||
629
- !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
787
+ !globalThis.FileSystemFileHandle?.prototype?.createSyncAccessHandle ||
630
788
  !navigator?.storage?.getDirectory){
631
789
  wPost('opfs-unavailable',"Missing required OPFS APIs.");
632
790
  }else{
@@ -31,5 +31,5 @@
31
31
  - `sqlite3.dir`, if set, treats the given directory name as the
32
32
  directory from which `sqlite3.js` will be loaded.
33
33
  */
34
- import {default as sqlite3InitModule} from './sqlite3-bundler-friendly.mjs';
34
+ import sqlite3InitModule from './sqlite3-bundler-friendly.mjs';
35
35
  sqlite3InitModule().then(sqlite3 => sqlite3.initWorker1API());