@lvce-editor/chat-storage-worker 1.2.0 → 1.3.0

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,59 +1,3 @@
1
- const normalizeLine = line => {
2
- if (line.startsWith('Error: ')) {
3
- return line.slice('Error: '.length);
4
- }
5
- if (line.startsWith('VError: ')) {
6
- return line.slice('VError: '.length);
7
- }
8
- return line;
9
- };
10
- const getCombinedMessage = (error, message) => {
11
- const stringifiedError = normalizeLine(`${error}`);
12
- if (message) {
13
- return `${message}: ${stringifiedError}`;
14
- }
15
- return stringifiedError;
16
- };
17
- const NewLine$2 = '\n';
18
- const getNewLineIndex$1 = (string, startIndex = undefined) => {
19
- return string.indexOf(NewLine$2, startIndex);
20
- };
21
- const mergeStacks = (parent, child) => {
22
- if (!child) {
23
- return parent;
24
- }
25
- const parentNewLineIndex = getNewLineIndex$1(parent);
26
- const childNewLineIndex = getNewLineIndex$1(child);
27
- if (childNewLineIndex === -1) {
28
- return parent;
29
- }
30
- const parentFirstLine = parent.slice(0, parentNewLineIndex);
31
- const childRest = child.slice(childNewLineIndex);
32
- const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
33
- if (parentFirstLine.includes(childFirstLine)) {
34
- return parentFirstLine + childRest;
35
- }
36
- return child;
37
- };
38
- class VError extends Error {
39
- constructor(error, message) {
40
- const combinedMessage = getCombinedMessage(error, message);
41
- super(combinedMessage);
42
- this.name = 'VError';
43
- if (error instanceof Error) {
44
- this.stack = mergeStacks(this.stack, error.stack);
45
- }
46
- if (error.codeFrame) {
47
- // @ts-ignore
48
- this.codeFrame = error.codeFrame;
49
- }
50
- if (error.code) {
51
- // @ts-ignore
52
- this.code = error.code;
53
- }
54
- }
55
- }
56
-
57
1
  const isMessagePort = value => {
58
2
  return value && value instanceof MessagePort;
59
3
  };
@@ -124,145 +68,6 @@ class Ipc extends EventTarget {
124
68
  attachEvents(this);
125
69
  }
126
70
  }
