alinea 2.0.0-preview.8 → 2.0.0-preview.9
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/.init/content/pages/welcome.json +1 -1
- package/dist/LICENSES.md +136 -136
- package/dist/adapter/next/cms.js +24 -8
- package/dist/adapter/next/handler.js +63 -10
- package/dist/adapter/next/renderStats.d.ts +25 -4
- package/dist/adapter/next/renderStats.js +71 -3
- package/dist/adapter/next/syncCheck.js +2 -8
- package/dist/adapter/next/with-alinea.js +6 -2
- package/dist/backend/HandleAction.d.ts +1 -1
- package/dist/backend/HandleAction.js +1 -1
- package/dist/backend/Handler.js +12 -35
- package/dist/backend/api/CreateBackend.js +6 -6
- package/dist/backend/api/DatabaseApi.js +2 -2
- package/dist/backend/api/ProxyMedia.d.ts +2 -3
- package/dist/backend/api/ProxyMedia.js +7 -22
- package/dist/backend/api/database.js +6 -6
- package/dist/backend/store/GeneratedDatabase.d.ts +6 -3
- package/dist/backend/store/GeneratedDatabase.js +13 -11
- package/dist/backend/store/GeneratedDatabaseNode.d.ts +1 -1
- package/dist/backend/store/GeneratedDatabaseNode.js +1 -1
- package/dist/bundled.d.ts +280 -211
- package/dist/chunks/{node-sqlite-7CSGL27V.js → bun-sqlite-5SHXN3AT.js} +3 -3
- package/dist/chunks/{chunk-IL7FJQAY.js → chunk-66YZ47TY.js} +1 -1
- package/dist/chunks/{chunk-M7KDJEGH.js → chunk-AIU6CMVT.js} +1 -1
- package/dist/chunks/{chunk-K7LHQXI4.js → chunk-ASYKC6IE.js} +1 -1
- package/dist/chunks/{chunk-RWWYUNVX.js → chunk-DWR5A5KL.js} +6 -2
- package/dist/chunks/{chunk-NLZLRQ5U.js → chunk-ETWOY4AL.js} +1 -1
- package/dist/chunks/{chunk-TFMUSWGG.js → chunk-MOWR65LM.js} +72 -67
- package/dist/chunks/{chunk-2U43BB6P.js → chunk-QJGGYF6E.js} +5 -5
- package/dist/chunks/{chunk-A42DP5T7.js → chunk-QSN6RH6X.js} +1 -1
- package/dist/chunks/{bun-sqlite-ZZDB7YQQ.js → node-sqlite-XVNTNMCY.js} +3 -3
- package/dist/cli/Serve.js +1 -1
- package/dist/cli/bin.js +6 -2
- package/dist/cli/generate/DevDB.js +4 -2
- package/dist/cli/serve/DevServer.d.ts +2 -0
- package/dist/cli/serve/DevServer.js +7 -2
- package/dist/cloud/CloudRemote.js +1 -1
- package/dist/components/Breadcrumbs.js +2 -2
- package/dist/components/Calendar.js +7 -7
- package/dist/components/Checkbox.js +3 -3
- package/dist/components/ComboBox.js +12 -12
- package/dist/components/DatePicker.js +3 -3
- package/dist/components/DateRangePicker.js +5 -5
- package/dist/components/Disclosure.js +7 -7
- package/dist/components/Label.js +5 -5
- package/dist/components/List.js +37 -37
- package/dist/components/Menu.js +2 -2
- package/dist/components/Modal.js +3 -3
- package/dist/components/MultipleSelect.js +26 -26
- package/dist/components/NumberField.js +6 -6
- package/dist/components/ProgressCircle.js +3 -3
- package/dist/components/RadioGroup.js +2 -2
- package/dist/components/SearchField.js +7 -7
- package/dist/components/Select.js +7 -7
- package/dist/components/Surface.js +2 -2
- package/dist/components/Switch.js +2 -2
- package/dist/components/Table.js +7 -7
- package/dist/components/Tabs.js +3 -3
- package/dist/components/TagGroup.js +2 -2
- package/dist/components/TextField.js +4 -4
- package/dist/components/TimeField.js +3 -3
- package/dist/components/Toggle.js +2 -2
- package/dist/components/Toolbar.js +3 -3
- package/dist/components/Tree.js +7 -7
- package/dist/core/Client.d.ts +1 -4
- package/dist/core/Client.js +5 -7
- package/dist/core/Connection.d.ts +4 -1
- package/dist/core/Connection.js +3 -1
- package/dist/core/db/LocalStore.d.ts +2 -0
- package/dist/core/source/GithubSource.js +39 -11
- package/dist/dashboard/App.js +2 -2
- package/dist/dashboard/app/AccessDenied.js +4 -4
- package/dist/dashboard/app/ActivityStatus.js +15 -15
- package/dist/dashboard/app/AuthView.js +13 -13
- package/dist/dashboard/app/Badge.js +2 -2
- package/dist/dashboard/app/CompactField.js +9 -9
- package/dist/dashboard/app/DashboardErrorBoundary.js +7 -7
- package/dist/dashboard/app/DashboardLayout.js +3 -3
- package/dist/dashboard/app/EntryFields.js +2 -2
- package/dist/dashboard/app/EntryHeader.js +10 -10
- package/dist/dashboard/app/EntryReferences.js +7 -7
- package/dist/dashboard/app/EntrySidebar.js +16 -16
- package/dist/dashboard/app/EntrySidebarPreview.js +10 -10
- package/dist/dashboard/app/EntryTranslationBanner.js +3 -3
- package/dist/dashboard/app/Explorer.js +44 -44
- package/dist/dashboard/app/ExplorerCards.js +34 -34
- package/dist/dashboard/app/ExplorerFileCard.js +21 -21
- package/dist/dashboard/app/ExplorerList.js +10 -10
- package/dist/dashboard/app/ExplorerModal.js +4 -4
- package/dist/dashboard/app/ExplorerTable.js +49 -49
- package/dist/dashboard/app/LinkPicker.js +4 -4
- package/dist/dashboard/app/LocaleMenu.js +3 -3
- package/dist/dashboard/app/SidebarTree.js +42 -42
- package/dist/dashboard/app/WorkspaceMenu.js +12 -12
- package/dist/dashboard/app/WorkspaceRoots.js +28 -28
- package/dist/dashboard/app/editor/FileEditor.js +27 -27
- package/dist/dashboard/app/editor/FilePreview.js +7 -7
- package/dist/dashboard/app/modals/CreateEntry.js +3 -3
- package/dist/dashboard/app/pages/EntryPage.js +19 -19
- package/dist/dashboard/app/pages/SplashPage.js +46 -46
- package/dist/dashboard/app/pages/UsersPage.js +36 -36
- package/dist/dashboard/app/ui/DashboardModal.js +19 -19
- package/dist/dashboard/app/ui/Rail.js +3 -3
- package/dist/dashboard/app/ui/Sidebar.js +2 -2
- package/dist/dashboard/boot/DashboardWorker.js +6 -2
- package/dist/dashboard/boot/WorkerDB.d.ts +2 -2
- package/dist/database/BrowserEntryStore.d.ts +18 -6
- package/dist/database/BrowserEntryStore.js +95 -81
- package/dist/database/DatabaseSource.d.ts +2 -2
- package/dist/database/DatabaseTables.js +2 -2
- package/dist/database/EntryDatabase.d.ts +83 -7
- package/dist/database/EntryDatabase.js +420 -30
- package/dist/database/EntryStore.d.ts +10 -12
- package/dist/database/EntryStore.js +27 -66
- package/dist/database/EntryTransaction.d.ts +3 -3
- package/dist/database/EntryTransaction.js +39 -21
- package/dist/database/Version.d.ts +2 -2
- package/dist/database/Version.js +1 -1
- package/dist/database/driver/DatabaseHandle.d.ts +17 -0
- package/dist/database/driver/DatabaseHandle.js +0 -0
- package/dist/database/driver/OverlayExtension.browser.d.ts +2 -0
- package/dist/database/driver/OverlayExtension.browser.js +9 -0
- package/dist/database/driver/OverlayExtension.d.ts +1 -0
- package/dist/database/driver/OverlayExtension.js +7 -0
- package/dist/database/driver/RuntimeDatabase.d.ts +11 -6
- package/dist/database/driver/RuntimeDatabase.js +66 -22
- package/dist/database/driver/WasmDatabase.d.ts +23 -2
- package/dist/database/driver/WasmDatabase.js +22 -9
- package/dist/database/entry/EntryTable.d.ts +21 -5
- package/dist/database/entry/EntryTable.js +59 -10
- package/dist/database/query/EntryQuery.d.ts +3 -2
- package/dist/database/query/EntryQuery.js +23 -25
- package/dist/database/query/EntryReferences.d.ts +2 -3
- package/dist/database/query/EntryReferences.js +43 -41
- package/dist/database/query/Relation.js +1 -1
- package/dist/database/query/ResolveQuery.d.ts +1 -4
- package/dist/database/query/ResolveQuery.js +54 -19
- package/dist/database/query/Search.d.ts +8 -17
- package/dist/database/query/Search.js +17 -37
- package/dist/database/sync/EntryParser.d.ts +5 -1
- package/dist/database/sync/EntryParser.js +4 -1
- package/dist/database/sync/EntrySyncer.d.ts +7 -19
- package/dist/database/sync/EntrySyncer.js +17 -45
- package/dist/database/sync/Ingest.js +40 -31
- package/dist/database/sync/SyncQueries.d.ts +5 -2
- package/dist/database/sync/SyncQueries.js +27 -3
- package/dist/field/check/CheckField.view.js +2 -2
- package/dist/field/code/CodeField.view.js +11 -11
- package/dist/field/link/LinkField.view.js +34 -34
- package/dist/field/list/ListField.view.js +17 -17
- package/dist/field/metadata/MetadataField.view.js +15 -15
- package/dist/field/richtext/RichTextBlock.js +2 -2
- package/dist/field/richtext/RichTextExtensions.js +23 -23
- package/dist/field/richtext/RichTextField.view.js +2 -2
- package/dist/field/richtext/RichTextInsertMenu.js +2 -2
- package/dist/next.cjs +6 -2
- package/dist/preview/widget.d.ts +29 -0
- package/dist/preview/widget.js +31 -5
- package/package.json +6 -2
- package/dist/adapter/next/DevRemote.d.ts +0 -3
- package/dist/adapter/next/DevRemote.js +0 -45
- package/dist/database/EntryLayer.d.ts +0 -93
- package/dist/database/EntryLayer.js +0 -459
- package/dist/database/entry/EntryView.d.ts +0 -22
- package/dist/database/entry/EntryView.js +0 -106
package/dist/bundled.d.ts
CHANGED
|
@@ -93,14 +93,6 @@ declare module 'alinea/adapter/next/context' {
|
|
|
93
93
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
declare module 'alinea/adapter/next/DevRemote' {
|
|
97
|
-
|
|
98
|
-
import type { RemoteConnection, RequestContext } from 'alinea/core/Connection';
|
|
99
|
-
import type { Config } from 'alinea/core/Config';
|
|
100
|
-
export function createDevRemote(context: RequestContext, config: Config): RemoteConnection;
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
96
|
declare module 'alinea/adapter/next/ForwardCredentials' {
|
|
105
97
|
|
|
106
98
|
export function forwardDevelopmentCredentials(request: Request | undefined, apiKey: string, init?: RequestInit): RequestInit;
|
|
@@ -167,16 +159,32 @@ declare module 'alinea/adapter/next/previews.spec' {
|
|
|
167
159
|
declare module 'alinea/adapter/next/renderStats' {
|
|
168
160
|
|
|
169
161
|
import type { GraphQuery } from 'alinea/core/Graph';
|
|
170
|
-
import type { PreviewStat, PreviewStats } from 'alinea/preview/widget';
|
|
162
|
+
import type { PreviewDatabase, PreviewStat, PreviewStatement, PreviewStats } from 'alinea/preview/widget';
|
|
171
163
|
/** Collects the CMS queries and syncs of one draft render. */
|
|
172
164
|
export class RenderStats {
|
|
173
165
|
#private;
|
|
174
166
|
rows: Array<PreviewStat>;
|
|
175
167
|
statements: number;
|
|
176
168
|
sqlMs: number;
|
|
169
|
+
slowest: Array<PreviewStatement>;
|
|
170
|
+
/** The bundled database that answered, once a query reached it. */
|
|
171
|
+
database?: PreviewDatabase;
|
|
172
|
+
readonly startedAt: number;
|
|
177
173
|
/** Add a row and count it as pending until `run` settles; see `timed`. */
|
|
178
174
|
track<T>(stat: Omit<PreviewStat, 'durationMs'>, run: (row: PreviewStat) => Promise<T>): Promise<T>;
|
|
179
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Time a database query without the time it waited behind the others:
|
|
177
|
+
* queries of a render run one at a time in the order they were called, so
|
|
178
|
+
* one starts executing once the previous one finished, or when it was
|
|
179
|
+
* called if that is later.
|
|
180
|
+
*/
|
|
181
|
+
executed<T>(row: PreviewStat, run: () => Promise<T>): Promise<T>;
|
|
182
|
+
/**
|
|
183
|
+
* Count a statement towards the render, and towards the row that ran it:
|
|
184
|
+
* a sync in progress, or else the query executing, which is the earliest
|
|
185
|
+
* one called that has not finished (see `executed`).
|
|
186
|
+
*/
|
|
187
|
+
statement(durationMs: number, sql?: string): void;
|
|
180
188
|
/**
|
|
181
189
|
* Resolves once nothing ran for `quietMs`, so queries of server components
|
|
182
190
|
* that render after the caller are counted, or after `maxMs` regardless.
|
|
@@ -184,8 +192,13 @@ declare module 'alinea/adapter/next/renderStats' {
|
|
|
184
192
|
settled(quietMs?: number, maxMs?: number): Promise<PreviewStats>;
|
|
185
193
|
}
|
|
186
194
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
195
|
+
* A statement short enough to read in a table, such as
|
|
196
|
+
* `select … from alinea_entry_index where (visible = ? and id in (?))`.
|
|
197
|
+
*/
|
|
198
|
+
export function summarizeSql(sql: string, maxLength?: number): string;
|
|
199
|
+
/**
|
|
200
|
+
* Time the work a row stands for from call to answer, such as a sync or a
|
|
201
|
+
* query the handler answers, without the sync it waited for.
|
|
189
202
|
*/
|
|
190
203
|
export function timed<T>(row: PreviewStat | undefined, run: () => Promise<T>): Promise<T>;
|
|
191
204
|
/** A short description such as `first(type, url=/about)`. */
|
|
@@ -422,9 +435,8 @@ declare module 'alinea/backend/api/OAuth2' {
|
|
|
422
435
|
|
|
423
436
|
declare module 'alinea/backend/api/ProxyMedia' {
|
|
424
437
|
|
|
425
|
-
import { type Request
|
|
426
|
-
export function proxyMediaUrl(request: Request, source: URL
|
|
427
|
-
export function isRedirectStatus(status: number): boolean;
|
|
438
|
+
import { type Request } from '@alinea/iso';
|
|
439
|
+
export function proxyMediaUrl(request: Request, source: URL): Promise<Response>;
|
|
428
440
|
|
|
429
441
|
}
|
|
430
442
|
|
|
@@ -562,7 +574,7 @@ declare module 'alinea/backend/HandleAction' {
|
|
|
562
574
|
Mutate = "mutate",
|
|
563
575
|
Upload = "upload",
|
|
564
576
|
Tree = "tree",
|
|
565
|
-
|
|
577
|
+
Sha = "sha",
|
|
566
578
|
Blob = "blob"
|
|
567
579
|
}
|
|
568
580
|
|
|
@@ -806,10 +818,13 @@ declare module 'alinea/backend/router/Router' {
|
|
|
806
818
|
declare module 'alinea/backend/store/GeneratedDatabase' {
|
|
807
819
|
|
|
808
820
|
import type { Config } from 'alinea/core/Config';
|
|
821
|
+
import type { DatabaseHandle } from 'alinea/database/driver/DatabaseHandle';
|
|
809
822
|
import { EntryStore } from 'alinea/database/EntryStore';
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
823
|
+
/**
|
|
824
|
+
* Serve a generated database from a connection that keeps its writes in
|
|
825
|
+
* memory, so syncs and commits never reach the generated file.
|
|
826
|
+
*/
|
|
827
|
+
export function createGeneratedDatabase(config: Config, { database: db, fork, driver }: DatabaseHandle): Promise<EntryStore>;
|
|
813
828
|
|
|
814
829
|
}
|
|
815
830
|
|
|
@@ -817,7 +832,7 @@ declare module 'alinea/backend/store/GeneratedDatabaseNode' {
|
|
|
817
832
|
|
|
818
833
|
import type { Config } from 'alinea/core/Config';
|
|
819
834
|
import type { DatabaseOptions } from 'rado';
|
|
820
|
-
/** Open the traced generated file
|
|
835
|
+
/** Open the traced generated file as an in-memory overlay. */
|
|
821
836
|
export function generatedDatabase(config: Config, options?: DatabaseOptions): Promise<import("alinea/database/EntryStore").EntryStore>;
|
|
822
837
|
|
|
823
838
|
}
|
|
@@ -1080,6 +1095,7 @@ declare module 'alinea/cli/serve/CreateLocalServer' {
|
|
|
1080
1095
|
|
|
1081
1096
|
declare module 'alinea/cli/serve/DevServer' {
|
|
1082
1097
|
|
|
1098
|
+
import type { CMS } from 'alinea/core/CMS';
|
|
1083
1099
|
import { Config } from 'alinea/core/Config';
|
|
1084
1100
|
import { Request, type Response } from '@alinea/iso';
|
|
1085
1101
|
import type { BuildOptions } from 'esbuild';
|
|
@@ -1100,6 +1116,7 @@ declare module 'alinea/cli/serve/DevServer' {
|
|
|
1100
1116
|
handle(input: Request): Promise<Response>;
|
|
1101
1117
|
}
|
|
1102
1118
|
export function createDevServer(dir: string, options: CreateDevServerOptions): Promise<DevServer>;
|
|
1119
|
+
export function forwardMutation(request: Request, cms: CMS, apiKey: string): Promise<Response | undefined>;
|
|
1103
1120
|
|
|
1104
1121
|
}
|
|
1105
1122
|
|
|
@@ -2209,7 +2226,6 @@ declare module 'alinea/core/Client' {
|
|
|
2209
2226
|
import { type AuthResult } from 'alinea/cloud/AuthResult';
|
|
2210
2227
|
import type { Config } from 'alinea/core/Config';
|
|
2211
2228
|
import type { BackendCapabilities, LocalConnection, Revision, UploadMetadata, UploadResponse } from 'alinea/core/Connection';
|
|
2212
|
-
import type { CommitRequest } from 'alinea/core/db/CommitRequest';
|
|
2213
2229
|
import type { Mutation } from 'alinea/core/db/Mutation';
|
|
2214
2230
|
import type { Draft, DraftKey } from 'alinea/core/Draft';
|
|
2215
2231
|
import type { EntryRecord } from 'alinea/core/EntryRecord';
|
|
@@ -2246,10 +2262,8 @@ declare module 'alinea/core/Client' {
|
|
|
2246
2262
|
revisions(file: string): Promise<Array<Revision>>;
|
|
2247
2263
|
revisionData(file: string, revisionId: string): Promise<EntryRecord | undefined>;
|
|
2248
2264
|
getTreeIfDifferent(sha: string): Promise<ReadonlyTree | undefined>;
|
|
2265
|
+
getSha(): Promise<string>;
|
|
2249
2266
|
getBlobs(shas: ReadonlyArray<string>, options?: GetBlobsOptions): AsyncGenerator<[sha: string, blob: Uint8Array]>;
|
|
2250
|
-
write(request: CommitRequest): Promise<{
|
|
2251
|
-
sha: string;
|
|
2252
|
-
}>;
|
|
2253
2267
|
getDraft(key: DraftKey): Promise<Draft | undefined>;
|
|
2254
2268
|
storeDraft(draft: Draft): Promise<void>;
|
|
2255
2269
|
}
|
|
@@ -2383,7 +2397,8 @@ declare module 'alinea/core/Connection' {
|
|
|
2383
2397
|
export interface BrowserConnection extends Connection {
|
|
2384
2398
|
logout?(): Promise<void>;
|
|
2385
2399
|
}
|
|
2386
|
-
|
|
2400
|
+
/** A handler seen from the dashboard or an app: it commits by mutating. */
|
|
2401
|
+
export interface LocalConnection extends SyncApi, HistoryApi, DraftsApi, UploadsApi, UserApi, CapabilitiesApi {
|
|
2387
2402
|
mutate(mutations: Array<Mutation>): Promise<{
|
|
2388
2403
|
sha: string;
|
|
2389
2404
|
}>;
|
|
@@ -2422,6 +2437,8 @@ declare module 'alinea/core/Connection' {
|
|
|
2422
2437
|
applyAuth?(init?: RequestInit): RequestInit;
|
|
2423
2438
|
}
|
|
2424
2439
|
export const developmentKeyHeader = "x-alinea-dev-key";
|
|
2440
|
+
/** Marks a mutation an app sends back to the dev server after its hooks ran. */
|
|
2441
|
+
export const forwardedMutationHeader = "x-alinea-forwarded";
|
|
2425
2442
|
export interface AuthedContext extends RequestContext {
|
|
2426
2443
|
user: User;
|
|
2427
2444
|
token: string;
|
|
@@ -2614,6 +2631,8 @@ declare module 'alinea/core/db/LocalStore' {
|
|
|
2614
2631
|
*/
|
|
2615
2632
|
export interface LocalStore extends WriteableGraph, RemoteSource {
|
|
2616
2633
|
source: Source;
|
|
2634
|
+
/** How the store reads its database, when it is a SQLite connection. */
|
|
2635
|
+
driver?: 'native' | 'overlay' | 'wasm';
|
|
2617
2636
|
sha: string | Promise<string>;
|
|
2618
2637
|
sync(): Promise<string>;
|
|
2619
2638
|
syncWith(remote: RemoteSource, options?: SyncOptions): Promise<string>;
|
|
@@ -8038,7 +8057,7 @@ declare module 'alinea/dashboard/boot/LoadWorker' {
|
|
|
8038
8057
|
declare module 'alinea/dashboard/boot/WorkerDB' {
|
|
8039
8058
|
|
|
8040
8059
|
import type { Config } from 'alinea/core/Config';
|
|
8041
|
-
import type {
|
|
8060
|
+
import type { LocalConnection, UploadMetadata, UploadResponse } from 'alinea/core/Connection';
|
|
8042
8061
|
import type { AnyQueryResult, GraphQuery } from 'alinea/core/Graph';
|
|
8043
8062
|
import type { EntryReferenceQuery, EntryReferenceResult } from 'alinea/core/db/EntryReference';
|
|
8044
8063
|
import type { Mutation } from 'alinea/core/db/Mutation';
|
|
@@ -8049,7 +8068,7 @@ declare module 'alinea/dashboard/boot/WorkerDB' {
|
|
|
8049
8068
|
#private;
|
|
8050
8069
|
config: Config;
|
|
8051
8070
|
events: EventTarget;
|
|
8052
|
-
constructor(config: Config, worker: DashboardWorker, client:
|
|
8071
|
+
constructor(config: Config, worker: DashboardWorker, client: LocalConnection, events: EventTarget);
|
|
8053
8072
|
mutate(mutations: Array<Mutation>): Promise<{
|
|
8054
8073
|
id: string;
|
|
8055
8074
|
sha: string;
|
|
@@ -8727,14 +8746,25 @@ declare module 'alinea/database/BrowserEntryStore' {
|
|
|
8727
8746
|
import type { RemoteSource } from 'alinea/core/source/Source';
|
|
8728
8747
|
import { EntryStore } from 'alinea/database/EntryStore';
|
|
8729
8748
|
export interface BrowserEntryStoreOptions {
|
|
8730
|
-
indexedDB: IDBFactory;
|
|
8731
8749
|
name: string;
|
|
8732
8750
|
revision: string;
|
|
8751
|
+
/**
|
|
8752
|
+
* The store this one replaces, such as one of a previous dashboard build:
|
|
8753
|
+
* its content carries over from memory instead of loading it again, and it
|
|
8754
|
+
* stops storing without waiting for its work in flight.
|
|
8755
|
+
*/
|
|
8756
|
+
replaces?: BrowserEntryStore;
|
|
8757
|
+
/** The IndexedDB implementation, the global one by default. */
|
|
8758
|
+
indexedDB?: IDBFactory;
|
|
8759
|
+
IDBKeyRange?: typeof IDBKeyRange;
|
|
8733
8760
|
}
|
|
8734
|
-
/**
|
|
8761
|
+
/**
|
|
8762
|
+
* WASM entry store kept in IndexedDB: every commit stores the pages it
|
|
8763
|
+
* changed.
|
|
8764
|
+
*/
|
|
8735
8765
|
export class BrowserEntryStore extends EntryStore {
|
|
8736
8766
|
#private;
|
|
8737
|
-
static open(config: Config, options: BrowserEntryStoreOptions): Promise<BrowserEntryStore>;
|
|
8767
|
+
static open(config: Config, options: BrowserEntryStoreOptions, retried?: boolean): Promise<BrowserEntryStore>;
|
|
8738
8768
|
private constructor();
|
|
8739
8769
|
sync(): Promise<string>;
|
|
8740
8770
|
syncWith(remote: RemoteSource, options?: SyncOptions): Promise<string>;
|
|
@@ -8745,9 +8775,10 @@ declare module 'alinea/database/BrowserEntryStore' {
|
|
|
8745
8775
|
sha: string;
|
|
8746
8776
|
}>;
|
|
8747
8777
|
close(): Promise<void>;
|
|
8748
|
-
/**
|
|
8749
|
-
*
|
|
8750
|
-
*
|
|
8778
|
+
/**
|
|
8779
|
+
* Close a store that a replacement took over from: its work in flight
|
|
8780
|
+
* changes only its memory copy, which is not stored.
|
|
8781
|
+
*/
|
|
8751
8782
|
abandon(): Promise<void>;
|
|
8752
8783
|
}
|
|
8753
8784
|
|
|
@@ -8758,11 +8789,11 @@ declare module 'alinea/database/DatabaseSource' {
|
|
|
8758
8789
|
import type { ChangesBatch } from 'alinea/core/source/Change';
|
|
8759
8790
|
import type { GetBlobsOptions, Source } from 'alinea/core/source/Source';
|
|
8760
8791
|
import type { ReadonlyTree } from 'alinea/core/source/Tree';
|
|
8761
|
-
import type {
|
|
8792
|
+
import type { EntryDatabase } from 'alinea/database/EntryDatabase';
|
|
8762
8793
|
/** Read-only Source view backed by exact payload text in an entry database. */
|
|
8763
8794
|
export class DatabaseSource implements Source {
|
|
8764
8795
|
#private;
|
|
8765
|
-
constructor(database:
|
|
8796
|
+
constructor(database: EntryDatabase);
|
|
8766
8797
|
getTree(): Promise<ReadonlyTree>;
|
|
8767
8798
|
getTreeIfDifferent(sha: string): Promise<ReadonlyTree | undefined>;
|
|
8768
8799
|
getBlobs(shas: ReadonlyArray<string>, options?: GetBlobsOptions): AsyncGenerator<[sha: string, blob: Uint8Array<ArrayBufferLike>], any, any>;
|
|
@@ -8814,28 +8845,89 @@ declare module 'alinea/database/DatabaseTables' {
|
|
|
8814
8845
|
|
|
8815
8846
|
}
|
|
8816
8847
|
|
|
8848
|
+
declare module 'alinea/database/driver/DatabaseHandle' {
|
|
8849
|
+
|
|
8850
|
+
import type { Database } from 'rado';
|
|
8851
|
+
/**
|
|
8852
|
+
* How a connection reads its data: a native file, a native in-memory overlay
|
|
8853
|
+
* of a file, or a copy in WASM memory.
|
|
8854
|
+
*/
|
|
8855
|
+
export type DatabaseDriver = 'native' | 'overlay' | 'wasm';
|
|
8856
|
+
/** A SQLite connection, which may copy itself without copying its data. */
|
|
8857
|
+
export interface DatabaseHandle {
|
|
8858
|
+
database: Database;
|
|
8859
|
+
driver?: DatabaseDriver;
|
|
8860
|
+
/**
|
|
8861
|
+
* An independent connection to the last committed state. The copy shares
|
|
8862
|
+
* every page with this one until either side writes it. Connections that
|
|
8863
|
+
* write a file in place cannot fork.
|
|
8864
|
+
*/
|
|
8865
|
+
fork?(): Promise<DatabaseHandle>;
|
|
8866
|
+
}
|
|
8867
|
+
|
|
8868
|
+
}
|
|
8869
|
+
|
|
8870
|
+
declare module 'alinea/database/driver/OverlayExtension.browser' {
|
|
8871
|
+
|
|
8872
|
+
/** Browser bundles reach the database driver without ever running it. */
|
|
8873
|
+
export function overlayExtension(): string;
|
|
8874
|
+
|
|
8875
|
+
}
|
|
8876
|
+
|
|
8877
|
+
declare module 'alinea/database/driver/OverlayExtension' {
|
|
8878
|
+
|
|
8879
|
+
export { overlayExtension } from '@alinea/sqlite-wasm/native';
|
|
8880
|
+
|
|
8881
|
+
}
|
|
8882
|
+
|
|
8817
8883
|
declare module 'alinea/database/driver/RuntimeDatabase' {
|
|
8818
8884
|
|
|
8819
|
-
import type {
|
|
8885
|
+
import type { DatabaseOptions } from 'rado';
|
|
8886
|
+
import type { DatabaseHandle } from 'alinea/database/driver/DatabaseHandle';
|
|
8820
8887
|
export interface RuntimeDatabaseOptions extends DatabaseOptions {
|
|
8821
|
-
path
|
|
8822
|
-
|
|
8823
|
-
|
|
8888
|
+
path: string;
|
|
8889
|
+
/** Keep every write in memory: the file is never written. */
|
|
8890
|
+
overlay?: boolean;
|
|
8824
8891
|
}
|
|
8825
|
-
/**
|
|
8826
|
-
|
|
8892
|
+
/**
|
|
8893
|
+
* Open a SQLite file with the native Node/Bun driver. Overlays of the file
|
|
8894
|
+
* keep their writes in memory and fork cheaply, through the native overlay
|
|
8895
|
+
* VFS or else a WASM copy; a file opened for writing cannot fork.
|
|
8896
|
+
*/
|
|
8897
|
+
export function runtimeDatabase(options: RuntimeDatabaseOptions): Promise<DatabaseHandle>;
|
|
8827
8898
|
|
|
8828
8899
|
}
|
|
8829
8900
|
|
|
8830
8901
|
declare module 'alinea/database/driver/WasmDatabase' {
|
|
8831
8902
|
|
|
8903
|
+
import type { Storage } from '@alinea/sqlite-wasm/Database.js';
|
|
8904
|
+
import type { DatabaseOptions } from 'rado';
|
|
8832
8905
|
import { connect } from 'rado/driver/sql.js';
|
|
8833
|
-
|
|
8906
|
+
import type { DatabaseHandle } from 'alinea/database/driver/DatabaseHandle';
|
|
8907
|
+
export interface WasmDatabaseHandle extends DatabaseHandle {
|
|
8834
8908
|
database: ReturnType<typeof connect>;
|
|
8909
|
+
fork(): Promise<WasmDatabaseHandle>;
|
|
8835
8910
|
export(): Uint8Array;
|
|
8911
|
+
/** Resolves once every commit so far is stored; at once in memory. */
|
|
8912
|
+
flush(): Promise<void>;
|
|
8913
|
+
/**
|
|
8914
|
+
* Store this database from now on, replacing what the storage held, once
|
|
8915
|
+
* a database detached from it wrote its last commits.
|
|
8916
|
+
*/
|
|
8917
|
+
attach(storage: Storage): Promise<void>;
|
|
8918
|
+
/**
|
|
8919
|
+
* Stop storing commits once the ones so far are written; later commits
|
|
8920
|
+
* change only the memory copy.
|
|
8921
|
+
*/
|
|
8922
|
+
detach(): void;
|
|
8836
8923
|
}
|
|
8924
|
+
/**
|
|
8925
|
+
* Open a WASM connection from the database kept in storage, or an empty one,
|
|
8926
|
+
* that stores every commit there.
|
|
8927
|
+
*/
|
|
8928
|
+
export function syncWasmDatabase(storage: Storage, options?: DatabaseOptions): Promise<WasmDatabaseHandle>;
|
|
8837
8929
|
/** Open an in-memory WASM connection, optionally from a complete SQLite file. */
|
|
8838
|
-
export function openWasmDatabase(data?: Uint8Array): Promise<WasmDatabaseHandle>;
|
|
8930
|
+
export function openWasmDatabase(data?: Uint8Array, options?: DatabaseOptions): Promise<WasmDatabaseHandle>;
|
|
8839
8931
|
export function wasmDatabase(data?: Uint8Array): Promise<import("rado").SyncDatabase<"sqlite">>;
|
|
8840
8932
|
|
|
8841
8933
|
}
|
|
@@ -8860,13 +8952,14 @@ declare module 'alinea/database/entry/EntryData' {
|
|
|
8860
8952
|
|
|
8861
8953
|
declare module 'alinea/database/entry/EntryTable' {
|
|
8862
8954
|
|
|
8955
|
+
import type { Config } from 'alinea/core/Config';
|
|
8863
8956
|
import type { Entry, EntryStatus } from 'alinea/core/Entry';
|
|
8864
|
-
import { type Table } from 'rado';
|
|
8957
|
+
import { type Database, type Table } from 'rado';
|
|
8865
8958
|
/** One complete authored entry version. Only arrays and authored data are JSON. */
|
|
8866
8959
|
export const EntryIndexColumns: {
|
|
8867
8960
|
/**
|
|
8868
8961
|
* Also the rowid of the version's full-text search row. Declared, so VACUUM
|
|
8869
|
-
*
|
|
8962
|
+
* keeps it.
|
|
8870
8963
|
*/
|
|
8871
8964
|
rowid: import("rado").Column<number, [false, false]>;
|
|
8872
8965
|
versionId: import("rado").Column<string, [false, boolean]>;
|
|
@@ -8905,10 +8998,10 @@ declare module 'alinea/database/entry/EntryTable' {
|
|
|
8905
8998
|
*/
|
|
8906
8999
|
data: import("rado").Column<string, [false, boolean]>;
|
|
8907
9000
|
};
|
|
8908
|
-
export function entryIndexTable(name: string
|
|
9001
|
+
export function entryIndexTable(name: string): Table<{
|
|
8909
9002
|
/**
|
|
8910
9003
|
* Also the rowid of the version's full-text search row. Declared, so VACUUM
|
|
8911
|
-
*
|
|
9004
|
+
* keeps it.
|
|
8912
9005
|
*/
|
|
8913
9006
|
rowid: import("rado").Column<number, [false, false]>;
|
|
8914
9007
|
versionId: import("rado").Column<string, [false, boolean]>;
|
|
@@ -8951,7 +9044,7 @@ declare module 'alinea/database/entry/EntryTable' {
|
|
|
8951
9044
|
export const EntryIndexTable: Table<{
|
|
8952
9045
|
/**
|
|
8953
9046
|
* Also the rowid of the version's full-text search row. Declared, so VACUUM
|
|
8954
|
-
*
|
|
9047
|
+
* keeps it.
|
|
8955
9048
|
*/
|
|
8956
9049
|
rowid: import("rado").Column<number, [false, false]>;
|
|
8957
9050
|
versionId: import("rado").Column<string, [false, boolean]>;
|
|
@@ -8990,6 +9083,21 @@ declare module 'alinea/database/entry/EntryTable' {
|
|
|
8990
9083
|
*/
|
|
8991
9084
|
data: import("rado").Column<string, [false, boolean]>;
|
|
8992
9085
|
}, string>;
|
|
9086
|
+
/** The entry ids each entry version references, under the version's rowid. */
|
|
9087
|
+
export const EntryReferenceTable: Table<{
|
|
9088
|
+
targetId: import("rado").Column<string, [false, boolean]>;
|
|
9089
|
+
source: import("rado").Column<number, [false, boolean]>;
|
|
9090
|
+
}, "alinea_entry_reference">;
|
|
9091
|
+
/** Fields whose queries order by their stored value, through a field index. */
|
|
9092
|
+
export function isOrderedField(field: unknown): boolean;
|
|
9093
|
+
/** Metadata fields whose queries order by their stored value. */
|
|
9094
|
+
export const orderedMetadata: Set<string>;
|
|
9095
|
+
/**
|
|
9096
|
+
* Index the stored value of every ordered field in the config, per type, and
|
|
9097
|
+
* of the ordered metadata. Field names are identifiers, so the dotted metadata
|
|
9098
|
+
* names cannot collide with them.
|
|
9099
|
+
*/
|
|
9100
|
+
export function syncFieldIndexes(db: Database, config: Config): Promise<void>;
|
|
8993
9101
|
/** An Entry plus the physical-version and local-index fields. */
|
|
8994
9102
|
export interface IndexedEntry extends Entry {
|
|
8995
9103
|
versionStatus: EntryStatus;
|
|
@@ -9036,93 +9144,29 @@ declare module 'alinea/database/entry/EntryTable' {
|
|
|
9036
9144
|
|
|
9037
9145
|
}
|
|
9038
9146
|
|
|
9039
|
-
declare module 'alinea/database/entry/EntryView' {
|
|
9040
|
-
|
|
9041
|
-
import { type Database } from 'rado';
|
|
9042
|
-
import type { EntrySyncTarget } from 'alinea/database/sync/EntrySyncer';
|
|
9043
|
-
/** The tables reads of a target go to: an unwritten view reads its parent's. */
|
|
9044
|
-
export function entryReadTarget(target: EntrySyncTarget): EntrySyncTarget;
|
|
9045
|
-
/**
|
|
9046
|
-
* Named, copy-on-write entry and search tables over another target. A view
|
|
9047
|
-
* reads its parent until the first write copies the parent's rows into
|
|
9048
|
-
* temporary tables of its own, which from then on no longer follow the parent.
|
|
9049
|
-
*/
|
|
9050
|
-
export class EntryView {
|
|
9051
|
-
#private;
|
|
9052
|
-
readonly target: EntrySyncTarget;
|
|
9053
|
-
private constructor();
|
|
9054
|
-
static create(db: Database, name: string, parent: EntrySyncTarget, revision: string): Promise<EntryView>;
|
|
9055
|
-
get readTarget(): EntrySyncTarget;
|
|
9056
|
-
/**
|
|
9057
|
-
* Copy the parent's rows into this view's tables. Await this before every
|
|
9058
|
-
* write through the view: until then reads go to the parent.
|
|
9059
|
-
*/
|
|
9060
|
-
diverge(): Promise<void>;
|
|
9061
|
-
close(): Promise<void>;
|
|
9062
|
-
}
|
|
9063
|
-
|
|
9064
|
-
}
|
|
9065
|
-
|
|
9066
9147
|
declare module 'alinea/database/EntryDatabase' {
|
|
9067
9148
|
|
|
9068
|
-
import type { Config } from 'alinea/core/Config';
|
|
9069
|
-
import type { FileStat } from 'alinea/core/source/FSSource';
|
|
9070
|
-
import { type Database } from 'rado';
|
|
9071
|
-
import { EntryLayer, type EntryDatabaseOptions, type EntrySyncResult } from 'alinea/database/EntryLayer';
|
|
9072
|
-
/** A queryable entry database owning its SQLite connection. */
|
|
9073
|
-
export class EntryDatabase extends EntryLayer {
|
|
9074
|
-
#private;
|
|
9075
|
-
constructor(config: Config, db: Database, options?: EntryDatabaseOptions);
|
|
9076
|
-
static createSchema(db: Database, revision: string, configFingerprint?: string): Promise<void>;
|
|
9077
|
-
/**
|
|
9078
|
-
* Derive every entry again with another config, recording the fingerprint
|
|
9079
|
-
* so a later open recognizes the database as written by that config.
|
|
9080
|
-
*/
|
|
9081
|
-
reindex(config: Config, configFingerprint?: string): Promise<EntrySyncResult>;
|
|
9082
|
-
/** File stats recorded by the last filesystem sync of this database. */
|
|
9083
|
-
getSourceFileStats(): Promise<Map<string, FileStat>>;
|
|
9084
|
-
/** Replace the recorded file stats after syncing from a filesystem source. */
|
|
9085
|
-
setSourceFileStats(stats: ReadonlyMap<string, FileStat>): Promise<void>;
|
|
9086
|
-
compact(): Promise<void>;
|
|
9087
|
-
protected releaseLayer(): Promise<void>;
|
|
9088
|
-
}
|
|
9089
|
-
|
|
9090
|
-
}
|
|
9091
|
-
|
|
9092
|
-
declare module 'alinea/database/EntryLayer' {
|
|
9093
|
-
|
|
9094
9149
|
import type { Config } from 'alinea/core/Config';
|
|
9095
9150
|
import type { CommitRequest } from 'alinea/core/db/CommitRequest';
|
|
9096
9151
|
import type { EntryReferenceQuery, EntryReferenceResult } from 'alinea/core/db/EntryReference';
|
|
9097
|
-
import type { Mutation } from 'alinea/core/db/Mutation';
|
|
9098
9152
|
import type { SyncOptions } from 'alinea/core/db/LocalStore';
|
|
9153
|
+
import type { Mutation } from 'alinea/core/db/Mutation';
|
|
9099
9154
|
import { Graph, type AnyQueryResult, type GraphQuery } from 'alinea/core/Graph';
|
|
9100
9155
|
import { Policy } from 'alinea/core/Role';
|
|
9101
|
-
import {
|
|
9156
|
+
import type { FileStat } from 'alinea/core/source/FSSource';
|
|
9102
9157
|
import { type GetBlobsOptions, type RemoteSource, type Source } from 'alinea/core/source/Source';
|
|
9103
9158
|
import { ReadonlyTree } from 'alinea/core/source/Tree';
|
|
9104
|
-
import { TaskQueue } from 'alinea/core/util/Async';
|
|
9105
9159
|
import { type Database } from 'rado';
|
|
9106
|
-
import {
|
|
9107
|
-
import { EntrySyncer, type EntrySyncTarget } from 'alinea/database/sync/EntrySyncer';
|
|
9108
|
-
export interface EntryLayerState {
|
|
9109
|
-
/** Read connection, or the write transaction of a working layer. */
|
|
9110
|
-
db: Database;
|
|
9111
|
-
/** Serializes every task on the connection, shared by its overlays. */
|
|
9112
|
-
queue: TaskQueue;
|
|
9113
|
-
syncer: EntrySyncer;
|
|
9114
|
-
target: EntrySyncTarget;
|
|
9115
|
-
/** The copy-on-write table behind an overlay's target. */
|
|
9116
|
-
view?: EntryView;
|
|
9117
|
-
/** The layer an overlay was created from. */
|
|
9118
|
-
parent?: EntryLayer;
|
|
9119
|
-
tree?: ReadonlyTree;
|
|
9120
|
-
initialTree?: ReadonlyTree;
|
|
9121
|
-
/** The connection is already inside a transaction: never open nested ones. */
|
|
9122
|
-
transactional?: boolean;
|
|
9123
|
-
}
|
|
9160
|
+
import type { DatabaseHandle } from 'alinea/database/driver/DatabaseHandle';
|
|
9124
9161
|
export interface EntryDatabaseOptions {
|
|
9125
9162
|
includedAtBuild?(filePath: string): boolean | Promise<boolean>;
|
|
9163
|
+
/** Copy the connection for an overlay; without it there are none. */
|
|
9164
|
+
fork?(): Promise<DatabaseHandle>;
|
|
9165
|
+
/**
|
|
9166
|
+
* Whether syncs record the source tree in the state, so the database can be
|
|
9167
|
+
* reopened and synced from it. An overlay keeps its tree in memory.
|
|
9168
|
+
*/
|
|
9169
|
+
recordsTree?: boolean;
|
|
9126
9170
|
}
|
|
9127
9171
|
export interface EntryApplyOptions {
|
|
9128
9172
|
source: Source;
|
|
@@ -9137,52 +9181,67 @@ declare module 'alinea/database/EntryLayer' {
|
|
|
9137
9181
|
export interface EntryApplyResult extends EntrySyncResult {
|
|
9138
9182
|
request: CommitRequest;
|
|
9139
9183
|
}
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
/** One queryable layer of the entry index: a database or a view over one. */
|
|
9146
|
-
export class EntryLayer extends Graph implements AsyncDisposable {
|
|
9184
|
+
/**
|
|
9185
|
+
* A queryable entry index owning its SQLite connection. Mutations are planned
|
|
9186
|
+
* on a working copy inside a write transaction of that connection.
|
|
9187
|
+
*/
|
|
9188
|
+
export class EntryDatabase extends Graph implements AsyncDisposable {
|
|
9147
9189
|
#private;
|
|
9148
|
-
constructor(config: Config,
|
|
9190
|
+
constructor(config: Config, db: Database, options?: EntryDatabaseOptions);
|
|
9149
9191
|
get config(): Config;
|
|
9192
|
+
/** Whether this database can create overlays. */
|
|
9193
|
+
get forkable(): boolean;
|
|
9150
9194
|
includedAtBuild(filePath: string): boolean | Promise<boolean>;
|
|
9151
|
-
/** Whether this
|
|
9195
|
+
/** Whether this database was closed, and answers only from a replacement. */
|
|
9152
9196
|
get closed(): boolean;
|
|
9153
9197
|
/**
|
|
9154
|
-
*
|
|
9155
|
-
*
|
|
9198
|
+
* Run a task while no other task uses the connection, so no transaction
|
|
9199
|
+
* is open: a fork of the connection then copies committed state.
|
|
9200
|
+
*/
|
|
9201
|
+
whileIdle<T>(task: () => Promise<T>): Promise<T>;
|
|
9202
|
+
/**
|
|
9203
|
+
* Fork the connection and synchronize the copy with a source. The overlay
|
|
9204
|
+
* shares every unchanged page with this database and is independent of it:
|
|
9205
|
+
* either can change or close without affecting the other.
|
|
9206
|
+
*/
|
|
9207
|
+
overlay(source: RemoteSource): Promise<EntryDatabase>;
|
|
9208
|
+
static createSchema(db: Database, config: Config, revision: string, configFingerprint?: string): Promise<void>;
|
|
9209
|
+
/**
|
|
9210
|
+
* Synchronize a source through this database's single prepared syncer,
|
|
9211
|
+
* without keeping an in-memory copy of its entries.
|
|
9156
9212
|
*/
|
|
9157
9213
|
syncWith(source: RemoteSource, options?: SyncOptions): Promise<EntrySyncResult>;
|
|
9158
9214
|
/**
|
|
9159
9215
|
* Adopt another config and derive every entry again from the payloads this
|
|
9160
|
-
*
|
|
9161
|
-
*
|
|
9162
|
-
*
|
|
9216
|
+
* database stores, recording the fingerprint so a later open recognizes the
|
|
9217
|
+
* database as written by that config. The rows of the previous config are
|
|
9218
|
+
* replaced within one transaction, so reads keep answering from them until
|
|
9219
|
+
* the replacement is committed.
|
|
9163
9220
|
*/
|
|
9164
|
-
|
|
9165
|
-
/** Atomically plan and apply mutations through a private working
|
|
9221
|
+
reindex(config: Config, configFingerprint?: string): Promise<EntrySyncResult>;
|
|
9222
|
+
/** Atomically plan and apply mutations through a private working copy. */
|
|
9166
9223
|
apply(mutations: ReadonlyArray<Mutation>, options: EntryApplyOptions): Promise<EntryApplyResult>;
|
|
9167
9224
|
/** Plan mutations like apply, then roll them back. */
|
|
9168
9225
|
plan(mutations: ReadonlyArray<Mutation>, options: EntryApplyOptions): Promise<CommitRequest>;
|
|
9226
|
+
/**
|
|
9227
|
+
* Resolve a query with a source synced into this database, within a write
|
|
9228
|
+
* transaction that is rolled back afterwards.
|
|
9229
|
+
*/
|
|
9230
|
+
resolveWith<const Query extends GraphQuery>(source: RemoteSource, query: Query): Promise<AnyQueryResult<Query>>;
|
|
9169
9231
|
close(): Promise<void>;
|
|
9170
|
-
/** Release what this layer owns, serialized with the read connection. */
|
|
9171
|
-
protected releaseLayer(): Promise<void>;
|
|
9172
9232
|
[Symbol.asyncDispose](): Promise<void>;
|
|
9173
9233
|
getRevision(): Promise<string>;
|
|
9174
9234
|
getTree(): Promise<ReadonlyTree>;
|
|
9175
9235
|
getBlobs(shas: ReadonlyArray<string>, options?: GetBlobsOptions): AsyncGenerator<[sha: string, blob: Uint8Array]>;
|
|
9176
|
-
/** Run a task serialized with every other read on this connection. */
|
|
9177
|
-
protected withReadConnection<T>(run: () => Promise<T>): Promise<T>;
|
|
9178
|
-
/** Create and synchronize a copy-on-write layer over this one. */
|
|
9179
|
-
overlay(source: RemoteSource): Promise<EntryLayer>;
|
|
9180
|
-
/** Create an initially empty writable source and database layer. */
|
|
9181
|
-
createOverlay(): Promise<EntryDatabaseOverlay>;
|
|
9182
9236
|
resolve<const Query extends GraphQuery>(query: Query): Promise<AnyQueryResult<Query>>;
|
|
9183
9237
|
/** Scan references in bounded pages without retaining an entry index. */
|
|
9184
9238
|
referencesTo(query: EntryReferenceQuery): Promise<EntryReferenceResult>;
|
|
9185
9239
|
onChange(listener: EntryChangeListener): () => void;
|
|
9240
|
+
/** File stats recorded by the last filesystem sync of this database. */
|
|
9241
|
+
getSourceFileStats(): Promise<Map<string, FileStat>>;
|
|
9242
|
+
/** Replace the recorded file stats after syncing from a filesystem source. */
|
|
9243
|
+
setSourceFileStats(stats: ReadonlyMap<string, FileStat>): Promise<void>;
|
|
9244
|
+
compact(): Promise<void>;
|
|
9186
9245
|
}
|
|
9187
9246
|
|
|
9188
9247
|
}
|
|
@@ -9200,39 +9259,37 @@ declare module 'alinea/database/EntryStore' {
|
|
|
9200
9259
|
import type { LocalStore, SyncOptions } from 'alinea/core/db/LocalStore';
|
|
9201
9260
|
import { WriteableGraph } from 'alinea/core/db/WriteableGraph';
|
|
9202
9261
|
import type { UploadMetadata, UploadResponse } from 'alinea/core/Connection';
|
|
9203
|
-
import
|
|
9262
|
+
import { EntryDatabase, type EntryChangeListener } from 'alinea/database/EntryDatabase';
|
|
9263
|
+
import type { DatabaseDriver } from 'alinea/database/driver/DatabaseHandle';
|
|
9204
9264
|
export interface EntryStoreOptions {
|
|
9205
9265
|
ownsDatabase?: boolean;
|
|
9206
9266
|
sourceFollowsDatabase?: boolean;
|
|
9207
|
-
|
|
9267
|
+
driver?: DatabaseDriver;
|
|
9208
9268
|
}
|
|
9209
9269
|
/** Source and commit lifecycle around the transport-neutral SQLite database. */
|
|
9210
9270
|
export class EntryStore extends WriteableGraph implements LocalStore, AsyncDisposable {
|
|
9211
9271
|
#private;
|
|
9212
9272
|
/** Replaced only by a reindex, which derives every entry again. */
|
|
9213
9273
|
config: Config;
|
|
9214
|
-
readonly database:
|
|
9274
|
+
readonly database: EntryDatabase;
|
|
9215
9275
|
readonly source: Source;
|
|
9216
|
-
|
|
9276
|
+
readonly driver?: DatabaseDriver;
|
|
9277
|
+
constructor(config: Config, database: EntryDatabase, source: Source, options?: EntryStoreOptions);
|
|
9217
9278
|
static memory(config: Config, source: Source): Promise<EntryStore>;
|
|
9218
9279
|
get sha(): Promise<string>;
|
|
9219
9280
|
includedAtBuild(filePath: string): boolean | Promise<boolean>;
|
|
9220
9281
|
/**
|
|
9221
|
-
* Preview queries
|
|
9222
|
-
*
|
|
9223
|
-
*
|
|
9224
|
-
*
|
|
9282
|
+
* Preview queries resolve over the store with the previewed entry synced
|
|
9283
|
+
* in. The last payload keeps its fork, so repeated queries of one preview
|
|
9284
|
+
* sync once; another payload or store revision forks afresh. A database
|
|
9285
|
+
* that cannot fork syncs each preview in a transaction it rolls back.
|
|
9225
9286
|
*/
|
|
9226
9287
|
resolve<Query extends GraphQuery>(query: Query): Promise<AnyQueryResult<Query>>;
|
|
9227
|
-
/** Close the preview overlay, which keeps this store's database open. */
|
|
9228
|
-
protected closePreviews(): Promise<void>;
|
|
9229
9288
|
referencesTo(query: EntryReferenceQuery): Promise<EntryReferenceResult>;
|
|
9230
9289
|
onChange(listener: EntryChangeListener): () => void;
|
|
9231
9290
|
sync(): Promise<string>;
|
|
9232
9291
|
/** Keep the writable source and its query database at one remote revision. */
|
|
9233
9292
|
syncWith(remote: RemoteSource, options?: SyncOptions): Promise<string>;
|
|
9234
|
-
/** Create a persistent copy-on-write session over this store. */
|
|
9235
|
-
overlay(remote: RemoteSource): Promise<EntryStore>;
|
|
9236
9293
|
/** Plan a commit without changing this store. */
|
|
9237
9294
|
request(mutations: ReadonlyArray<Mutation>, policy?: Policy): Promise<CommitRequest>;
|
|
9238
9295
|
mutate(mutations: Array<Mutation>): Promise<{
|
|
@@ -9260,7 +9317,7 @@ declare module 'alinea/database/EntryTransaction' {
|
|
|
9260
9317
|
import type { ReadonlyTree } from 'alinea/core/source/Tree';
|
|
9261
9318
|
import { type CommitRequest } from 'alinea/core/db/CommitRequest';
|
|
9262
9319
|
import type { ArchiveMutation, CreateMutation, MoveMutation, Mutation, PublishMutation, RemoveFileMutation, RemoveMutation, UnpublishMutation, UpdateMutation, UploadFileMutation } from 'alinea/core/db/Mutation';
|
|
9263
|
-
import type {
|
|
9320
|
+
import type { EntryDatabase } from 'alinea/database/EntryDatabase';
|
|
9264
9321
|
type Op<T> = Omit<T, 'op'>;
|
|
9265
9322
|
/**
|
|
9266
9323
|
* Plans mutations inside the receiver's write transaction. Each mutation is
|
|
@@ -9269,8 +9326,8 @@ declare module 'alinea/database/EntryTransaction' {
|
|
|
9269
9326
|
*/
|
|
9270
9327
|
export class EntryTransaction implements AsyncDisposable {
|
|
9271
9328
|
#private;
|
|
9272
|
-
/** @internal Constructed by
|
|
9273
|
-
constructor(workingDatabase:
|
|
9329
|
+
/** @internal Constructed by EntryDatabase.apply. */
|
|
9330
|
+
constructor(workingDatabase: EntryDatabase, workingSource: OverlaySource, sourceTransaction: SourceTransaction, from: ReadonlyTree, policy: Policy);
|
|
9274
9331
|
get changedEntryIds(): Array<string>;
|
|
9275
9332
|
apply(mutations: ReadonlyArray<Mutation>): Promise<void>;
|
|
9276
9333
|
create({ locale, type, data, root, workspace, fromSeed, parentId, id, insertOrder, status, overwrite }: Op<CreateMutation>): Promise<void>;
|
|
@@ -9362,7 +9419,7 @@ declare module 'alinea/database/query/EntryQuery' {
|
|
|
9362
9419
|
import { type Scope } from 'alinea/core/Scope';
|
|
9363
9420
|
import { type HasSql, type SelectionInput, type Sql } from 'rado';
|
|
9364
9421
|
import { type EntryIndexTarget } from 'alinea/database/entry/EntryTable';
|
|
9365
|
-
import { searchQuery
|
|
9422
|
+
import { searchQuery } from 'alinea/database/query/Search';
|
|
9366
9423
|
interface RelationProjection {
|
|
9367
9424
|
path: Array<string>;
|
|
9368
9425
|
plan: ProjectionPlan;
|
|
@@ -9392,7 +9449,8 @@ declare module 'alinea/database/query/EntryQuery' {
|
|
|
9392
9449
|
entry?: EntryIndexTarget;
|
|
9393
9450
|
depth?: number;
|
|
9394
9451
|
baseEntry?: EntryIndexTarget;
|
|
9395
|
-
|
|
9452
|
+
/** Wrap every row and carry its entry id next to the selection. */
|
|
9453
|
+
withId?: boolean;
|
|
9396
9454
|
}
|
|
9397
9455
|
export function compileEntryQuery(config: Config, query: GraphQuery, options?: EntryQueryOptions): {
|
|
9398
9456
|
rows: import("rado").Select<SelectionInput, import("rado/core/MetaData").QueryMeta>;
|
|
@@ -9407,9 +9465,8 @@ declare module 'alinea/database/query/EntryReferences' {
|
|
|
9407
9465
|
import type { Config } from 'alinea/core/Config';
|
|
9408
9466
|
import type { EntryReferenceQuery, EntryReferenceResult } from 'alinea/core/db/EntryReference';
|
|
9409
9467
|
import { type Database } from 'rado';
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
export function queryEntryReferences(config: Config, db: Database, entry: EntryIndexTarget, query: EntryReferenceQuery): Promise<EntryReferenceResult>;
|
|
9468
|
+
/** Read the versions indexed as referencing the target and walk their data. */
|
|
9469
|
+
export function queryEntryReferences(config: Config, db: Database, query: EntryReferenceQuery): Promise<EntryReferenceResult>;
|
|
9413
9470
|
|
|
9414
9471
|
}
|
|
9415
9472
|
|
|
@@ -9434,14 +9491,11 @@ declare module 'alinea/database/query/ResolveQuery' {
|
|
|
9434
9491
|
import type { Config } from 'alinea/core/Config';
|
|
9435
9492
|
import type { GraphQuery } from 'alinea/core/Graph';
|
|
9436
9493
|
import { type Database } from 'rado';
|
|
9437
|
-
import type {
|
|
9438
|
-
import type { EntrySearchTarget, SearchQuery } from 'alinea/database/query/Search';
|
|
9494
|
+
import type { SearchQuery } from 'alinea/database/query/Search';
|
|
9439
9495
|
/** Query dependencies bound to one connection and its current transaction. */
|
|
9440
9496
|
export interface EntryQueryContext {
|
|
9441
9497
|
config: Config;
|
|
9442
9498
|
database: Database;
|
|
9443
|
-
entries: EntryIndexTarget;
|
|
9444
|
-
searchTable: EntrySearchTarget;
|
|
9445
9499
|
search(input: GraphQuery['search']): Promise<SearchQuery | undefined>;
|
|
9446
9500
|
includedAtBuild(filePath: string): boolean | Promise<boolean>;
|
|
9447
9501
|
}
|
|
@@ -9451,20 +9505,13 @@ declare module 'alinea/database/query/ResolveQuery' {
|
|
|
9451
9505
|
|
|
9452
9506
|
declare module 'alinea/database/query/Search' {
|
|
9453
9507
|
|
|
9454
|
-
import { type Database, type HasSql, type Sql
|
|
9508
|
+
import { type Database, type HasSql, type Sql } from 'rado';
|
|
9455
9509
|
import type { EntryIndexTarget } from 'alinea/database/entry/EntryTable';
|
|
9456
|
-
|
|
9457
|
-
* The FTS5 index of an entry table. Sync writes a row for every entry version
|
|
9458
|
-
* under the rowid of its entry row; the body is the version's searchable text.
|
|
9459
|
-
*/
|
|
9460
|
-
const EntrySearchColumns: {
|
|
9510
|
+
export const EntrySearchTable: import("rado").Table<{
|
|
9461
9511
|
rowid: import("rado").Column<number, [false, false]>;
|
|
9462
9512
|
title: import("rado").Column<string, [false, boolean]>;
|
|
9463
9513
|
body: import("rado").Column<string, [false, boolean]>;
|
|
9464
|
-
}
|
|
9465
|
-
export type EntrySearchTarget = Table<typeof EntrySearchColumns>;
|
|
9466
|
-
export function entrySearchTable(name: string, temporary?: boolean): EntrySearchTarget;
|
|
9467
|
-
export const EntrySearchTable: EntrySearchTarget;
|
|
9514
|
+
}, "alinea_entry_search">;
|
|
9468
9515
|
export interface SearchQuery {
|
|
9469
9516
|
target: Sql;
|
|
9470
9517
|
identity: Sql<boolean>;
|
|
@@ -9472,32 +9519,30 @@ declare module 'alinea/database/query/Search' {
|
|
|
9472
9519
|
rank: Sql<number>;
|
|
9473
9520
|
snippet(start: HasSql, end: HasSql, cutOff: HasSql, limit: HasSql): Sql<string>;
|
|
9474
9521
|
}
|
|
9475
|
-
export function createSearch(db: Database
|
|
9522
|
+
export function createSearch(db: Database): Promise<void>;
|
|
9476
9523
|
/** The searchable text of an entry row, read from its search row. */
|
|
9477
|
-
export function searchableText(entry: EntryIndexTarget
|
|
9524
|
+
export function searchableText(entry: EntryIndexTarget): Sql<string>;
|
|
9478
9525
|
export function searchTokens(input: string | Array<string> | undefined): RegExpMatchArray | [] | undefined;
|
|
9479
9526
|
export interface SearchQueryOptions {
|
|
9480
9527
|
/** Indexed spellings a token may also match, besides its prefix. */
|
|
9481
9528
|
alternatives?(token: string): ReadonlyArray<string>;
|
|
9482
9529
|
}
|
|
9483
|
-
export function searchQuery(input: string | Array<string> | undefined, entry: EntryIndexTarget,
|
|
9530
|
+
export function searchQuery(input: string | Array<string> | undefined, entry: EntryIndexTarget, options?: SearchQueryOptions): SearchQuery | undefined;
|
|
9484
9531
|
/** The edits a token may be away from an indexed term: none below five
|
|
9485
9532
|
* characters, one up to fourteen, then one more per ten. */
|
|
9486
9533
|
export function fuzzyDistance(token: string): number;
|
|
9487
|
-
export function dropVocabulary(db: Database, search: EntrySearchTarget): Promise<void>;
|
|
9488
9534
|
/**
|
|
9489
|
-
* The terms of
|
|
9535
|
+
* The terms of the search index, loaded once per database revision. Query tokens
|
|
9490
9536
|
* expand to indexed terms within a small edit distance, so a typo still
|
|
9491
9537
|
* finds the entry.
|
|
9492
9538
|
*/
|
|
9493
9539
|
export class SearchVocabulary {
|
|
9494
9540
|
#private;
|
|
9495
|
-
load(db: Database,
|
|
9541
|
+
load(db: Database, revision: string): Promise<void>;
|
|
9496
9542
|
/** Indexed terms close to a token, most frequent first; prefixes of the
|
|
9497
9543
|
* token are left to the prefix match. */
|
|
9498
9544
|
alternatives(token: string): Array<string>;
|
|
9499
9545
|
}
|
|
9500
|
-
export {};
|
|
9501
9546
|
|
|
9502
9547
|
}
|
|
9503
9548
|
|
|
@@ -9518,8 +9563,12 @@ declare module 'alinea/database/sync/EntryParser' {
|
|
|
9518
9563
|
|
|
9519
9564
|
import type { Config } from 'alinea/core/Config';
|
|
9520
9565
|
import type { IndexedEntry } from 'alinea/database/entry/EntryTable';
|
|
9566
|
+
/** A parsed source entry and the ids of the entries it references. */
|
|
9567
|
+
export interface ParsedEntry extends IndexedEntry {
|
|
9568
|
+
references: Array<string>;
|
|
9569
|
+
}
|
|
9521
9570
|
/** Parse one source blob into the entry fields that do not depend on its tree. */
|
|
9522
|
-
export function parseSourceEntry(config: Config, filePath: string, fileHash: string, blob: Uint8Array):
|
|
9571
|
+
export function parseSourceEntry(config: Config, filePath: string, fileHash: string, blob: Uint8Array): ParsedEntry;
|
|
9523
9572
|
|
|
9524
9573
|
}
|
|
9525
9574
|
|
|
@@ -9528,27 +9577,17 @@ declare module 'alinea/database/sync/EntrySyncer' {
|
|
|
9528
9577
|
import type { Config } from 'alinea/core/Config';
|
|
9529
9578
|
import type { RemoteSource } from 'alinea/core/source/Source';
|
|
9530
9579
|
import { ReadonlyTree } from 'alinea/core/source/Tree';
|
|
9531
|
-
import type { Database
|
|
9532
|
-
import { type DatabaseStateColumns } from 'alinea/database/DatabaseTables';
|
|
9533
|
-
import { type EntryIndexTarget } from 'alinea/database/entry/EntryTable';
|
|
9534
|
-
import { type EntrySearchTarget } from 'alinea/database/query/Search';
|
|
9535
|
-
export interface EntrySyncTarget {
|
|
9536
|
-
entries: EntryIndexTarget;
|
|
9537
|
-
state: Table<typeof DatabaseStateColumns>;
|
|
9538
|
-
/** The full-text index of the entries, written along with them. */
|
|
9539
|
-
search: EntrySearchTarget;
|
|
9540
|
-
/**
|
|
9541
|
-
* Whether the state records the synced source tree, so the database can be
|
|
9542
|
-
* reopened and synced from it. A temporary overlay keeps its tree in memory.
|
|
9543
|
-
*/
|
|
9544
|
-
recordsTree?: boolean;
|
|
9545
|
-
}
|
|
9546
|
-
export const EntrySyncRoot: EntrySyncTarget;
|
|
9580
|
+
import type { Database } from 'rado';
|
|
9547
9581
|
export interface EntrySyncOptions {
|
|
9548
9582
|
previousTree?: ReadonlyTree;
|
|
9549
9583
|
withinTransaction?: boolean;
|
|
9550
9584
|
/** Skip entry validation for a source whose entries were already validated. */
|
|
9551
9585
|
validate?: boolean;
|
|
9586
|
+
/**
|
|
9587
|
+
* Record the synced source tree in the state, so the database can be
|
|
9588
|
+
* reopened and synced from it. Defaults to true.
|
|
9589
|
+
*/
|
|
9590
|
+
recordsTree?: boolean;
|
|
9552
9591
|
}
|
|
9553
9592
|
/** Prepared, serialized source synchronization for one database connection. */
|
|
9554
9593
|
export class EntrySyncer {
|
|
@@ -9557,9 +9596,7 @@ declare module 'alinea/database/sync/EntrySyncer' {
|
|
|
9557
9596
|
/** Derive later syncs with another config; prepared statements are shared. */
|
|
9558
9597
|
reconfigure(config: Config): Promise<void>;
|
|
9559
9598
|
/** Stream a source/tree diff directly into the canonical SQLite table. */
|
|
9560
|
-
sync(
|
|
9561
|
-
/** Release prepared statements belonging to a closed named target. */
|
|
9562
|
-
release(target: EntrySyncTarget): Promise<void>;
|
|
9599
|
+
sync(source: RemoteSource, tree: ReadonlyTree, fromRevision: string, options?: EntrySyncOptions): Promise<Array<string>>;
|
|
9563
9600
|
close(): Promise<void>;
|
|
9564
9601
|
}
|
|
9565
9602
|
|
|
@@ -9597,7 +9634,6 @@ declare module 'alinea/database/sync/SyncQueries' {
|
|
|
9597
9634
|
import type { Tree } from 'alinea/core/source/Tree';
|
|
9598
9635
|
import { type Database } from 'rado';
|
|
9599
9636
|
import { type entryIndexRow } from 'alinea/database/entry/EntryTable';
|
|
9600
|
-
import type { EntrySyncTarget } from 'alinea/database/sync/EntrySyncer';
|
|
9601
9637
|
export const sqliteBatchSize = 5000;
|
|
9602
9638
|
/**
|
|
9603
9639
|
* Named parameters bypass column encoders, so bind SQLite values explicitly for
|
|
@@ -9633,7 +9669,7 @@ declare module 'alinea/database/sync/SyncQueries' {
|
|
|
9633
9669
|
main: number;
|
|
9634
9670
|
visible: number;
|
|
9635
9671
|
};
|
|
9636
|
-
export function prepareSyncQueries(db: Database,
|
|
9672
|
+
export function prepareSyncQueries(db: Database,
|
|
9637
9673
|
/** Store entry data as JSONB, on a SQLite that reads it. */
|
|
9638
9674
|
jsonb: boolean): {
|
|
9639
9675
|
revision: import("rado").PreparedQuery<{
|
|
@@ -9649,6 +9685,8 @@ declare module 'alinea/database/sync/SyncQueries' {
|
|
|
9649
9685
|
insertEntry: import("rado").PreparedQuery<import("rado/core/MetaData").MutationResultBase, Record<string, unknown>, import("rado/core/MetaData").QueryMeta>;
|
|
9650
9686
|
/** Index the entry row inserted last, under its rowid. */
|
|
9651
9687
|
insertSearch: import("rado").PreparedQuery<import("rado/core/MetaData").MutationResultBase, Record<string, unknown>, import("rado/core/MetaData").QueryMeta>;
|
|
9688
|
+
/** Record the entry ids a version references, under its rowid. */
|
|
9689
|
+
insertReferences: import("rado").PreparedQuery<import("rado/core/MetaData").MutationResultBase, Record<string, unknown>, import("rado/core/MetaData").QueryMeta>;
|
|
9652
9690
|
/** Versions stored at these file paths or under these version ids. */
|
|
9653
9691
|
storedFiles: import("rado").PreparedQuery<{
|
|
9654
9692
|
id: string;
|
|
@@ -9660,6 +9698,8 @@ declare module 'alinea/database/sync/SyncQueries' {
|
|
|
9660
9698
|
deleteFiles: import("rado").PreparedQuery<import("rado/core/MetaData").MutationResultBase, Record<string, unknown>, import("rado/core/MetaData").QueryMeta>;
|
|
9661
9699
|
/** Delete the search rows of those versions, before the versions. */
|
|
9662
9700
|
deleteSearch: import("rado").PreparedQuery<import("rado/core/MetaData").MutationResultBase, Record<string, unknown>, import("rado/core/MetaData").QueryMeta>;
|
|
9701
|
+
/** Delete the reference rows of those versions, before the versions. */
|
|
9702
|
+
deleteReferences: import("rado").PreparedQuery<import("rado/core/MetaData").MutationResultBase, Record<string, unknown>, import("rado/core/MetaData").QueryMeta>;
|
|
9663
9703
|
directories: import("rado").PreparedQuery<{
|
|
9664
9704
|
id: string;
|
|
9665
9705
|
childrenDir: string;
|
|
@@ -9761,8 +9801,8 @@ declare module 'alinea/database/Version' {
|
|
|
9761
9801
|
* by this version rather than the package version, so releases that keep the
|
|
9762
9802
|
* schema reuse the databases that are already there.
|
|
9763
9803
|
*/
|
|
9764
|
-
export const databaseVersion =
|
|
9765
|
-
export const generatedDatabaseFile = "database-
|
|
9804
|
+
export const databaseVersion = 8;
|
|
9805
|
+
export const generatedDatabaseFile = "database-v8.sqlite";
|
|
9766
9806
|
export function versionedCacheName(name: string): string;
|
|
9767
9807
|
|
|
9768
9808
|
}
|
|
@@ -11967,7 +12007,32 @@ declare module 'alinea/preview/widget' {
|
|
|
11967
12007
|
summary: string;
|
|
11968
12008
|
/** Whether the query was answered by the bundled database or the handler. */
|
|
11969
12009
|
source?: 'database' | 'handler';
|
|
12010
|
+
/**
|
|
12011
|
+
* Execution time for queries the bundled database answers, without the
|
|
12012
|
+
* wait behind the render's other queries; time from call to answer for
|
|
12013
|
+
* syncs and queries the handler answers.
|
|
12014
|
+
*/
|
|
12015
|
+
durationMs: number;
|
|
12016
|
+
/** SQL statements this row's work ran, such as a preview's sync. */
|
|
12017
|
+
statements?: number;
|
|
12018
|
+
sqlMs?: number;
|
|
12019
|
+
}
|
|
12020
|
+
/** One of the slowest SQL statements of a render. */
|
|
12021
|
+
export interface PreviewStatement {
|
|
12022
|
+
/** The statement, shortened */
|
|
12023
|
+
sql: string;
|
|
11970
12024
|
durationMs: number;
|
|
12025
|
+
/** Summary of the query or sync that ran it */
|
|
12026
|
+
query?: string;
|
|
12027
|
+
}
|
|
12028
|
+
/** The bundled database that answered the render's queries. */
|
|
12029
|
+
export interface PreviewDatabase {
|
|
12030
|
+
/** The native overlay, the native file, or the WASM copy */
|
|
12031
|
+
driver?: string;
|
|
12032
|
+
/** Time this process took to open it */
|
|
12033
|
+
openMs: number;
|
|
12034
|
+
/** Whether this render waited for it to open */
|
|
12035
|
+
cold: boolean;
|
|
11971
12036
|
}
|
|
11972
12037
|
/** The CMS work of one render, shown in the widget. */
|
|
11973
12038
|
export interface PreviewStats {
|
|
@@ -11975,6 +12040,10 @@ declare module 'alinea/preview/widget' {
|
|
|
11975
12040
|
/** SQL statements run in this process for the render. */
|
|
11976
12041
|
statements: number;
|
|
11977
12042
|
sqlMs: number;
|
|
12043
|
+
/** Time from the first query or sync of the render until the last settled. */
|
|
12044
|
+
renderMs: number;
|
|
12045
|
+
slowest?: Array<PreviewStatement>;
|
|
12046
|
+
database?: PreviewDatabase;
|
|
11978
12047
|
}
|
|
11979
12048
|
export function registerPreviewWidget(): void;
|
|
11980
12049
|
global {
|