js-dos 8.1.5 → 8.1.7
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/dist/emulators/emulators.js +2 -0
- package/dist/emulators/emulators.js.map +1 -0
- package/dist/emulators/types/build.d.ts +28 -0
- package/dist/emulators/types/dos/bundle/dos-bundle.d.ts +20 -0
- package/dist/emulators/types/dos/dosbox/ts/direct.d.ts +3 -0
- package/dist/emulators/types/dos/dosbox/ts/worker.d.ts +3 -0
- package/dist/emulators/types/emulators.d.ts +76 -0
- package/dist/emulators/types/http.d.ts +9 -0
- package/dist/emulators/types/impl/ci-impl.d.ts +29 -0
- package/dist/emulators/types/impl/emulators-impl.d.ts +26 -0
- package/dist/emulators/types/impl/modules.d.ts +38 -0
- package/dist/emulators/types/libzip/libzip.d.ts +16 -0
- package/dist/emulators/types/protocol/messages-queue.d.ts +8 -0
- package/dist/emulators/types/protocol/protocol.d.ts +128 -0
- package/dist/emulators/wdosbox-x.js +55 -0
- package/dist/emulators/wdosbox-x.js.symbols +8760 -0
- package/dist/emulators/wdosbox-x.wasm +0 -0
- package/dist/emulators/wdosbox.js +55 -0
- package/dist/emulators/wdosbox.js.symbols +3001 -0
- package/dist/emulators/wdosbox.wasm +0 -0
- package/dist/emulators/wlibzip.js +21 -0
- package/dist/emulators/wlibzip.js.symbols +268 -0
- package/dist/emulators/wlibzip.wasm +0 -0
- package/dist/js-dos.css +1 -0
- package/dist/js-dos.js +22 -0
- package/dist/js-dos.js.map +1 -0
- package/package.json +1 -1
- package/release.zip +0 -0
- package/.eslintrc.json +0 -43
- package/.github/workflows/build.yml +0 -51
- package/.gitmodules +0 -4
- package/index.html +0 -110
- package/postcss.config.cjs +0 -8
- package/src/app.css +0 -14
- package/src/base.css +0 -10
- package/src/components/checkbox.tsx +0 -41
- package/src/components/close-button.tsx +0 -17
- package/src/components/components.css +0 -28
- package/src/components/dos-option-checkbox.tsx +0 -94
- package/src/components/dos-option-select.tsx +0 -108
- package/src/components/dos-option-slider.tsx +0 -35
- package/src/components/error.tsx +0 -16
- package/src/components/loading.tsx +0 -26
- package/src/components/lock.tsx +0 -10
- package/src/components/select.tsx +0 -33
- package/src/components/slider.tsx +0 -69
- package/src/download-file.ts +0 -18
- package/src/frame/account-frame.tsx +0 -156
- package/src/frame/editor/defaults.ts +0 -419
- package/src/frame/editor/editor-conf-frame.tsx +0 -227
- package/src/frame/editor/editor-frame.css +0 -55
- package/src/frame/editor/editor-fs-frame.tsx +0 -314
- package/src/frame/fat-drives-frame.tsx +0 -199
- package/src/frame/frame.css +0 -119
- package/src/frame/frame.tsx +0 -34
- package/src/frame/image-rendering-frame.tsx +0 -8
- package/src/frame/network-frame.tsx +0 -157
- package/src/frame/quick-save-frame.tsx +0 -98
- package/src/frame/settings-frame.tsx +0 -14
- package/src/frame/stats-frame.tsx +0 -87
- package/src/host/bundle-storage.ts +0 -91
- package/src/host/fullscreen.ts +0 -35
- package/src/host/lcache.ts +0 -203
- package/src/host/lstorage.ts +0 -156
- package/src/i18n.ts +0 -185
- package/src/index.css +0 -7
- package/src/load.ts +0 -132
- package/src/login/login.css +0 -9
- package/src/login/login.tsx +0 -77
- package/src/main.tsx +0 -197
- package/src/public/types.ts +0 -45
- package/src/sidebar/account-button.tsx +0 -33
- package/src/sidebar/cloud-save-button.tsx +0 -89
- package/src/sidebar/diskette-icon.tsx +0 -14
- package/src/sidebar/fullscreen-button.tsx +0 -44
- package/src/sidebar/network-button.tsx +0 -39
- package/src/sidebar/sidebar-button.tsx +0 -244
- package/src/sidebar/sidebar.css +0 -47
- package/src/sidebar/sidebar.tsx +0 -30
- package/src/sockdrive/LICENSE +0 -674
- package/src/sockdrive/README.md +0 -45
- package/src/sockdrive/include/sockdrive.h +0 -23
- package/src/sockdrive/js/.eslintrc.json +0 -43
- package/src/sockdrive/js/package.json +0 -29
- package/src/sockdrive/js/src/fatfs/chains.js +0 -318
- package/src/sockdrive/js/src/fatfs/dir.js +0 -385
- package/src/sockdrive/js/src/fatfs/helpers.js +0 -210
- package/src/sockdrive/js/src/fatfs/index.js +0 -606
- package/src/sockdrive/js/src/fatfs/structs.js +0 -255
- package/src/sockdrive/js/src/fatfs/vol.js +0 -166
- package/src/sockdrive/js/src/sockdrive/cache.ts +0 -56
- package/src/sockdrive/js/src/sockdrive/drive.ts +0 -471
- package/src/sockdrive/js/src/sockdrive/lru.ts +0 -221
- package/src/sockdrive/js/src/sockdrive/types.ts +0 -14
- package/src/sockdrive/js/src/sockdrive-fat.d.ts +0 -64
- package/src/sockdrive/js/src/sockdrive-fat.ts +0 -226
- package/src/sockdrive/js/src/sockdrive-native.ts +0 -100
- package/src/sockdrive/js/src/test/test.ts +0 -289
- package/src/sockdrive/js/tsconfig.json +0 -11
- package/src/sockdrive/js/webpack.config.js +0 -68
- package/src/sockdrive/js/yarn.lock +0 -1808
- package/src/store/auth.ts +0 -115
- package/src/store/dos.ts +0 -305
- package/src/store/editor.ts +0 -61
- package/src/store/init.ts +0 -48
- package/src/store/storage.ts +0 -32
- package/src/store/ui.ts +0 -191
- package/src/store.tsx +0 -116
- package/src/ui.tsx +0 -140
- package/src/v8/changes.ts +0 -56
- package/src/v8/config.ts +0 -20
- package/src/v8/subscriptions.ts +0 -62
- package/src/vite-env.d.ts +0 -5
- package/src/window/dos/controls/keyboard.ts +0 -32
- package/src/window/dos/controls/keys.ts +0 -331
- package/src/window/dos/controls/mouse/mount.ts +0 -99
- package/src/window/dos/controls/mouse/mouse-locked.ts +0 -51
- package/src/window/dos/controls/mouse/mouse-not-locked.ts +0 -84
- package/src/window/dos/controls/mouse/mouse-swipe.ts +0 -57
- package/src/window/dos/controls/mouse/pointer.ts +0 -85
- package/src/window/dos/controls/mouse.ts +0 -21
- package/src/window/dos/dos-dhry2.tsx +0 -191
- package/src/window/dos/dos-runtime.tsx +0 -216
- package/src/window/dos/dos-window.tsx +0 -91
- package/src/window/dos/render/canvas.ts +0 -65
- package/src/window/dos/render/resize.ts +0 -31
- package/src/window/dos/render/webgl.ts +0 -173
- package/src/window/dos/sound/audio-node.ts +0 -148
- package/src/window/error-window.tsx +0 -9
- package/src/window/loading-window.tsx +0 -54
- package/src/window/prerun-window.tsx +0 -121
- package/src/window/select-window.tsx +0 -118
- package/src/window/window.css +0 -78
- package/src/window/window.tsx +0 -49
- package/src/ws/ws-sockdrive.ts +0 -123
- package/src/ws/ws-transport-layer.ts +0 -468
- package/tailwind.config.cjs +0 -48
- package/tsconfig.json +0 -32
- package/tsconfig.node.json +0 -9
- package/vite.config.ts +0 -25
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { useSelector } from "react-redux";
|
|
2
|
-
import { State } from "../store";
|
|
3
|
-
|
|
4
|
-
export function StatsFrame() {
|
|
5
|
-
const startedAt = useSelector((state: State) => state.dos.ciStartedAt);
|
|
6
|
-
const stats = useSelector((state: State) => state.dos.stats);
|
|
7
|
-
const cycles = Math.round(useSelector((state: State) => state.dos.stats.cyclesPerMs) / 1000);
|
|
8
|
-
const driveRecvMb = Math.round(stats.driveRecv / 1024 / 1024 * 100) / 100;
|
|
9
|
-
const driveSpeedMb = (stats.driveRecvTime / 1000) > 1 ?
|
|
10
|
-
Math.round(driveRecvMb / stats.driveRecvTime * 1000 * 100) / 100 : 0;
|
|
11
|
-
return <div class="stats-frame frame-root items-start px-4">
|
|
12
|
-
<div class="w-full overflow-x-auto">
|
|
13
|
-
<table class="table table-compact w-full">
|
|
14
|
-
<thead>
|
|
15
|
-
<tr>
|
|
16
|
-
<th>Metric</th>
|
|
17
|
-
<th>Value</th>
|
|
18
|
-
</tr>
|
|
19
|
-
</thead>
|
|
20
|
-
<tbody>
|
|
21
|
-
<tr>
|
|
22
|
-
<td>Uptime</td>
|
|
23
|
-
<td>{Math.round((Date.now() - startedAt) / 100) / 10} s</td>
|
|
24
|
-
</tr>
|
|
25
|
-
<tr>
|
|
26
|
-
<td>Cycles/ms</td>
|
|
27
|
-
{ cycles <= 0 && <td>~ K</td> }
|
|
28
|
-
{ cycles > 0 && cycles <= 1000 && <td>{cycles} K</td> }
|
|
29
|
-
{ cycles > 1000 && <td>{Math.round(cycles / 1000)} KK</td> }
|
|
30
|
-
</tr>
|
|
31
|
-
<tr>
|
|
32
|
-
<td>NonSkipSleep COUNT/s</td>
|
|
33
|
-
<td>{stats.nonSkippableSleepPreSec}</td>
|
|
34
|
-
</tr>
|
|
35
|
-
<tr>
|
|
36
|
-
<td>Sleep COUNT/s</td>
|
|
37
|
-
<td>{stats.sleepPerSec}</td>
|
|
38
|
-
</tr>
|
|
39
|
-
<tr>
|
|
40
|
-
<td>Sleep TIME/s</td>
|
|
41
|
-
<td>{stats.sleepTimePerSec}</td>
|
|
42
|
-
</tr>
|
|
43
|
-
<tr>
|
|
44
|
-
<td>Msg FRAME/s</td>
|
|
45
|
-
<td>{stats.framePerSec}</td>
|
|
46
|
-
</tr>
|
|
47
|
-
<tr>
|
|
48
|
-
<td>Msg SOUND/s</td>
|
|
49
|
-
<td>{stats.soundPerSec}</td>
|
|
50
|
-
</tr>
|
|
51
|
-
<tr>
|
|
52
|
-
<td>Msg SENT/s</td>
|
|
53
|
-
<td>{stats.msgSentPerSec}</td>
|
|
54
|
-
</tr>
|
|
55
|
-
<tr>
|
|
56
|
-
<td>Msg RECV/s</td>
|
|
57
|
-
<td>{stats.msgRecvPerSec}</td>
|
|
58
|
-
</tr>
|
|
59
|
-
<tr>
|
|
60
|
-
<td>Net SENT/s</td>
|
|
61
|
-
<td>{Math.round(stats.netSent / 1024 * 100) / 100}Kb</td>
|
|
62
|
-
</tr>
|
|
63
|
-
<tr>
|
|
64
|
-
<td>Net RECV/s</td>
|
|
65
|
-
<td>{Math.round(stats.netRecv / 1024 * 100) / 100}Kb</td>
|
|
66
|
-
</tr>
|
|
67
|
-
<tr>
|
|
68
|
-
<td>HDD RECV/s</td>
|
|
69
|
-
<td>{driveRecvMb}Mb (~{driveSpeedMb}Mb/s)</td>
|
|
70
|
-
</tr>
|
|
71
|
-
<tr>
|
|
72
|
-
<td>HDD SENT/s</td>
|
|
73
|
-
<td>{Math.round(stats.driveSent / 1024 / 1024 * 100) / 100}Mb</td>
|
|
74
|
-
</tr>
|
|
75
|
-
<tr>
|
|
76
|
-
<td>HDD Cache</td>
|
|
77
|
-
<td>{Math.round(stats.driveCacheUsed / 1024 / 1024 * 100) / 100}Mb</td>
|
|
78
|
-
</tr>
|
|
79
|
-
<tr>
|
|
80
|
-
<td>HDD Cache Hit/Miss</td>
|
|
81
|
-
<td>{stats.driveCacheHit} / {stats.driveCacheMiss}</td>
|
|
82
|
-
</tr>
|
|
83
|
-
</tbody>
|
|
84
|
-
</table>
|
|
85
|
-
</div>
|
|
86
|
-
</div>;
|
|
87
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { storageSlice } from "../store/storage";
|
|
2
|
-
import { Account } from "../store/auth";
|
|
3
|
-
import { brCdn } from "../v8/config";
|
|
4
|
-
import { Store, getNonSerializableStore } from "../store";
|
|
5
|
-
|
|
6
|
-
export function bundleFromFile(file: File, store: Store): Promise<Uint8Array> {
|
|
7
|
-
return new Promise<Uint8Array>((resolve) => {
|
|
8
|
-
store.dispatch(storageSlice.actions.reset());
|
|
9
|
-
const reader = new FileReader();
|
|
10
|
-
reader.addEventListener("load", async (e) => {
|
|
11
|
-
resolve(new Uint8Array(reader.result as ArrayBuffer));
|
|
12
|
-
});
|
|
13
|
-
reader.addEventListener("progress", (e) => {
|
|
14
|
-
store.dispatch(storageSlice.actions.progress([e.loaded, e.total]));
|
|
15
|
-
});
|
|
16
|
-
reader.readAsArrayBuffer(file);
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export async function bundleFromChanges(url: string, account: Account | null,
|
|
22
|
-
store: Store): Promise<Uint8Array | null> {
|
|
23
|
-
if (account === null || !account.premium) {
|
|
24
|
-
return await getNonSerializableStore(store).cache.get(url).catch(() => null);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const response = await fetch(url, {
|
|
29
|
-
cache: "no-cache",
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (response.status !== 200) {
|
|
33
|
-
throw new Error("Resource not avalible (" + response.status + "): " + response.statusText);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return response.arrayBuffer().then((b) => new Uint8Array(b));
|
|
37
|
-
} catch (e: any) {
|
|
38
|
-
return await getNonSerializableStore(store).cache.get(url).catch(() => null);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function bundleFromUrl(url: string, store: Store): Promise<Uint8Array> {
|
|
43
|
-
try {
|
|
44
|
-
return await getNonSerializableStore(store).cache.get(url);
|
|
45
|
-
} catch (e: any) {
|
|
46
|
-
// ignore
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
store.dispatch(storageSlice.actions.reset());
|
|
50
|
-
const response = await fetch(url, {
|
|
51
|
-
cache: "no-store",
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
if (response.status !== 200) {
|
|
55
|
-
throw new Error("Resource not avalible (" + response.status + "): " + response.statusText);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const lenHeader = response.headers.get("Content-Length");
|
|
59
|
-
const length = lenHeader === null ? 0 :
|
|
60
|
-
Number.parseInt(lenHeader);
|
|
61
|
-
const reader = response.body!.getReader();
|
|
62
|
-
|
|
63
|
-
let received = 0;
|
|
64
|
-
const chunks: Uint8Array[] = [];
|
|
65
|
-
while (true) {
|
|
66
|
-
const { done, value } = await reader.read();
|
|
67
|
-
|
|
68
|
-
if (done) {
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
chunks.push(value);
|
|
73
|
-
received += value.length;
|
|
74
|
-
|
|
75
|
-
const bytes = Math.min(url.startsWith(brCdn) ? received / 2 : received, length);
|
|
76
|
-
store.dispatch(storageSlice.actions.progress([bytes, length]));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
let offset = 0;
|
|
80
|
-
const complete = new Uint8Array(received);
|
|
81
|
-
for (const next of chunks) {
|
|
82
|
-
complete.set(next, offset);
|
|
83
|
-
offset += next.length;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
getNonSerializableStore(store).cache
|
|
87
|
-
.put(url, complete)
|
|
88
|
-
.catch(console.error);
|
|
89
|
-
|
|
90
|
-
return complete;
|
|
91
|
-
};
|
package/src/host/fullscreen.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Store, getNonSerializableStore } from "../store";
|
|
2
|
-
import { uiSlice } from "../store/ui";
|
|
3
|
-
|
|
4
|
-
export function browserSetFullScreen(fullScreen: boolean, store: Store) {
|
|
5
|
-
const root = getNonSerializableStore(store).root as any;
|
|
6
|
-
if (fullScreen) {
|
|
7
|
-
if (root.requestFullscreen) {
|
|
8
|
-
root.requestFullscreen();
|
|
9
|
-
} else if (root.webkitRequestFullscreen) {
|
|
10
|
-
root.webkitRequestFullscreen();
|
|
11
|
-
} else if (root.mozRequestFullScreen) {
|
|
12
|
-
root.mozRequestFullScreen();
|
|
13
|
-
} else if (root.msRequestFullscreen) {
|
|
14
|
-
root.msRequestFullscreen();
|
|
15
|
-
} else if (root.webkitEnterFullscreen) {
|
|
16
|
-
root.webkitEnterFullscreen();
|
|
17
|
-
} else {
|
|
18
|
-
root.classList.add("jsdos-fullscreen-workaround");
|
|
19
|
-
}
|
|
20
|
-
} else {
|
|
21
|
-
if (root.classList.contains("jsdos-fullscreen-workaround")) {
|
|
22
|
-
root.classList.remove("jsdos-fullscreen-workaround");
|
|
23
|
-
} else if (document.exitFullscreen) {
|
|
24
|
-
document.exitFullscreen();
|
|
25
|
-
} else if ((document as any).webkitExitFullscreen) {
|
|
26
|
-
(document as any).webkitExitFullscreen();
|
|
27
|
-
} else if ((document as any).mozCancelFullScreen) {
|
|
28
|
-
(document as any).mozCancelFullScreen();
|
|
29
|
-
} else if ((document as any).msExitFullscreen) {
|
|
30
|
-
(document as any).msExitFullscreen();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
store.dispatch(uiSlice.actions.setFullScreen(fullScreen));
|
|
35
|
-
}
|
package/src/host/lcache.ts
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-unused-vars: 0 */
|
|
2
|
-
|
|
3
|
-
export interface Cache {
|
|
4
|
-
readonly owner: string;
|
|
5
|
-
put: (key: string, data: Uint8Array) => Promise<void>;
|
|
6
|
-
get: (key: string, defaultValue?: Uint8Array) => Promise<Uint8Array>;
|
|
7
|
-
del: (key: string) => Promise<void>;
|
|
8
|
-
keys: () => Promise<string[]>;
|
|
9
|
-
forEach: (each: (key: string, value: Uint8Array) => void) => Promise<void>;
|
|
10
|
-
close: () => void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class CacheNoop implements Cache {
|
|
14
|
-
public owner = "";
|
|
15
|
-
|
|
16
|
-
public close() {
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public put(key: string, data: Uint8Array): Promise<void> {
|
|
20
|
-
return Promise.resolve();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public get(key: string, defaultValue?: Uint8Array): Promise<Uint8Array> {
|
|
24
|
-
if (defaultValue !== undefined) {
|
|
25
|
-
return Promise.resolve(defaultValue);
|
|
26
|
-
}
|
|
27
|
-
return Promise.reject(new Error("Cache is not supported on this host"));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public del(key: string): Promise<void> {
|
|
31
|
-
return Promise.resolve();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public keys(): Promise<string[]> {
|
|
35
|
-
return Promise.resolve([]);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public forEach(each: (key: string, value: Uint8Array) => void) {
|
|
39
|
-
return Promise.resolve();
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
class LCache implements Cache {
|
|
44
|
-
public owner: string;
|
|
45
|
-
private storeName = "files";
|
|
46
|
-
private indexedDB: IDBFactory;
|
|
47
|
-
private db: IDBDatabase | null = null;
|
|
48
|
-
|
|
49
|
-
constructor(owner: string,
|
|
50
|
-
onready: (cache: Cache) => void,
|
|
51
|
-
onerror: (msg: string) => void) {
|
|
52
|
-
this.owner = owner;
|
|
53
|
-
this.indexedDB = (typeof window === "undefined" ? undefined : window.indexedDB ||
|
|
54
|
-
(window as any).mozIndexedDB ||
|
|
55
|
-
(window as any).webkitIndexedDB || (window as any).msIndexedDB) as any;
|
|
56
|
-
|
|
57
|
-
if (!this.indexedDB) {
|
|
58
|
-
onerror("Indexed db is not supported on this host");
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
const openRequest = this.indexedDB.open("js-dos-cache (" + owner + ")", 1);
|
|
64
|
-
openRequest.onerror = (event) => {
|
|
65
|
-
onerror("Can't open cache database: " + openRequest.error?.message);
|
|
66
|
-
};
|
|
67
|
-
openRequest.onsuccess = (event) => {
|
|
68
|
-
this.db = openRequest.result;
|
|
69
|
-
onready(this);
|
|
70
|
-
};
|
|
71
|
-
openRequest.onupgradeneeded = (event) => {
|
|
72
|
-
try {
|
|
73
|
-
this.db = openRequest.result;
|
|
74
|
-
this.db.onerror = (event) => {
|
|
75
|
-
onerror("Can't upgrade cache database");
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const objectStore = this.db.createObjectStore(this.storeName);
|
|
79
|
-
objectStore.createIndex("key", "", {
|
|
80
|
-
unique: true,
|
|
81
|
-
multiEntry: false,
|
|
82
|
-
});
|
|
83
|
-
} catch (e) {
|
|
84
|
-
onerror("Can't upgrade cache database");
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
} catch (e: any) {
|
|
88
|
-
onerror("Can't open cache database: " + e.message);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public close() {
|
|
93
|
-
if (this.db !== null) {
|
|
94
|
-
this.db.close();
|
|
95
|
-
this.db = null;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
public put(key: string, data: Uint8Array): Promise<void> {
|
|
100
|
-
return new Promise<void>((resolve, reject) => {
|
|
101
|
-
if (this.db === null) {
|
|
102
|
-
resolve();
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const transaction = this.db.transaction(this.storeName, "readwrite");
|
|
107
|
-
const request = transaction.objectStore(this.storeName).put(data.buffer, key);
|
|
108
|
-
request.onerror = () => reject;
|
|
109
|
-
request.onsuccess = () => resolve();
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public del(key: string): Promise<void> {
|
|
114
|
-
return new Promise<void>((resolve, reject) => {
|
|
115
|
-
if (this.db === null) {
|
|
116
|
-
resolve();
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const transaction = this.db.transaction(this.storeName, "readwrite");
|
|
121
|
-
const request = transaction.objectStore(this.storeName).delete(key);
|
|
122
|
-
request.onerror = () => reject;
|
|
123
|
-
request.onsuccess = () => resolve();
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
public get(key: string, defaultValue?: Uint8Array): Promise<Uint8Array> {
|
|
128
|
-
return new Promise<Uint8Array>((resolve, reject) => {
|
|
129
|
-
function rejectOrResolve(message: string) {
|
|
130
|
-
if (defaultValue === undefined) {
|
|
131
|
-
reject(new Error(message));
|
|
132
|
-
} else {
|
|
133
|
-
resolve(defaultValue);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (this.db === null) {
|
|
139
|
-
rejectOrResolve("db is not initalized");
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const transaction = this.db.transaction(this.storeName, "readonly");
|
|
144
|
-
const request = transaction.objectStore(this.storeName).get(key) as IDBRequest<ArrayBuffer>;
|
|
145
|
-
request.onerror = () => reject(new Error("Can't read value for key '" + key + "'"));
|
|
146
|
-
request.onsuccess = () => {
|
|
147
|
-
if (request.result) {
|
|
148
|
-
resolve(new Uint8Array(request.result));
|
|
149
|
-
} else {
|
|
150
|
-
rejectOrResolve("Result is empty for key '" + key + "', result: " + request.result);
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
public keys(): Promise<string[]> {
|
|
157
|
-
return new Promise<string[]>((resolve, reject) => {
|
|
158
|
-
if (this.db === null) {
|
|
159
|
-
resolve([]);
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const transaction = this.db.transaction(this.storeName, "readonly");
|
|
164
|
-
const request = transaction.objectStore(this.storeName).index("key").getAllKeys();
|
|
165
|
-
request.onerror = () => reject;
|
|
166
|
-
request.onsuccess = (event) => {
|
|
167
|
-
const keys = (event.target as any).result as string[];
|
|
168
|
-
resolve(keys);
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
public forEach(each: (key: string, value: Uint8Array) => void): Promise<void> {
|
|
174
|
-
return new Promise<void>((resolve, reject) => {
|
|
175
|
-
if (this.db === null) {
|
|
176
|
-
resolve();
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const transaction = this.db.transaction(this.storeName, "readonly");
|
|
181
|
-
const request = transaction.objectStore(this.storeName).openCursor();
|
|
182
|
-
request.onerror = () => reject;
|
|
183
|
-
request.onsuccess = (event) => {
|
|
184
|
-
const cursor = (event.target as any).result as IDBCursorWithValue;
|
|
185
|
-
if (cursor) {
|
|
186
|
-
each(cursor.key.toString(), new Uint8Array(cursor.value));
|
|
187
|
-
cursor.continue();
|
|
188
|
-
} else {
|
|
189
|
-
resolve();
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export function getCache(owner: string): Promise<Cache> {
|
|
197
|
-
return new Promise((resolve) => {
|
|
198
|
-
new LCache(owner, resolve, (msg: string) => {
|
|
199
|
-
console.error("Can't open IndexedDB cache", msg);
|
|
200
|
-
resolve(new CacheNoop());
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
}
|
package/src/host/lstorage.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
const MAX_VALUE_SIZE = 1024;
|
|
2
|
-
const NEXT_PART_SYMBOL = "@";
|
|
3
|
-
const NEXT_PART_SYFFIX = ".";
|
|
4
|
-
|
|
5
|
-
class MemStorage implements Storage {
|
|
6
|
-
length = 0;
|
|
7
|
-
|
|
8
|
-
private storage: {[key: string]: string} = {};
|
|
9
|
-
|
|
10
|
-
setItem(key: string, value: string): void {
|
|
11
|
-
this.storage[key] = value;
|
|
12
|
-
this.length = Object.keys(this.storage).length;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
getItem(key: string): string | null {
|
|
16
|
-
const value = this.storage[key];
|
|
17
|
-
return value === undefined ? null : value;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
removeItem(key: string): void {
|
|
21
|
-
delete this.storage[key];
|
|
22
|
-
this.length = Object.keys(this.storage).length;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
key(index: number): string | null {
|
|
26
|
-
const keys = Object.keys(this.storage);
|
|
27
|
-
return keys[index] === undefined ? null : keys[index];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
clear() {
|
|
31
|
-
this.length = 0;
|
|
32
|
-
this.storage = {};
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class LStorage implements Storage {
|
|
38
|
-
private backend: Storage;
|
|
39
|
-
length: number;
|
|
40
|
-
prefix: string;
|
|
41
|
-
|
|
42
|
-
constructor(backend: Storage | undefined, prefix: string) {
|
|
43
|
-
this.prefix = prefix;
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
this.backend = backend || localStorage;
|
|
47
|
-
this.testBackend();
|
|
48
|
-
} catch (e) {
|
|
49
|
-
this.backend = new MemStorage();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
this.length = this.backend.length;
|
|
53
|
-
|
|
54
|
-
if (typeof this.backend.sync === "function") {
|
|
55
|
-
(this as any).sync = (callback: any) => {
|
|
56
|
-
this.backend.sync(callback);
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private testBackend() {
|
|
62
|
-
const testKey = this.prefix + ".test.record";
|
|
63
|
-
const testValue = "123";
|
|
64
|
-
this.backend.setItem(testKey, testValue);
|
|
65
|
-
const readedValue = this.backend.getItem(testKey);
|
|
66
|
-
this.backend.removeItem(testKey);
|
|
67
|
-
const valid = readedValue === testValue && this.backend.getItem(testKey) === null;
|
|
68
|
-
|
|
69
|
-
if (!valid) {
|
|
70
|
-
throw new Error("Storage backend is not working properly");
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
setLocalStoragePrefix(prefix: string) {
|
|
75
|
-
this.prefix = prefix;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
clear(): void {
|
|
79
|
-
if (!this.backend.length) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const toRemove: string[] = [];
|
|
84
|
-
for (let i = 0; i < this.backend.length; ++i) {
|
|
85
|
-
const next = this.backend.key(i);
|
|
86
|
-
if (next && next.startsWith(this.prefix)) {
|
|
87
|
-
toRemove.push(next);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
for (const next of toRemove) {
|
|
92
|
-
this.backend.removeItem(next);
|
|
93
|
-
}
|
|
94
|
-
this.length = this.backend.length;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
key(index: number): string | null {
|
|
98
|
-
return this.backend.key(index);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
setItem(key: string, value: string): void {
|
|
102
|
-
if (!value || value.length === undefined || value.length === 0) {
|
|
103
|
-
this.writeStringToKey(key, "");
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
let offset = 0;
|
|
108
|
-
while (offset < value.length) {
|
|
109
|
-
let substr = value.substr(offset, MAX_VALUE_SIZE);
|
|
110
|
-
offset += substr.length;
|
|
111
|
-
|
|
112
|
-
if (offset < value.length) {
|
|
113
|
-
substr += NEXT_PART_SYMBOL;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
this.writeStringToKey(key, substr);
|
|
117
|
-
key += NEXT_PART_SYFFIX;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
getItem(key: string): string | null {
|
|
122
|
-
let value = this.readStringFromKey(key);
|
|
123
|
-
if (value === null) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (value.length === 0) {
|
|
128
|
-
return value;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
while (value[value.length - 1] === NEXT_PART_SYMBOL) {
|
|
132
|
-
value = value.substr(0, value.length - 1);
|
|
133
|
-
key += NEXT_PART_SYFFIX;
|
|
134
|
-
const next = this.readStringFromKey(key);
|
|
135
|
-
value += next === null ? "" : next;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return value;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
removeItem(key: string): void {
|
|
142
|
-
this.backend.removeItem(this.prefix + key);
|
|
143
|
-
this.length = this.backend.length;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private writeStringToKey(key: string, value: string) {
|
|
147
|
-
this.backend.setItem(this.prefix + key, value);
|
|
148
|
-
this.length = this.backend.length;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
private readStringFromKey(key: string) {
|
|
152
|
-
return this.backend.getItem(this.prefix + key);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export const lStorage = new LStorage(undefined, "jsdos.8.");
|