127
- const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
128
- const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
129
- const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
130
- const NewLine$1 = '\n';
131
- const joinLines$1 = lines => {
132
- return lines.join(NewLine$1);
133
- };
134
- const RE_AT = /^\s+at/;
135
- const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
136
- const isNormalStackLine = line => {
137
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
138
- };
139
- const getDetails = lines => {
140
- const index = lines.findIndex(isNormalStackLine);
141
- if (index === -1) {
142
- return {
143
- actualMessage: joinLines$1(lines),
144
- rest: []
145
- };
146
- }
147
- let lastIndex = index - 1;
148
- while (++lastIndex < lines.length) {
149
- if (!isNormalStackLine(lines[lastIndex])) {
150
- break;
151
- }
152
- }
153
- return {
154
- actualMessage: lines[index - 1],
155
- rest: lines.slice(index, lastIndex)
156
- };
157
- };
158
- const splitLines$1 = lines => {
159
- return lines.split(NewLine$1);
160
- };
161
- const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
162
- const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
163
- const isMessageCodeBlockStartIndex = line => {
164
- return RE_MESSAGE_CODE_BLOCK_START.test(line);
165
- };
166
- const isMessageCodeBlockEndIndex = line => {
167
- return RE_MESSAGE_CODE_BLOCK_END.test(line);
168
- };
169
- const getMessageCodeBlock = stderr => {
170
- const lines = splitLines$1(stderr);
171
- const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
172
- const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
173
- const relevantLines = lines.slice(startIndex, endIndex);
174
- const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
175
- return relevantMessage;
176
- };
177
- const isModuleNotFoundMessage = line => {
178
- return line.includes('[ERR_MODULE_NOT_FOUND]');
179
- };
180
- const getModuleNotFoundError = stderr => {
181
- const lines = splitLines$1(stderr);
182
- const messageIndex = lines.findIndex(isModuleNotFoundMessage);
183
- const message = lines[messageIndex];
184
- return {
185
- code: ERR_MODULE_NOT_FOUND,
186
- message
187
- };
188
- };
189
- const isModuleNotFoundError = stderr => {
190
- if (!stderr) {
191
- return false;
192
- }
193
- return stderr.includes('ERR_MODULE_NOT_FOUND');
194
- };
195
- const isModulesSyntaxError = stderr => {
196
- if (!stderr) {
197
- return false;
198
- }
199
- return stderr.includes('SyntaxError: Cannot use import statement outside a module');
200
- };
201
- const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
202
- const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
203
- const isUnhelpfulNativeModuleError = stderr => {
204
- return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
205
- };
206
- const getNativeModuleErrorMessage = stderr => {
207
- const message = getMessageCodeBlock(stderr);
208
- return {
209
- code: E_INCOMPATIBLE_NATIVE_MODULE,
210
- message: `Incompatible native node module: ${message}`
211
- };
212
- };
213
- const getModuleSyntaxError = () => {
214
- return {
215
- code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
216
- message: `ES Modules are not supported in electron`
217
- };
218
- };
219
- const getHelpfulChildProcessError = (stdout, stderr) => {
220
- if (isUnhelpfulNativeModuleError(stderr)) {
221
- return getNativeModuleErrorMessage(stderr);
222
- }
223
- if (isModulesSyntaxError(stderr)) {
224
- return getModuleSyntaxError();
225
- }
226
- if (isModuleNotFoundError(stderr)) {
227
- return getModuleNotFoundError(stderr);
228
- }
229
- const lines = splitLines$1(stderr);
230
- const {
231
- actualMessage,
232
- rest
233
- } = getDetails(lines);
234
- return {
235
- code: '',
236
- message: actualMessage,
237
- stack: rest
238
- };
239
- };
240
- class IpcError extends VError {
241
- // @ts-ignore
242
- constructor(betterMessage, stdout = '', stderr = '') {
243
- if (stdout || stderr) {
244
- // @ts-ignore
245
- const {
246
- code,
247
- message,
248
- stack
249
- } = getHelpfulChildProcessError(stdout, stderr);
250
- const cause = new Error(message);
251
- // @ts-ignore
252
- cause.code = code;
253
- cause.stack = stack;
254
- super(cause, betterMessage);
255
- } else {
256
- super(betterMessage);
257
- }
258
- // @ts-ignore
259
- this.name = 'IpcError';
260
- // @ts-ignore
261
- this.stdout = stdout;
262
- // @ts-ignore
263
- this.stderr = stderr;
264
- }
265
- }
266
71
  const readyMessage = 'ready';
