sliftutils 1.2.38 → 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.
- package/.claude/settings.local.json +5 -1
- package/index.d.ts +268 -0
- package/misc/getSecret.d.ts +1 -0
- package/misc/getSecret.ts +7 -0
- package/misc/https/httpsCerts.d.ts +17 -0
- package/misc/https/httpsCerts.ts +4 -4
- package/package.json +2 -2
- package/render-utils/mobxTyped.d.ts +1 -0
- package/render-utils/mobxTyped.ts +4 -0
- package/storage/BulkDatabase2/BulkDatabase2.d.ts +8 -0
- package/storage/BulkDatabase2/BulkDatabase2.ts +41 -0
- package/storage/BulkDatabase2/BulkDatabaseBase.d.ts +84 -0
- package/storage/BulkDatabase2/BulkDatabaseBase.ts +797 -0
- package/storage/BulkDatabase2/BulkDatabaseFormat.d.ts +24 -0
- package/storage/BulkDatabase2/BulkDatabaseFormat.ts +285 -0
- package/storage/BulkDatabase2/blockCache.d.ts +17 -0
- package/storage/BulkDatabase2/blockCache.ts +173 -0
- package/storage/BulkDatabase2/streamLog.d.ts +25 -0
- package/storage/BulkDatabase2/streamLog.ts +116 -0
- package/storage/BulkDatabase2/syncClient.d.ts +9 -0
- package/storage/BulkDatabase2/syncClient.ts +81 -0
- package/storage/DiskCollection.d.ts +2 -0
- package/storage/DiskCollection.ts +17 -1
- package/storage/FileFolderAPI.d.ts +56 -0
- package/storage/FileFolderAPI.tsx +93 -19
- package/yarn.lock +4 -4
package/index.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ declare module "sliftutils/misc/getSecret" {
|
|
|
55
55
|
getAllKeys(): string[];
|
|
56
56
|
get(key: string): Promise<string> | undefined;
|
|
57
57
|
};
|
|
58
|
+
export declare function setSecret(key: string, value: string): void;
|
|
58
59
|
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -156,6 +157,11 @@ declare module "sliftutils/misc/https/dns" {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
declare module "sliftutils/misc/https/httpsCerts" {
|
|
160
|
+
/// <reference path="node-forge-ed25519.d.ts" />
|
|
161
|
+
/// <reference path="../../storage/storage.d.ts" />
|
|
162
|
+
/// <reference types="node" />
|
|
163
|
+
/// <reference types="node" />
|
|
164
|
+
import * as forge from "node-forge";
|
|
159
165
|
/** NOTE: We also generate the domain *.domain */
|
|
160
166
|
export declare const getHTTPSCert: {
|
|
161
167
|
(key: string): Promise<{
|
|
@@ -174,6 +180,18 @@ declare module "sliftutils/misc/https/httpsCerts" {
|
|
|
174
180
|
cert: string;
|
|
175
181
|
}> | undefined;
|
|
176
182
|
};
|
|
183
|
+
export declare const getAccountKey: (domain: string) => Promise<string>;
|
|
184
|
+
export declare function parseCert(PEMorDER: string | Buffer): forge.pki.Certificate;
|
|
185
|
+
export declare function normalizeCertToPEM(PEMorDER: string | Buffer): string;
|
|
186
|
+
export declare function generateCert(config: {
|
|
187
|
+
accountKey: string;
|
|
188
|
+
domain: string;
|
|
189
|
+
altDomains?: string[];
|
|
190
|
+
}): Promise<{
|
|
191
|
+
domains: string[];
|
|
192
|
+
key: string;
|
|
193
|
+
cert: string;
|
|
194
|
+
}>;
|
|
177
195
|
|
|
178
196
|
}
|
|
179
197
|
|
|
@@ -697,6 +715,7 @@ declare module "sliftutils/render-utils/colors" {
|
|
|
697
715
|
}
|
|
698
716
|
|
|
699
717
|
declare module "sliftutils/render-utils/mobxTyped" {
|
|
718
|
+
export { observable, runInAction, computed, autorun } from "mobx";
|
|
700
719
|
export declare function configureMobxNextFrameScheduler(): void;
|
|
701
720
|
|
|
702
721
|
}
|
|
@@ -743,6 +762,197 @@ declare module "sliftutils/render-utils/observer" {
|
|
|
743
762
|
|
|
744
763
|
}
|
|
745
764
|
|
|
765
|
+
declare module "sliftutils/storage/BulkDatabase2/BulkDatabase2" {
|
|
766
|
+
import { BulkDatabaseBase } from "./BulkDatabaseBase";
|
|
767
|
+
export { BulkDatabaseBase, noopReactiveDeps } from "./BulkDatabaseBase";
|
|
768
|
+
export type { ReactiveDeps, StorageFactory } from "./BulkDatabaseBase";
|
|
769
|
+
export declare class BulkDatabase2<T extends {
|
|
770
|
+
key: string;
|
|
771
|
+
}> extends BulkDatabaseBase<T> {
|
|
772
|
+
constructor(name: string);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseBase" {
|
|
778
|
+
import type { FileStorage } from "../FileFolderAPI";
|
|
779
|
+
export interface ReactiveDeps {
|
|
780
|
+
observe(signal: string): void;
|
|
781
|
+
invalidate(signal: string): void;
|
|
782
|
+
batch(fn: () => void): void;
|
|
783
|
+
}
|
|
784
|
+
export declare const noopReactiveDeps: ReactiveDeps;
|
|
785
|
+
export type StorageFactory = (path: string) => Promise<FileStorage>;
|
|
786
|
+
export declare class BulkDatabaseBase<T extends {
|
|
787
|
+
key: string;
|
|
788
|
+
}> {
|
|
789
|
+
readonly name: string;
|
|
790
|
+
protected deps: ReactiveDeps;
|
|
791
|
+
private storageFactory;
|
|
792
|
+
constructor(name: string, deps: ReactiveDeps, storageFactory: StorageFactory);
|
|
793
|
+
static clearCache(): void;
|
|
794
|
+
storage: {
|
|
795
|
+
(): Promise<FileStorage>;
|
|
796
|
+
reset(): void;
|
|
797
|
+
set(newValue: Promise<FileStorage>): void;
|
|
798
|
+
};
|
|
799
|
+
private overlay;
|
|
800
|
+
private streamTimes;
|
|
801
|
+
private streamFileName;
|
|
802
|
+
private streamRowsWritten;
|
|
803
|
+
private getStreamFileName;
|
|
804
|
+
private setOverlay;
|
|
805
|
+
private reader;
|
|
806
|
+
private syncSetup;
|
|
807
|
+
private localTime;
|
|
808
|
+
private applyRemote;
|
|
809
|
+
private resetReader;
|
|
810
|
+
write(entry: T): Promise<void>;
|
|
811
|
+
writeBatch(entries: T[]): Promise<void>;
|
|
812
|
+
delete(key: string): Promise<void>;
|
|
813
|
+
deleteBatch(keys: string[]): Promise<void>;
|
|
814
|
+
private writeBulkFile;
|
|
815
|
+
private listStreamFiles;
|
|
816
|
+
private loadStreamEntries;
|
|
817
|
+
private orderStreamEntries;
|
|
818
|
+
private maybeRolloverStream;
|
|
819
|
+
private rolloverStream;
|
|
820
|
+
compact(): Promise<void>;
|
|
821
|
+
private listFiles;
|
|
822
|
+
private makeRawGetRange;
|
|
823
|
+
private loadFileReader;
|
|
824
|
+
private fileLogicalSize;
|
|
825
|
+
private handleUnreadableFile;
|
|
826
|
+
private mergeFilesBase;
|
|
827
|
+
private mergeFiles;
|
|
828
|
+
private formatInfo;
|
|
829
|
+
private patchColumn;
|
|
830
|
+
getSingleField<Column extends keyof T>(key: string, column: Column): Promise<T[Column] | undefined>;
|
|
831
|
+
getColumn<Column extends keyof T>(column: Column): Promise<{
|
|
832
|
+
key: string;
|
|
833
|
+
value: T[Column];
|
|
834
|
+
}[]>;
|
|
835
|
+
getKeys(): Promise<string[]>;
|
|
836
|
+
private baseColumns;
|
|
837
|
+
private baseColumnsLoading;
|
|
838
|
+
private baseFields;
|
|
839
|
+
private baseFieldsLoading;
|
|
840
|
+
private ensureBaseColumn;
|
|
841
|
+
private ensureBaseField;
|
|
842
|
+
getSingleFieldSync<Column extends keyof T>(key: string, column: Column): T[Column] | undefined;
|
|
843
|
+
getColumnSync<Column extends keyof T>(column: Column): {
|
|
844
|
+
key: string;
|
|
845
|
+
value: T[Column];
|
|
846
|
+
}[] | undefined;
|
|
847
|
+
getColumnInfo(): Promise<{
|
|
848
|
+
column: string;
|
|
849
|
+
byteSize: number;
|
|
850
|
+
}[]>;
|
|
851
|
+
getReaderInfo(): Promise<{
|
|
852
|
+
rowCount: number;
|
|
853
|
+
totalBytes: number;
|
|
854
|
+
keyCount: number;
|
|
855
|
+
sampleKey: string | undefined;
|
|
856
|
+
columns: {
|
|
857
|
+
column: string;
|
|
858
|
+
byteSize: number;
|
|
859
|
+
}[];
|
|
860
|
+
}>;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseFormat" {
|
|
866
|
+
/// <reference types="node" />
|
|
867
|
+
/// <reference types="node" />
|
|
868
|
+
export declare const KEY_COLUMN = "key";
|
|
869
|
+
export declare const EMPTY_BUFFER: Buffer;
|
|
870
|
+
export declare function buildFileBuffer(rows: Record<string, unknown>[]): Buffer[];
|
|
871
|
+
export type BaseBulkDatabaseReader = {
|
|
872
|
+
rowCount: number;
|
|
873
|
+
totalBytes: number;
|
|
874
|
+
keys: string[];
|
|
875
|
+
columns: {
|
|
876
|
+
column: string;
|
|
877
|
+
byteSize: number;
|
|
878
|
+
}[];
|
|
879
|
+
deletedKeys?: Set<string>;
|
|
880
|
+
getColumn: (column: string) => Promise<{
|
|
881
|
+
key: string;
|
|
882
|
+
value: unknown;
|
|
883
|
+
}[]>;
|
|
884
|
+
getSingleField: (key: string, column: string) => Promise<unknown | undefined>;
|
|
885
|
+
};
|
|
886
|
+
export declare function loadBulkDatabase(config: {
|
|
887
|
+
totalBytes: number;
|
|
888
|
+
getRange: (start: number, end: number) => Promise<Buffer>;
|
|
889
|
+
}): Promise<BaseBulkDatabaseReader>;
|
|
890
|
+
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
declare module "sliftutils/storage/BulkDatabase2/blockCache" {
|
|
894
|
+
/// <reference types="node" />
|
|
895
|
+
/// <reference types="node" />
|
|
896
|
+
export type GetRange = (start: number, end: number) => Promise<Buffer>;
|
|
897
|
+
export declare function encodeCompressedBlocks(data: Buffer): Buffer;
|
|
898
|
+
export declare class BlockCache {
|
|
899
|
+
private blocks;
|
|
900
|
+
private indexes;
|
|
901
|
+
clear(): void;
|
|
902
|
+
private touch;
|
|
903
|
+
private readIndex;
|
|
904
|
+
open(fileId: string, fileSize: number, rawGetRange: GetRange): Promise<{
|
|
905
|
+
uncompressedSize: number;
|
|
906
|
+
getRange: GetRange;
|
|
907
|
+
}>;
|
|
908
|
+
private makeGetRange;
|
|
909
|
+
}
|
|
910
|
+
export declare const blockCache: BlockCache;
|
|
911
|
+
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
declare module "sliftutils/storage/BulkDatabase2/streamLog" {
|
|
915
|
+
/// <reference types="node" />
|
|
916
|
+
/// <reference types="node" />
|
|
917
|
+
import { BaseBulkDatabaseReader } from "./BulkDatabaseFormat";
|
|
918
|
+
export declare const STREAM_EXTENSION = ".stream";
|
|
919
|
+
export type StreamEntry = {
|
|
920
|
+
time: number;
|
|
921
|
+
row?: Record<string, unknown>;
|
|
922
|
+
deletedKey?: string;
|
|
923
|
+
};
|
|
924
|
+
export declare function frameRows(entries: {
|
|
925
|
+
time: number;
|
|
926
|
+
row: Record<string, unknown>;
|
|
927
|
+
}[]): Buffer;
|
|
928
|
+
export declare function frameDeletes(entries: {
|
|
929
|
+
time: number;
|
|
930
|
+
key: string;
|
|
931
|
+
}[]): Buffer;
|
|
932
|
+
export declare function parseStream(buffer: Buffer): {
|
|
933
|
+
entries: StreamEntry[];
|
|
934
|
+
badBytes: number;
|
|
935
|
+
};
|
|
936
|
+
export declare function streamReaderFromEntries(entries: StreamEntry[], totalBytes: number): {
|
|
937
|
+
reader: BaseBulkDatabaseReader;
|
|
938
|
+
times: Map<string, number>;
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
declare module "sliftutils/storage/BulkDatabase2/syncClient" {
|
|
944
|
+
export type RemoteWrite = {
|
|
945
|
+
key: string;
|
|
946
|
+
time: number;
|
|
947
|
+
deleted?: boolean;
|
|
948
|
+
value?: unknown;
|
|
949
|
+
};
|
|
950
|
+
export declare function isSyncSupported(): boolean;
|
|
951
|
+
export declare function connect(collection: string, onWrite: (write: RemoteWrite) => void): Promise<RemoteWrite[]>;
|
|
952
|
+
export declare function broadcast(collection: string, write: RemoteWrite): void;
|
|
953
|
+
|
|
954
|
+
}
|
|
955
|
+
|
|
746
956
|
declare module "sliftutils/storage/CBORStorage" {
|
|
747
957
|
/// <reference types="node" />
|
|
748
958
|
/// <reference types="node" />
|
|
@@ -798,6 +1008,8 @@ declare module "sliftutils/storage/DiskCollection" {
|
|
|
798
1008
|
export declare class DiskCollection<T> implements IStorageSync<T> {
|
|
799
1009
|
private collectionName;
|
|
800
1010
|
private config?;
|
|
1011
|
+
static getForceNoPrompt(): boolean;
|
|
1012
|
+
static setForceNoPrompt(forceNoPrompt: boolean): void;
|
|
801
1013
|
constructor(collectionName: string, config?: {
|
|
802
1014
|
writeDelay?: number | undefined;
|
|
803
1015
|
cbor?: boolean | undefined;
|
|
@@ -967,6 +1179,52 @@ declare module "sliftutils/storage/FileFolderAPI" {
|
|
|
967
1179
|
]>;
|
|
968
1180
|
};
|
|
969
1181
|
export declare function setFileAPIKey(key: string): void;
|
|
1182
|
+
export declare class NodeJSFileHandleWrapper implements FileWrapper {
|
|
1183
|
+
private filePath;
|
|
1184
|
+
constructor(filePath: string);
|
|
1185
|
+
getFile(): Promise<{
|
|
1186
|
+
size: number;
|
|
1187
|
+
lastModified: number;
|
|
1188
|
+
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
1189
|
+
slice: (start: number, end: number) => {
|
|
1190
|
+
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
1191
|
+
};
|
|
1192
|
+
}>;
|
|
1193
|
+
createWritable(config?: {
|
|
1194
|
+
keepExistingData?: boolean;
|
|
1195
|
+
}): Promise<{
|
|
1196
|
+
seek: (offset: number) => Promise<void>;
|
|
1197
|
+
write: (value: Buffer) => Promise<void>;
|
|
1198
|
+
close: () => Promise<void>;
|
|
1199
|
+
}>;
|
|
1200
|
+
}
|
|
1201
|
+
export declare class NodeJSDirectoryHandleWrapper implements DirectoryWrapper {
|
|
1202
|
+
private rootPath;
|
|
1203
|
+
constructor(rootPath: string);
|
|
1204
|
+
removeEntry(key: string, options?: {
|
|
1205
|
+
recursive?: boolean;
|
|
1206
|
+
}): Promise<void>;
|
|
1207
|
+
getFileHandle(key: string, options?: {
|
|
1208
|
+
create?: boolean;
|
|
1209
|
+
}): Promise<FileWrapper>;
|
|
1210
|
+
getDirectoryHandle(key: string, options?: {
|
|
1211
|
+
create?: boolean;
|
|
1212
|
+
}): Promise<DirectoryWrapper>;
|
|
1213
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<[
|
|
1214
|
+
string,
|
|
1215
|
+
{
|
|
1216
|
+
kind: "file";
|
|
1217
|
+
name: string;
|
|
1218
|
+
getFile(): Promise<FileWrapper>;
|
|
1219
|
+
} | {
|
|
1220
|
+
kind: "directory";
|
|
1221
|
+
name: string;
|
|
1222
|
+
getDirectoryHandle(key: string, options?: {
|
|
1223
|
+
create?: boolean;
|
|
1224
|
+
}): Promise<DirectoryWrapper>;
|
|
1225
|
+
}
|
|
1226
|
+
]>;
|
|
1227
|
+
}
|
|
970
1228
|
export declare const getDirectoryHandle: {
|
|
971
1229
|
(): Promise<DirectoryWrapper>;
|
|
972
1230
|
reset(): void;
|
|
@@ -980,6 +1238,14 @@ declare module "sliftutils/storage/FileFolderAPI" {
|
|
|
980
1238
|
getAllKeys(): string[];
|
|
981
1239
|
get(key: string): Promise<FileStorage> | undefined;
|
|
982
1240
|
};
|
|
1241
|
+
export declare const getFileStorageNested2: {
|
|
1242
|
+
(key: string): Promise<FileStorage>;
|
|
1243
|
+
clear(key: string): void;
|
|
1244
|
+
clearAll(): void;
|
|
1245
|
+
forceSet(key: string, value: Promise<FileStorage>): void;
|
|
1246
|
+
getAllKeys(): string[];
|
|
1247
|
+
get(key: string): Promise<FileStorage> | undefined;
|
|
1248
|
+
};
|
|
983
1249
|
export declare const getFileStorage: {
|
|
984
1250
|
(): Promise<FileStorage>;
|
|
985
1251
|
reset(): void;
|
|
@@ -995,6 +1261,8 @@ declare module "sliftutils/storage/FileFolderAPI" {
|
|
|
995
1261
|
export type FileStorage = IStorageRaw & {
|
|
996
1262
|
folder: NestedFileStorage;
|
|
997
1263
|
};
|
|
1264
|
+
export declare function wrapHandle(handle: DirectoryWrapper): FileStorage;
|
|
1265
|
+
export declare function tryToLoadPointer(pointer: string): Promise<DirectoryWrapper | undefined>;
|
|
998
1266
|
export {};
|
|
999
1267
|
|
|
1000
1268
|
}
|
package/misc/getSecret.d.ts
CHANGED
package/misc/getSecret.ts
CHANGED
|
@@ -96,3 +96,10 @@ export const getSecret = cache(async function getSecret(key: string): Promise<st
|
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
|
+
|
|
100
|
+
export function setSecret(key: string, value: string) {
|
|
101
|
+
if (isNode()) {
|
|
102
|
+
throw new Error("setSecret is only supported in the browser. We don't want to break the user's file system with setSecret in NodeJS.");
|
|
103
|
+
}
|
|
104
|
+
localStorage.setItem(getStorageKey(key), value);
|
|
105
|
+
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/// <reference path="node-forge-ed25519.d.ts" />
|
|
2
|
+
/// <reference path="../../storage/storage.d.ts" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
import * as forge from "node-forge";
|
|
1
6
|
/** NOTE: We also generate the domain *.domain */
|
|
2
7
|
export declare const getHTTPSCert: {
|
|
3
8
|
(key: string): Promise<{
|
|
@@ -16,3 +21,15 @@ export declare const getHTTPSCert: {
|
|
|
16
21
|
cert: string;
|
|
17
22
|
}> | undefined;
|
|
18
23
|
};
|
|
24
|
+
export declare const getAccountKey: (domain: string) => Promise<string>;
|
|
25
|
+
export declare function parseCert(PEMorDER: string | Buffer): forge.pki.Certificate;
|
|
26
|
+
export declare function normalizeCertToPEM(PEMorDER: string | Buffer): string;
|
|
27
|
+
export declare function generateCert(config: {
|
|
28
|
+
accountKey: string;
|
|
29
|
+
domain: string;
|
|
30
|
+
altDomains?: string[];
|
|
31
|
+
}): Promise<{
|
|
32
|
+
domains: string[];
|
|
33
|
+
key: string;
|
|
34
|
+
cert: string;
|
|
35
|
+
}>;
|
package/misc/https/httpsCerts.ts
CHANGED
|
@@ -91,7 +91,7 @@ export const getHTTPSCert = cache(async (domain: string): Promise<{ key: string;
|
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
const getAccountKey = async function getAccountKey(domain: string) {
|
|
94
|
+
export const getAccountKey = async function getAccountKey(domain: string) {
|
|
95
95
|
let accountKey = getKeyStore<string>(domain, "letsEncryptAccountKey");
|
|
96
96
|
let secret = await accountKey.get();
|
|
97
97
|
if (!secret) {
|
|
@@ -105,11 +105,11 @@ const getAccountKey = async function getAccountKey(domain: string) {
|
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
function parseCert(PEMorDER: string | Buffer) {
|
|
108
|
+
export function parseCert(PEMorDER: string | Buffer) {
|
|
109
109
|
return forge.pki.certificateFromPem(normalizeCertToPEM(PEMorDER));
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function normalizeCertToPEM(PEMorDER: string | Buffer): string {
|
|
112
|
+
export function normalizeCertToPEM(PEMorDER: string | Buffer): string {
|
|
113
113
|
if (PEMorDER.toString().startsWith("-----BEGIN CERTIFICATE-----")) {
|
|
114
114
|
return PEMorDER.toString();
|
|
115
115
|
}
|
|
@@ -118,7 +118,7 @@ function normalizeCertToPEM(PEMorDER: string | Buffer): string {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
|
|
121
|
-
async function generateCert(config: {
|
|
121
|
+
export async function generateCert(config: {
|
|
122
122
|
accountKey: string;
|
|
123
123
|
domain: string;
|
|
124
124
|
altDomains?: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sliftutils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"mobx": "^6.13.3",
|
|
52
52
|
"preact-old-types": "^10.28.1",
|
|
53
53
|
"shell-quote": "^1.8.3",
|
|
54
|
-
"socket-function": "^1.1.
|
|
54
|
+
"socket-function": "^1.1.42",
|
|
55
55
|
"typenode": "*",
|
|
56
56
|
"typesafecss": "*",
|
|
57
57
|
"ws": "^8.18.3",
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as mobx from "mobx";
|
|
2
2
|
import { batchFunction } from "socket-function/src/batching";
|
|
3
|
+
|
|
4
|
+
// Re-export the core mobx primitives so downstream packages (which may have their own duplicate mobx
|
|
5
|
+
// in node_modules) can share THIS mobx instance, otherwise reactivity doesn't cross package boundaries.
|
|
6
|
+
export { observable, runInAction, computed, autorun } from "mobx";
|
|
3
7
|
export function configureMobxNextFrameScheduler() {
|
|
4
8
|
// NOTE: This makes a big difference if we do await calls in a loop which mutates observable state. BUT... we should probably just do those await calls before the loop?
|
|
5
9
|
let batchReactionScheduler = batchFunction({
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BulkDatabaseBase } from "./BulkDatabaseBase";
|
|
2
|
+
export { BulkDatabaseBase, noopReactiveDeps } from "./BulkDatabaseBase";
|
|
3
|
+
export type { ReactiveDeps, StorageFactory } from "./BulkDatabaseBase";
|
|
4
|
+
export declare class BulkDatabase2<T extends {
|
|
5
|
+
key: string;
|
|
6
|
+
}> extends BulkDatabaseBase<T> {
|
|
7
|
+
constructor(name: string);
|
|
8
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getFileStorageNested2 } from "../FileFolderAPI";
|
|
2
|
+
import { observable, runInAction } from "../../render-utils/mobxTyped";
|
|
3
|
+
import { BulkDatabaseBase, ReactiveDeps } from "./BulkDatabaseBase";
|
|
4
|
+
|
|
5
|
+
export { BulkDatabaseBase, noopReactiveDeps } from "./BulkDatabaseBase";
|
|
6
|
+
export type { ReactiveDeps, StorageFactory } from "./BulkDatabaseBase";
|
|
7
|
+
|
|
8
|
+
// mobx-backed reactivity: each signal string gets its own observable box. observe() reads it (so an
|
|
9
|
+
// observer/autorun that calls it tracks that box) and invalidate() bumps it (so those reactions re-run).
|
|
10
|
+
// This reproduces the fine-grained per-key + load-version reactivity the class had when it used
|
|
11
|
+
// observable.map/observable.box directly, while keeping all that logic in the mobx-free base.
|
|
12
|
+
class MobxReactiveDeps implements ReactiveDeps {
|
|
13
|
+
private boxes = new Map<string, { get(): number; set(value: number): void }>();
|
|
14
|
+
private box(signal: string) {
|
|
15
|
+
let box = this.boxes.get(signal);
|
|
16
|
+
if (!box) {
|
|
17
|
+
box = observable.box(0);
|
|
18
|
+
this.boxes.set(signal, box);
|
|
19
|
+
}
|
|
20
|
+
return box;
|
|
21
|
+
}
|
|
22
|
+
observe(signal: string) {
|
|
23
|
+
this.box(signal).get();
|
|
24
|
+
}
|
|
25
|
+
invalidate(signal: string) {
|
|
26
|
+
let box = this.box(signal);
|
|
27
|
+
box.set(box.get() + 1);
|
|
28
|
+
}
|
|
29
|
+
batch(fn: () => void) {
|
|
30
|
+
runInAction(fn);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Backwards-compatible BulkDatabase2: the mobx-reactive flavor. All behavior lives in BulkDatabaseBase;
|
|
35
|
+
// this just supplies mobx reactivity and the default (getFileStorageNested2) storage backend, so the
|
|
36
|
+
// sync reads (getSingleFieldSync / getColumnSync) stay observable for mobx components.
|
|
37
|
+
export class BulkDatabase2<T extends { key: string }> extends BulkDatabaseBase<T> {
|
|
38
|
+
constructor(name: string) {
|
|
39
|
+
super(name, new MobxReactiveDeps(), getFileStorageNested2);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { FileStorage } from "../FileFolderAPI";
|
|
2
|
+
export interface ReactiveDeps {
|
|
3
|
+
observe(signal: string): void;
|
|
4
|
+
invalidate(signal: string): void;
|
|
5
|
+
batch(fn: () => void): void;
|
|
6
|
+
}
|
|
7
|
+
export declare const noopReactiveDeps: ReactiveDeps;
|
|
8
|
+
export type StorageFactory = (path: string) => Promise<FileStorage>;
|
|
9
|
+
export declare class BulkDatabaseBase<T extends {
|
|
10
|
+
key: string;
|
|
11
|
+
}> {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
protected deps: ReactiveDeps;
|
|
14
|
+
private storageFactory;
|
|
15
|
+
constructor(name: string, deps: ReactiveDeps, storageFactory: StorageFactory);
|
|
16
|
+
static clearCache(): void;
|
|
17
|
+
storage: {
|
|
18
|
+
(): Promise<FileStorage>;
|
|
19
|
+
reset(): void;
|
|
20
|
+
set(newValue: Promise<FileStorage>): void;
|
|
21
|
+
};
|
|
22
|
+
private overlay;
|
|
23
|
+
private streamTimes;
|
|
24
|
+
private streamFileName;
|
|
25
|
+
private streamRowsWritten;
|
|
26
|
+
private getStreamFileName;
|
|
27
|
+
private setOverlay;
|
|
28
|
+
private reader;
|
|
29
|
+
private syncSetup;
|
|
30
|
+
private localTime;
|
|
31
|
+
private applyRemote;
|
|
32
|
+
private resetReader;
|
|
33
|
+
write(entry: T): Promise<void>;
|
|
34
|
+
writeBatch(entries: T[]): Promise<void>;
|
|
35
|
+
delete(key: string): Promise<void>;
|
|
36
|
+
deleteBatch(keys: string[]): Promise<void>;
|
|
37
|
+
private writeBulkFile;
|
|
38
|
+
private listStreamFiles;
|
|
39
|
+
private loadStreamEntries;
|
|
40
|
+
private orderStreamEntries;
|
|
41
|
+
private maybeRolloverStream;
|
|
42
|
+
private rolloverStream;
|
|
43
|
+
compact(): Promise<void>;
|
|
44
|
+
private listFiles;
|
|
45
|
+
private makeRawGetRange;
|
|
46
|
+
private loadFileReader;
|
|
47
|
+
private fileLogicalSize;
|
|
48
|
+
private handleUnreadableFile;
|
|
49
|
+
private mergeFilesBase;
|
|
50
|
+
private mergeFiles;
|
|
51
|
+
private formatInfo;
|
|
52
|
+
private patchColumn;
|
|
53
|
+
getSingleField<Column extends keyof T>(key: string, column: Column): Promise<T[Column] | undefined>;
|
|
54
|
+
getColumn<Column extends keyof T>(column: Column): Promise<{
|
|
55
|
+
key: string;
|
|
56
|
+
value: T[Column];
|
|
57
|
+
}[]>;
|
|
58
|
+
getKeys(): Promise<string[]>;
|
|
59
|
+
private baseColumns;
|
|
60
|
+
private baseColumnsLoading;
|
|
61
|
+
private baseFields;
|
|
62
|
+
private baseFieldsLoading;
|
|
63
|
+
private ensureBaseColumn;
|
|
64
|
+
private ensureBaseField;
|
|
65
|
+
getSingleFieldSync<Column extends keyof T>(key: string, column: Column): T[Column] | undefined;
|
|
66
|
+
getColumnSync<Column extends keyof T>(column: Column): {
|
|
67
|
+
key: string;
|
|
68
|
+
value: T[Column];
|
|
69
|
+
}[] | undefined;
|
|
70
|
+
getColumnInfo(): Promise<{
|
|
71
|
+
column: string;
|
|
72
|
+
byteSize: number;
|
|
73
|
+
}[]>;
|
|
74
|
+
getReaderInfo(): Promise<{
|
|
75
|
+
rowCount: number;
|
|
76
|
+
totalBytes: number;
|
|
77
|
+
keyCount: number;
|
|
78
|
+
sampleKey: string | undefined;
|
|
79
|
+
columns: {
|
|
80
|
+
column: string;
|
|
81
|
+
byteSize: number;
|
|
82
|
+
}[];
|
|
83
|
+
}>;
|
|
84
|
+
}
|