sliftutils 1.4.66 → 1.4.67
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/index.d.ts +13 -0
- package/package.json +1 -1
- package/storage/BulkDatabase2/BulkDatabase2.d.ts +7 -0
- package/storage/BulkDatabase2/BulkDatabase2.ts +8 -0
- package/storage/BulkDatabase2/BulkDatabaseBase.d.ts +2 -0
- package/storage/BulkDatabase2/BulkDatabaseBase.ts +16 -0
- package/storage/BulkDatabase2/BulkDatabaseReader.d.ts +4 -0
- package/storage/BulkDatabase2/BulkDatabaseReader.ts +17 -0
package/index.d.ts
CHANGED
|
@@ -853,6 +853,13 @@ declare module "sliftutils/storage/BulkDatabase2/BulkDatabase2" {
|
|
|
853
853
|
isFieldLoadedSync<Column extends keyof T>(key: string, column: Column): boolean;
|
|
854
854
|
/** Reactive: whether a whole column is loaded yet (see isFieldLoadedSync). */
|
|
855
855
|
isColumnLoadedSync<Column extends keyof T>(column: Column): boolean;
|
|
856
|
+
/**
|
|
857
|
+
* Reactive: true while a merge is rewriting this collection's files (background `maybeMerge` or
|
|
858
|
+
* an explicit `compact`/`merge`/`tryMergeNow`). Becomes false as soon as the new index is swapped
|
|
859
|
+
* in — the deferred-delete cleanup window is NOT counted. Use this in a UI to show a per-database
|
|
860
|
+
* "compacting…" indicator.
|
|
861
|
+
*/
|
|
862
|
+
isCompactingSync(): boolean;
|
|
856
863
|
/**
|
|
857
864
|
* Whether a row (key) is currently being watched by some reactive observer (getSingleFieldObjSync /
|
|
858
865
|
* getSingleFieldSync). Lets callers skip per-row work when nothing's watching. Non-reactive query;
|
|
@@ -1030,6 +1037,7 @@ declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseBase" {
|
|
|
1030
1037
|
private fileLogicalSize;
|
|
1031
1038
|
private handleUnreadableFile;
|
|
1032
1039
|
private mergeFileSet;
|
|
1040
|
+
private mergeFileSetInner;
|
|
1033
1041
|
private canDeleteStream;
|
|
1034
1042
|
private mergeSpacingDelay;
|
|
1035
1043
|
private testMerge;
|
|
@@ -1059,6 +1067,7 @@ declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseBase" {
|
|
|
1059
1067
|
}[] | undefined;
|
|
1060
1068
|
isFieldLoadedSync<C extends keyof T>(key: string, column: C): boolean;
|
|
1061
1069
|
isColumnLoadedSync<C extends keyof T>(column: C): boolean;
|
|
1070
|
+
isCompactingSync(): boolean;
|
|
1062
1071
|
getColumnInfo(): Promise<{
|
|
1063
1072
|
column: string;
|
|
1064
1073
|
byteSize: number;
|
|
@@ -1279,6 +1288,10 @@ declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseReader" {
|
|
|
1279
1288
|
isKeyWatched(key: string): boolean;
|
|
1280
1289
|
isLiveNow(key: string): boolean;
|
|
1281
1290
|
localTime(key: string): number;
|
|
1291
|
+
private compactingCount;
|
|
1292
|
+
beginCompaction(): void;
|
|
1293
|
+
endCompaction(): void;
|
|
1294
|
+
isCompactingSync(): boolean;
|
|
1282
1295
|
private notifyOverlayMutation;
|
|
1283
1296
|
getKeys(): Promise<string[]>;
|
|
1284
1297
|
getColumn<C extends keyof T>(column: C): Promise<{
|
package/package.json
CHANGED
|
@@ -88,6 +88,13 @@ export interface IBulkDatabase2<T extends {
|
|
|
88
88
|
isFieldLoadedSync<Column extends keyof T>(key: string, column: Column): boolean;
|
|
89
89
|
/** Reactive: whether a whole column is loaded yet (see isFieldLoadedSync). */
|
|
90
90
|
isColumnLoadedSync<Column extends keyof T>(column: Column): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Reactive: true while a merge is rewriting this collection's files (background `maybeMerge` or
|
|
93
|
+
* an explicit `compact`/`merge`/`tryMergeNow`). Becomes false as soon as the new index is swapped
|
|
94
|
+
* in — the deferred-delete cleanup window is NOT counted. Use this in a UI to show a per-database
|
|
95
|
+
* "compacting…" indicator.
|
|
96
|
+
*/
|
|
97
|
+
isCompactingSync(): boolean;
|
|
91
98
|
/**
|
|
92
99
|
* Whether a row (key) is currently being watched by some reactive observer (getSingleFieldObjSync /
|
|
93
100
|
* getSingleFieldSync). Lets callers skip per-row work when nothing's watching. Non-reactive query;
|
|
@@ -74,6 +74,14 @@ export interface IBulkDatabase2<T extends { key: string }> {
|
|
|
74
74
|
/** Reactive: whether a whole column is loaded yet (see isFieldLoadedSync). */
|
|
75
75
|
isColumnLoadedSync<Column extends keyof T>(column: Column): boolean;
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Reactive: true while a merge is rewriting this collection's files (background `maybeMerge` or
|
|
79
|
+
* an explicit `compact`/`merge`/`tryMergeNow`). Becomes false as soon as the new index is swapped
|
|
80
|
+
* in — the deferred-delete cleanup window is NOT counted. Use this in a UI to show a per-database
|
|
81
|
+
* "compacting…" indicator.
|
|
82
|
+
*/
|
|
83
|
+
isCompactingSync(): boolean;
|
|
84
|
+
|
|
77
85
|
/**
|
|
78
86
|
* Whether a row (key) is currently being watched by some reactive observer (getSingleFieldObjSync /
|
|
79
87
|
* getSingleFieldSync). Lets callers skip per-row work when nothing's watching. Non-reactive query;
|
|
@@ -106,6 +106,7 @@ export declare class BulkDatabaseBase<T extends {
|
|
|
106
106
|
private fileLogicalSize;
|
|
107
107
|
private handleUnreadableFile;
|
|
108
108
|
private mergeFileSet;
|
|
109
|
+
private mergeFileSetInner;
|
|
109
110
|
private canDeleteStream;
|
|
110
111
|
private mergeSpacingDelay;
|
|
111
112
|
private testMerge;
|
|
@@ -135,6 +136,7 @@ export declare class BulkDatabaseBase<T extends {
|
|
|
135
136
|
}[] | undefined;
|
|
136
137
|
isFieldLoadedSync<C extends keyof T>(key: string, column: C): boolean;
|
|
137
138
|
isColumnLoadedSync<C extends keyof T>(column: C): boolean;
|
|
139
|
+
isCompactingSync(): boolean;
|
|
138
140
|
getColumnInfo(): Promise<{
|
|
139
141
|
column: string;
|
|
140
142
|
byteSize: number;
|
|
@@ -632,6 +632,15 @@ export class BulkDatabaseBase<T extends { key: string }> {
|
|
|
632
632
|
// we trigger an index rebuild + atomic swap; once swap completes, the consumed files' block-cache
|
|
633
633
|
// entries are evicted (no consumer can ask for them now).
|
|
634
634
|
private async mergeFileSet(bulkFiles: BulkFileInfo[], streamFiles: StreamFileInfo[], includesOldest = false, forceDeleteStreams = false): Promise<boolean> {
|
|
635
|
+
this.reader.beginCompaction();
|
|
636
|
+
try {
|
|
637
|
+
return await this.mergeFileSetInner(bulkFiles, streamFiles, includesOldest, forceDeleteStreams);
|
|
638
|
+
} finally {
|
|
639
|
+
this.reader.endCompaction();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
private async mergeFileSetInner(bulkFiles: BulkFileInfo[], streamFiles: StreamFileInfo[], includesOldest: boolean, forceDeleteStreams: boolean): Promise<boolean> {
|
|
635
644
|
const storage = await this.storage();
|
|
636
645
|
const timestamp = nextFileTime();
|
|
637
646
|
|
|
@@ -932,6 +941,13 @@ export class BulkDatabaseBase<T extends { key: string }> {
|
|
|
932
941
|
return this.reader.isColumnLoadedSync(column);
|
|
933
942
|
}
|
|
934
943
|
|
|
944
|
+
// Reactive: true while a merge is rewriting this collection's files. Use this in UI to show a
|
|
945
|
+
// "compacting…" indicator. Counts both background merges (maybeMerge) and explicit compact/merge
|
|
946
|
+
// calls. Becomes false once the new index is swapped in (the deferred-delete window is NOT counted).
|
|
947
|
+
public isCompactingSync(): boolean {
|
|
948
|
+
return this.reader.isCompactingSync();
|
|
949
|
+
}
|
|
950
|
+
|
|
935
951
|
public async getColumnInfo() {
|
|
936
952
|
const index = await this.ensureIndex();
|
|
937
953
|
return index.reader.columns;
|
|
@@ -31,6 +31,10 @@ export declare class BulkDatabaseReader<T extends {
|
|
|
31
31
|
isKeyWatched(key: string): boolean;
|
|
32
32
|
isLiveNow(key: string): boolean;
|
|
33
33
|
localTime(key: string): number;
|
|
34
|
+
private compactingCount;
|
|
35
|
+
beginCompaction(): void;
|
|
36
|
+
endCompaction(): void;
|
|
37
|
+
isCompactingSync(): boolean;
|
|
34
38
|
private notifyOverlayMutation;
|
|
35
39
|
getKeys(): Promise<string[]>;
|
|
36
40
|
getColumn<C extends keyof T>(column: C): Promise<{
|
|
@@ -7,6 +7,7 @@ import { blue, red } from "socket-function/src/formatting/logColors";
|
|
|
7
7
|
const NULL = String.fromCharCode(0);
|
|
8
8
|
const LOAD_SIGNAL = NULL + "load";
|
|
9
9
|
const OVERLAY_SIGNAL = NULL + "overlay";
|
|
10
|
+
const COMPACTING_SIGNAL = NULL + "compacting";
|
|
10
11
|
const TRIGGER_THROTTLE_FIRST_STEP_MS = 16;
|
|
11
12
|
|
|
12
13
|
function nullJoin(a: string, b: string): string {
|
|
@@ -88,6 +89,22 @@ export class BulkDatabaseReader<T extends { key: string }> {
|
|
|
88
89
|
return -Infinity;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// Counter (so concurrent / nested merges in the same instance compose correctly). Signal fires
|
|
93
|
+
// immediately, not through the trigger throttle — UI spinners should show right away.
|
|
94
|
+
private compactingCount = 0;
|
|
95
|
+
beginCompaction(): void {
|
|
96
|
+
this.compactingCount++;
|
|
97
|
+
if (this.compactingCount === 1) this.cfg.deps.invalidate(COMPACTING_SIGNAL);
|
|
98
|
+
}
|
|
99
|
+
endCompaction(): void {
|
|
100
|
+
this.compactingCount--;
|
|
101
|
+
if (this.compactingCount === 0) this.cfg.deps.invalidate(COMPACTING_SIGNAL);
|
|
102
|
+
}
|
|
103
|
+
isCompactingSync(): boolean {
|
|
104
|
+
this.cfg.deps.observe(COMPACTING_SIGNAL);
|
|
105
|
+
return this.compactingCount > 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
91
108
|
private notifyOverlayMutation(key: string, columns: Iterable<string> | "all"): void {
|
|
92
109
|
this.dataGen++;
|
|
93
110
|
if (columns === "all") this.columnCache.clear();
|