267
72
  const getData$2 = event => {
268
73
  return event.data;
@@ -342,70 +147,11 @@ class IpcChildWithModuleWorker extends Ipc {
342
147
  const wrap$f = global => {
343
148
  return new IpcChildWithModuleWorker(global);
344
149
  };
345
- const waitForFirstMessage = async port => {
346
- const {
347
- promise,
348
- resolve
349
- } = Promise.withResolvers();
350
- port.addEventListener('message', resolve, {
351
- once: true
352
- });
353
- const event = await promise;
354
- // @ts-ignore
355
- return event.data;
356
- };
357
- const listen$6 = async () => {
358
- const parentIpcRaw = listen$7();
359
- signal$8(parentIpcRaw);
360
- const parentIpc = wrap$f(parentIpcRaw);
361
- const firstMessage = await waitForFirstMessage(parentIpc);
362
- if (firstMessage.method !== 'initialize') {
363
- throw new IpcError('unexpected first message');
364
- }
365
- const type = firstMessage.params[0];
366
- if (type === 'message-port') {
367
- parentIpc.send({
368
- id: firstMessage.id,
369
- jsonrpc: '2.0',
370
- result: null
371
- });
372
- parentIpc.dispose();
373
- const port = firstMessage.params[1];
374
- return port;
375
- }
376
- return globalThis;
377
- };
378
- class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
379
- getData(event) {
380
- return getData$2(event);
381
- }
382
- send(message) {
383
- this._rawIpc.postMessage(message);
384
- }
385
- sendAndTransfer(message) {
386
- const transfer = getTransferrables(message);
387
- this._rawIpc.postMessage(message, transfer);
388
- }
389
- dispose() {
390
- if (this._rawIpc.close) {
391
- this._rawIpc.close();
392
- }
393
- }
394
- onClose(callback) {
395
- // ignore
396
- }
397
- onMessage(callback) {
398
- this._rawIpc.addEventListener('message', callback);
399
- this._rawIpc.start();
400
- }
401
- }
402
- const wrap$e = port => {
403
- return new IpcChildWithModuleWorkerAndMessagePort(port);
404
- };
405
- const IpcChildWithModuleWorkerAndMessagePort$1 = {
150
+ const IpcChildWithModuleWorker$1 = {
406
151
  __proto__: null,
407
- listen: listen$6,
408
- wrap: wrap$e
152
+ listen: listen$7,
153
+ signal: signal$8,
154
+ wrap: wrap$f
409
155
  };
410
156
 
411
157
  class CommandNotFoundError extends Error {
@@ -882,53 +628,267 @@ const create = async ({
882
628
  }) => {
883
629
  // TODO create a commandMap per rpc instance
884
630
  register(commandMap);
885
- const ipc = await listen$1(IpcChildWithModuleWorkerAndMessagePort$1);
631
+ const ipc = await listen$1(IpcChildWithModuleWorker$1);
886
632
  handleIpc(ipc);
887
633
  const rpc = createRpc(ipc);
888
634
  return rpc;
889
635
  };
890
636
 
891
- const toError = error => {
892
- if (error instanceof Error) {
893
- return error;
894
- }
895
- return new Error('IndexedDB request failed');
896
- };
897
-
898
- const requestToPromise = async createRequest => {
899
- const request = createRequest();
900
- const {
901
- promise,
902
- reject,
903
- resolve
904
- } = Promise.withResolvers();
905
- request.addEventListener('success', () => {
906
- resolve(request.result);
907
- });
908
- request.addEventListener('error', () => {
909
- reject(toError(request.error));
637
+ const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
638
+ let idbProxyableTypes;
639
+ let cursorAdvanceMethods;
640
+ // This is a function to prevent it throwing up in node environments.
641
+ function getIdbProxyableTypes() {
642
+ return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
643
+ }
644
+ // This is a function to prevent it throwing up in node environments.
645
+ function getCursorAdvanceMethods() {
646
+ return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
647
+ }
648
+ const transactionDoneMap = new WeakMap();
649
+ const transformCache = new WeakMap();
650
+ const reverseTransformCache = new WeakMap();
651
+ function promisifyRequest(request) {
652
+ const promise = new Promise((resolve, reject) => {
653
+ const unlisten = () => {
654
+ request.removeEventListener('success', success);
655
+ request.removeEventListener('error', error);
656
+ };
657
+ const success = () => {
658
+ resolve(wrap(request.result));
659
+ unlisten();
660
+ };
661
+ const error = () => {
662
+ reject(request.error);
663
+ unlisten();
664
+ };
665
+ request.addEventListener('success', success);
666
+ request.addEventListener('error', error);
910
667
  });
668
+ // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
669
+ // is because we create many promises from a single IDBRequest.
670
+ reverseTransformCache.set(promise, request);
911
671
  return promise;
912
- };
913
-
914
- const transactionToPromise = async createTransaction => {
915
- const transaction = createTransaction();
916
- const {
917
- promise,
918
- reject,
919
- resolve
920
- } = Promise.withResolvers();
921
- transaction.addEventListener('complete', () => {
922
- resolve();
923
- });
924
- transaction.addEventListener('error', () => {
925
- reject(toError(transaction.error));
926
- });
927
- transaction.addEventListener('abort', () => {
928
- reject(toError(transaction.error));
672
+ }
673
+ function cacheDonePromiseForTransaction(tx) {
674
+ // Early bail if we've already created a done promise for this transaction.
675
+ if (transactionDoneMap.has(tx)) return;
676
+ const done = new Promise((resolve, reject) => {
677
+ const unlisten = () => {
678
+ tx.removeEventListener('complete', complete);
679
+ tx.removeEventListener('error', error);
680
+ tx.removeEventListener('abort', error);
681
+ };
682
+ const complete = () => {
683
+ resolve();
684
+ unlisten();
685
+ };
686
+ const error = () => {
687
+ reject(tx.error || new DOMException('AbortError', 'AbortError'));
688
+ unlisten();
689
+ };
690
+ tx.addEventListener('complete', complete);
691
+ tx.addEventListener('error', error);
692
+ tx.addEventListener('abort', error);
929
693
  });
930
- return promise;
694
+ // Cache it for later retrieval.
695
+ transactionDoneMap.set(tx, done);
696
+ }
697
+ let idbProxyTraps = {
698
+ get(target, prop, receiver) {
699
+ if (target instanceof IDBTransaction) {
700
+ // Special handling for transaction.done.
701
+ if (prop === 'done') return transactionDoneMap.get(target);
702
+ // Make tx.store return the only store in the transaction, or undefined if there are many.
703
+ if (prop === 'store') {
704
+ return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
705
+ }
706
+ }
707
+ // Else transform whatever we get back.
708
+ return wrap(target[prop]);
709
+ },
710
+ set(target, prop, value) {
711
+ target[prop] = value;
712
+ return true;
713
+ },
714
+ has(target, prop) {
715
+ if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
716
+ return true;
717
+ }
718
+ return prop in target;
719
+ }
931
720
  };
721
+ function replaceTraps(callback) {
722
+ idbProxyTraps = callback(idbProxyTraps);
723
+ }
724
+ function wrapFunction(func) {
725
+ // Due to expected object equality (which is enforced by the caching in `wrap`), we
726
+ // only create one new func per func.
727
+ // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
728
+ // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
729
+ // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
730
+ // with real promises, so each advance methods returns a new promise for the cursor object, or
731
+ // undefined if the end of the cursor has been reached.
732
+ if (getCursorAdvanceMethods().includes(func)) {
733
+ return function (...args) {
734
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
735
+ // the original object.
736
+ func.apply(unwrap(this), args);
737
+ return wrap(this.request);
738
+ };
739
+ }
740
+ return function (...args) {
741
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
742
+ // the original object.
743
+ return wrap(func.apply(unwrap(this), args));
744
+ };
745
+ }
746
+ function transformCachableValue(value) {
747
+ if (typeof value === 'function') return wrapFunction(value);
748
+ // This doesn't return, it just creates a 'done' promise for the transaction,
749
+ // which is later returned for transaction.done (see idbObjectHandler).
750
+ if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
751
+ if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
752
+ // Return the same value back if we're not going to transform it.
753
+ return value;
754
+ }
755
+ function wrap(value) {
756
+ // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
757
+ // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
758
+ if (value instanceof IDBRequest) return promisifyRequest(value);
759
+ // If we've already transformed this value before, reuse the transformed value.
760
+ // This is faster, but it also provides object equality.
761
+ if (transformCache.has(value)) return transformCache.get(value);
762
+ const newValue = transformCachableValue(value);
763
+ // Not all types are transformed.
764
+ // These may be primitive types, so they can't be WeakMap keys.
765
+ if (newValue !== value) {
766
+ transformCache.set(value, newValue);
767
+ reverseTransformCache.set(newValue, value);
768
+ }
769
+ return newValue;
770
+ }
771
+ const unwrap = value => reverseTransformCache.get(value);
772
+
773
+ /**
774
+ * Open a database.
775
+ *
776
+ * @param name Name of the database.
777
+ * @param version Schema version.
778
+ * @param callbacks Additional callbacks.
779
+ */
780
+ function openDB(name, version, {
781
+ blocked,
782
+ upgrade,
783
+ blocking,
784
+ terminated
785
+ } = {}) {
786
+ const request = indexedDB.open(name, version);
787
+ const openPromise = wrap(request);
788
+ if (upgrade) {
789
+ request.addEventListener('upgradeneeded', event => {
790
+ upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
791
+ });
792
+ }
793
+ if (blocked) {
794
+ request.addEventListener('blocked', event => blocked(
795
+ // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
796
+ event.oldVersion, event.newVersion, event));
797
+ }
798
+ openPromise.then(db => {
799
+ if (terminated) db.addEventListener('close', () => terminated());
800
+ if (blocking) {
801
+ db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
802
+ }
803
+ }).catch(() => {});
804
+ return openPromise;
805
+ }
806
+ const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
807
+ const writeMethods = ['put', 'add', 'delete', 'clear'];
808
+ const cachedMethods = new Map();
809
+ function getMethod(target, prop) {
810
+ if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
811
+ return;
812
+ }
813
+ if (cachedMethods.get(prop)) return cachedMethods.get(prop);
814
+ const targetFuncName = prop.replace(/FromIndex$/, '');
815
+ const useIndex = prop !== targetFuncName;
816
+ const isWrite = writeMethods.includes(targetFuncName);
817
+ if (
818
+ // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
819
+ !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
820
+ return;
821
+ }
822
+ const method = async function (storeName, ...args) {
823
+ // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
824
+ const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
825
+ let target = tx.store;
826
+ if (useIndex) target = target.index(args.shift());
827
+ // Must reject if op rejects.
828
+ // If it's a write operation, must reject if tx.done rejects.
829
+ // Must reject with op rejection first.
830
+ // Must resolve with op value.
831
+ // Must handle both promises (no unhandled rejections)
832
+ return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
833
+ };
834
+ cachedMethods.set(prop, method);
835
+ return method;
836
+ }
837
+ replaceTraps(oldTraps => ({
838
+ ...oldTraps,
839
+ get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
840
+ has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
841
+ }));
842
+ const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
843
+ const methodMap = {};
844
+ const advanceResults = new WeakMap();
845
+ const ittrProxiedCursorToOriginalProxy = new WeakMap();
846
+ const cursorIteratorTraps = {
847
+ get(target, prop) {
848
+ if (!advanceMethodProps.includes(prop)) return target[prop];
849
+ let cachedFunc = methodMap[prop];
850
+ if (!cachedFunc) {
851
+ cachedFunc = methodMap[prop] = function (...args) {
852
+ advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
853
+ };
854
+ }
855
+ return cachedFunc;
856
+ }
857
+ };
858
+ async function* iterate(...args) {
859
+ // tslint:disable-next-line:no-this-assignment
860
+ let cursor = this;
861
+ if (!(cursor instanceof IDBCursor)) {
862
+ cursor = await cursor.openCursor(...args);
863
+ }
864
+ if (!cursor) return;
865
+ cursor = cursor;
866
+ const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
867
+ ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
868
+ // Map this double-proxy back to the original, so other cursor methods work.
869
+ reverseTransformCache.set(proxiedCursor, unwrap(cursor));
870
+ while (cursor) {
871
+ yield proxiedCursor;
872
+ // If one of the advancing methods was not called, call continue().
873
+ cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
874
+ advanceResults.delete(proxiedCursor);
875
+ }
876
+ }
877
+ function isIteratorProp(target, prop) {
878
+ return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
879
+ }
880
+ replaceTraps(oldTraps => ({
881
+ ...oldTraps,
882
+ get(target, prop, receiver) {
883
+ if (isIteratorProp(target, prop)) return iterate;
884
+ return oldTraps.get(target, prop, receiver);
885
+ },
886
+ has(target, prop) {
887
+ return isIteratorProp(target, prop) || oldTraps.has(target, prop);
888
+ }
889
+ }));
890
+
891
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
932
892
 
933
893
  const toChatViewEvent = event => {
934
894
  const {
@@ -1105,68 +1065,52 @@ class IndexedDbChatSessionStorage {
1105
1065
  if (this.state.databasePromise) {
1106
1066
  return this.state.databasePromise;
1107
1067
  }
1108
- const request = indexedDB.open(this.state.databaseName, this.state.databaseVersion);
1109
- request.addEventListener('upgradeneeded', () => {
1110
- const database = request.result;
1111
- if (!database.objectStoreNames.contains(this.state.storeName)) {
1112
- database.createObjectStore(this.state.storeName, {
1113
- keyPath: 'id'
1114
- });
1115
- }
1116
- if (database.objectStoreNames.contains(this.state.eventStoreName)) {
1117
- const {
1118
- transaction
1119
- } = request;
1120
- if (!transaction) {
1121
- return;
1068
+ const databasePromise = openDB(this.state.databaseName, this.state.databaseVersion, {
1069
+ upgrade: (database, _oldVersion, _newVersion, transaction) => {
1070
+ if (!database.objectStoreNames.contains(this.state.storeName)) {
1071
+ database.createObjectStore(this.state.storeName, {
1072
+ keyPath: 'id'
1073
+ });
1122
1074
  }
1123
- const eventStore = transaction.objectStore(this.state.eventStoreName);
1124
- if (!eventStore.indexNames.contains('sessionId')) {
1075
+ if (database.objectStoreNames.contains(this.state.eventStoreName)) {
1076
+ const eventStore = transaction.objectStore(this.state.eventStoreName);
1077
+ if (!eventStore.indexNames.contains('sessionId')) {
1078
+ eventStore.createIndex('sessionId', 'sessionId', {
1079
+ unique: false
1080
+ });
1081
+ }
1082
+ } else {
1083
+ const eventStore = database.createObjectStore(this.state.eventStoreName, {
1084
+ autoIncrement: true,
1085
+ keyPath: 'eventId'
1086
+ });
1125
1087
  eventStore.createIndex('sessionId', 'sessionId', {
1126
1088
  unique: false
1127
1089
  });
1128
1090
  }
1129
- } else {
1130
- const eventStore = database.createObjectStore(this.state.eventStoreName, {
1131
- autoIncrement: true,
1132
- keyPath: 'eventId'
1133
- });
1134
- eventStore.createIndex('sessionId', 'sessionId', {
1135
- unique: false
1136
- });
1137
1091
  }
1138
1092
  });
1139
- const databasePromise = requestToPromise(() => request);
1140
1093
  this.state.databasePromise = databasePromise;
1141
1094
  return databasePromise;
1142
1095
  };
1143
1096
  listSummaries = async () => {
1144
1097
  const database = await this.openDatabase();
1145
- const transaction = database.transaction(this.state.storeName, 'readonly');
1146
- const store = transaction.objectStore(this.state.storeName);
1147
- const summaries = await requestToPromise(() => store.getAll());
1098
+ const summaries = await database.getAll(this.state.storeName);
1148
1099
  return summaries;
1149
1100
  };
1150
1101
  getSummary = async id => {
1151
1102
  const database = await this.openDatabase();
1152
- const transaction = database.transaction(this.state.storeName, 'readonly');
1153
- const store = transaction.objectStore(this.state.storeName);
1154
- const summary = await requestToPromise(() => store.get(id));
1103
+ const summary = await database.get(this.state.storeName, id);
1155
1104
  return summary;
1156
1105
  };
1157
1106
  getEventsBySessionId = async sessionId => {
1158
1107
  const database = await this.openDatabase();
1159
- const transaction = database.transaction(this.state.eventStoreName, 'readonly');
1160
- const store = transaction.objectStore(this.state.eventStoreName);
1161
- const index = store.index('sessionId');
1162
- const events = await requestToPromise(() => index.getAll(IDBKeyRange.only(sessionId)));
1108
+ const events = await database.getAllFromIndex(this.state.eventStoreName, 'sessionId', IDBKeyRange.only(sessionId));
1163
1109
  return events.map(toChatViewEvent);
1164
1110
  };
1165
1111
  listEventsInternal = async () => {
1166
1112
  const database = await this.openDatabase();
1167
- const transaction = database.transaction(this.state.eventStoreName, 'readonly');
1168
- const store = transaction.objectStore(this.state.eventStoreName);
1169
- const events = await requestToPromise(() => store.getAll());
1113
+ const events = await database.getAll(this.state.eventStoreName);
1170
1114
  return events.map(toChatViewEvent);
1171
1115
  };
1172
1116
  appendEvents = async events => {
@@ -1178,18 +1122,18 @@ class IndexedDbChatSessionStorage {
1178
1122
  const summaryStore = transaction.objectStore(this.state.storeName);
1179
1123
  const eventStore = transaction.objectStore(this.state.eventStoreName);
1180
1124
  for (const event of events) {
1181
- eventStore.add(event);
1125
+ await eventStore.add(event);
1182
1126
  if (event.type === 'chat-session-created' || event.type === 'chat-session-title-updated') {
1183
- summaryStore.put({
1127
+ await summaryStore.put({
1184
1128
  id: event.sessionId,
1185
1129
  title: event.title
1186
1130
  });
1187
1131
  }
1188
1132
  if (event.type === 'chat-session-deleted') {
1189
- summaryStore.delete(event.sessionId);
1133
+ await summaryStore.delete(event.sessionId);
1190
1134
  }
1191
1135
  }
1192
- await transactionToPromise(() => transaction);
1136
+ await transaction.done;
1193
1137
  };
1194
1138
  async appendEvent(event) {
1195
1139
  await this.appendEvents([event]);
@@ -1197,9 +1141,8 @@ class IndexedDbChatSessionStorage {
1197
1141
  async clear() {
1198
1142
  const database = await this.openDatabase();
1199
1143
  const transaction = database.transaction([this.state.storeName, this.state.eventStoreName], 'readwrite');
1200
- transaction.objectStore(this.state.storeName).clear();
1201
- transaction.objectStore(this.state.eventStoreName).clear();
1202
- await transactionToPromise(() => transaction);
1144
+ await Promise.all([transaction.objectStore(this.state.storeName).clear(), transaction.objectStore(this.state.eventStoreName).clear()]);
1145
+ await transaction.done;
1203
1146
  }
1204
1147
  async deleteSession(id) {
1205
1148
  await this.appendEvent({
@@ -1239,11 +1182,11 @@ class IndexedDbChatSessionStorage {
1239
1182
  const database = await this.openDatabase();
1240
1183
  const transaction = database.transaction(this.state.storeName, 'readwrite');
1241
1184
  const summaryStore = transaction.objectStore(this.state.storeName);
1242
- summaryStore.put({
1185
+ await summaryStore.put({
1243
1186
  id: session.id,
1244
1187
  title: session.title
1245
1188
  });
1246
- await transactionToPromise(() => transaction);
1189
+ await transaction.done;
1247
1190
  }
1248
1191
  }
1249
1192
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-storage-worker",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Chat Storage Worker",
5
5
  "repository": {
6
6
  "type": "git",