Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/src/lib/libidbstore.js
4150 views
1
/**
2
* @license
3
* Copyright 2015 The Emscripten Authors
4
* SPDX-License-Identifier: MIT
5
*/
6
7
#include "IDBStore.js"
8
9
var LibraryIDBStore = {
10
// A simple IDB-backed storage mechanism. Suitable for saving and loading
11
// large files asynchronously. This does *NOT* use the emscripten filesystem,
12
// intentionally, to avoid overhead. It lets you application define whatever
13
// filesystem-like layer you want, with the overhead 100% controlled by you.
14
// At the extremes, you could either just store large files, with almost no
15
// extra code; or you could implement a file b-tree using posix-compliant
16
// filesystem on top.
17
$IDBStore: IDBStore,
18
emscripten_idb_async_load__deps: ['$UTF8ToString', '$callUserCallback', 'malloc', 'free'],
19
emscripten_idb_async_load: (db, id, arg, onload, onerror) => {
20
{{{ runtimeKeepalivePush() }}};
21
IDBStore.getFile(UTF8ToString(db), UTF8ToString(id), (error, byteArray) => {
22
{{{ runtimeKeepalivePop() }}}
23
callUserCallback(() => {
24
if (error) {
25
if (onerror) {{{ makeDynCall('vp', 'onerror') }}}(arg);
26
return;
27
}
28
var buffer = _malloc(byteArray.length);
29
HEAPU8.set(byteArray, buffer);
30
{{{ makeDynCall('vppi', 'onload') }}}(arg, buffer, byteArray.length);
31
_free(buffer);
32
});
33
});
34
},
35
emscripten_idb_async_store__deps: ['$UTF8ToString', '$callUserCallback'],
36
emscripten_idb_async_store: (db, id, ptr, num, arg, onstore, onerror) => {
37
// note that we copy the data here, as these are async operatins - changes
38
// to HEAPU8 meanwhile should not affect us!
39
{{{ runtimeKeepalivePush() }}};
40
IDBStore.setFile(UTF8ToString(db), UTF8ToString(id), new Uint8Array(HEAPU8.subarray(ptr, ptr+num)), (error) => {
41
{{{ runtimeKeepalivePop() }}}
42
callUserCallback(() => {
43
if (error) {
44
if (onerror) {{{ makeDynCall('vp', 'onerror') }}}(arg);
45
return;
46
}
47
if (onstore) {{{ makeDynCall('vp', 'onstore') }}}(arg);
48
});
49
});
50
},
51
emscripten_idb_async_delete__deps: ['$UTF8ToString', '$callUserCallback'],
52
emscripten_idb_async_delete: (db, id, arg, ondelete, onerror) => {
53
{{{ runtimeKeepalivePush() }}};
54
IDBStore.deleteFile(UTF8ToString(db), UTF8ToString(id), (error) => {
55
{{{ runtimeKeepalivePop() }}}
56
callUserCallback(() => {
57
if (error) {
58
if (onerror) {{{ makeDynCall('vp', 'onerror') }}}(arg);
59
return;
60
}
61
if (ondelete) {{{ makeDynCall('vp', 'ondelete') }}}(arg);
62
});
63
});
64
},
65
emscripten_idb_async_exists__deps: ['$UTF8ToString', '$callUserCallback'],
66
emscripten_idb_async_exists: (db, id, arg, oncheck, onerror) => {
67
{{{ runtimeKeepalivePush() }}};
68
IDBStore.existsFile(UTF8ToString(db), UTF8ToString(id), (error, exists) => {
69
{{{ runtimeKeepalivePop() }}}
70
callUserCallback(() => {
71
if (error) {
72
if (onerror) {{{ makeDynCall('vp', 'onerror') }}}(arg);
73
return;
74
}
75
if (oncheck) {{{ makeDynCall('vpi', 'oncheck') }}}(arg, exists);
76
});
77
});
78
},
79
emscripten_idb_async_clear__deps: ['$UTF8ToString', '$callUserCallback'],
80
emscripten_idb_async_clear: (db, arg, onclear, onerror) => {
81
{{{ runtimeKeepalivePush() }}};
82
IDBStore.clearStore(UTF8ToString(db), (error) => {
83
{{{ runtimeKeepalivePop() }}}
84
callUserCallback(() => {
85
if (error) {
86
if (onerror) {{{ makeDynCall('vp', 'onerror') }}}(arg);
87
return;
88
}
89
if (onclear) {{{ makeDynCall('vp', 'onclear') }}}(arg);
90
});
91
});
92
},
93
94
#if ASYNCIFY
95
emscripten_idb_load__async: true,
96
emscripten_idb_load__deps: ['malloc'],
97
emscripten_idb_load: (db, id, pbuffer, pnum, perror) => Asyncify.handleSleep((wakeUp) => {
98
IDBStore.getFile(UTF8ToString(db), UTF8ToString(id), (error, byteArray) => {
99
if (error) {
100
{{{ makeSetValue('perror', 0, '1', 'i32') }}};
101
wakeUp();
102
return;
103
}
104
var buffer = _malloc(byteArray.length); // must be freed by the caller!
105
HEAPU8.set(byteArray, buffer);
106
{{{ makeSetValue('pbuffer', 0, 'buffer', '*') }}};
107
{{{ makeSetValue('pnum', 0, 'byteArray.length', 'i32') }}};
108
{{{ makeSetValue('perror', 0, '0', 'i32') }}};
109
wakeUp();
110
});
111
}),
112
emscripten_idb_store__async: true,
113
emscripten_idb_store: (db, id, ptr, num, perror) => Asyncify.handleSleep((wakeUp) => {
114
IDBStore.setFile(UTF8ToString(db), UTF8ToString(id), new Uint8Array(HEAPU8.subarray(ptr, ptr+num)), (error) => {
115
// Closure warns about storing booleans in TypedArrays.
116
/** @suppress{checkTypes} */
117
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
118
wakeUp();
119
});
120
}),
121
emscripten_idb_delete__async: true,
122
emscripten_idb_delete: (db, id, perror) => Asyncify.handleSleep((wakeUp) => {
123
IDBStore.deleteFile(UTF8ToString(db), UTF8ToString(id), (error) => {
124
/** @suppress{checkTypes} */
125
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
126
wakeUp();
127
});
128
}),
129
emscripten_idb_exists__async: true,
130
emscripten_idb_exists: (db, id, pexists, perror) => Asyncify.handleSleep((wakeUp) => {
131
IDBStore.existsFile(UTF8ToString(db), UTF8ToString(id), (error, exists) => {
132
/** @suppress{checkTypes} */
133
{{{ makeSetValue('pexists', 0, '!!exists', 'i32') }}};
134
/** @suppress{checkTypes} */
135
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
136
wakeUp();
137
});
138
}),
139
emscripten_idb_clear__async: true,
140
emscripten_idb_clear: (db, perror) => Asyncify.handleSleep((wakeUp) => {
141
IDBStore.clearStore(UTF8ToString(db), (error) => {
142
/** @suppress{checkTypes} */
143
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
144
wakeUp();
145
});
146
}),
147
// extra worker methods - proxied
148
emscripten_idb_load_blob__async: true,
149
emscripten_idb_load_blob: (db, id, pblob, perror) => Asyncify.handleSleep((wakeUp) => {
150
#if ASSERTIONS
151
assert(!IDBStore.pending);
152
#endif
153
IDBStore.pending = (msg) => {
154
IDBStore.pending = null;
155
var blob = msg.blob;
156
if (!blob) {
157
{{{ makeSetValue('perror', 0, '1', 'i32') }}};
158
wakeUp();
159
return;
160
}
161
#if ASSERTIONS
162
assert(blob instanceof Blob);
163
#endif
164
var blobId = IDBStore.blobs.length;
165
IDBStore.blobs.push(blob);
166
{{{ makeSetValue('pblob', 0, 'blobId', 'i32') }}};
167
wakeUp();
168
};
169
postMessage({
170
target: 'IDBStore',
171
method: 'loadBlob',
172
db: UTF8ToString(db),
173
id: UTF8ToString(id)
174
});
175
}),
176
emscripten_idb_store_blob__async: true,
177
emscripten_idb_store_blob: (db, id, ptr, num, perror) => Asyncify.handleSleep((wakeUp) => {
178
#if ASSERTIONS
179
assert(!IDBStore.pending);
180
#endif
181
IDBStore.pending = (msg) => {
182
IDBStore.pending = null;
183
{{{ makeSetValue('perror', 0, '!!msg.error', 'i32') }}};
184
wakeUp();
185
};
186
postMessage({
187
target: 'IDBStore',
188
method: 'storeBlob',
189
db: UTF8ToString(db),
190
id: UTF8ToString(id),
191
blob: new Blob([new Uint8Array(HEAPU8.subarray(ptr, ptr+num))])
192
});
193
}),
194
emscripten_idb_read_from_blob: (blobId, start, num, buffer) => {
195
var blob = IDBStore.blobs[blobId];
196
if (!blob) return 1;
197
if (start+num > blob.size) return 2;
198
var byteArray = (new FileReaderSync()).readAsArrayBuffer(blob.slice(start, start+num));
199
HEAPU8.set(new Uint8Array(byteArray), buffer);
200
return 0;
201
},
202
emscripten_idb_free_blob: (blobId) => {
203
#if ASSERTIONS
204
assert(IDBStore.blobs[blobId]);
205
#endif
206
IDBStore.blobs[blobId] = null;
207
},
208
#else
209
emscripten_idb_load: (db, id, pbuffer, pnum, perror) => {
210
throw 'Please compile your program with async support in order to use synchronous operations like emscripten_idb_load, etc.';
211
},
212
emscripten_idb_store: (db, id, ptr, num, perror) => {
213
throw 'Please compile your program with async support in order to use synchronous operations like emscripten_idb_store, etc.';
214
},
215
emscripten_idb_delete: (db, id, perror) => {
216
throw 'Please compile your program with async support in order to use synchronous operations like emscripten_idb_delete, etc.';
217
},
218
emscripten_idb_exists: (db, id, pexists, perror) => {
219
throw 'Please compile your program with async support in order to use synchronous operations like emscripten_idb_exists, etc.';
220
},
221
emscripten_idb_clear: (db, perror) => {
222
throw 'Please compile your program with async support in order to use synchronous operations like emscripten_idb_clear, etc.';
223
},
224
#endif // ASYNCIFY
225
};
226
227
autoAddDeps(LibraryIDBStore, '$IDBStore');
228
addToLibrary(LibraryIDBStore);
229
230