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
|
@@ -1,27 +1,78 @@
|
|
|
1
1
|
import "../../chunks/chunk-CQ52GEHY.js";
|
|
2
2
|
|
|
3
3
|
// src/adapter/next/renderStats.ts
|
|
4
|
+
var slowestCount = 5;
|
|
4
5
|
var RenderStats = class {
|
|
5
6
|
rows = [];
|
|
6
7
|
statements = 0;
|
|
7
8
|
sqlMs = 0;
|
|
9
|
+
slowest = [];
|
|
10
|
+
/** The bundled database that answered, once a query reached it. */
|
|
11
|
+
database;
|
|
12
|
+
startedAt = Date.now();
|
|
8
13
|
#pending = 0;
|
|
9
14
|
#idleSince = Date.now();
|
|
15
|
+
#renderStart = Number.POSITIVE_INFINITY;
|
|
16
|
+
#renderEnd = Number.NEGATIVE_INFINITY;
|
|
17
|
+
#executedUntil = Number.NEGATIVE_INFINITY;
|
|
18
|
+
/** Syncs in progress: their statements run before any query's. */
|
|
19
|
+
#syncing = [];
|
|
20
|
+
/** Queries executing or waiting to, in the order they run. */
|
|
21
|
+
#executing = [];
|
|
10
22
|
/** Add a row and count it as pending until `run` settles; see `timed`. */
|
|
11
23
|
async track(stat, run) {
|
|
12
24
|
const row = { ...stat, durationMs: 0 };
|
|
13
25
|
this.rows.push(row);
|
|
14
26
|
this.#pending++;
|
|
27
|
+
this.#renderStart = Math.min(this.#renderStart, performance.now());
|
|
28
|
+
if (row.kind === "sync") this.#syncing.push(row);
|
|
15
29
|
try {
|
|
16
30
|
return await run(row);
|
|
17
31
|
} finally {
|
|
32
|
+
if (row.kind === "sync") remove(this.#syncing, row);
|
|
18
33
|
this.#pending--;
|
|
19
34
|
this.#idleSince = Date.now();
|
|
35
|
+
this.#renderEnd = Math.max(this.#renderEnd, performance.now());
|
|
20
36
|
}
|
|
21
37
|
}
|
|
22
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Time a database query without the time it waited behind the others:
|
|
40
|
+
* queries of a render run one at a time in the order they were called, so
|
|
41
|
+
* one starts executing once the previous one finished, or when it was
|
|
42
|
+
* called if that is later.
|
|
43
|
+
*/
|
|
44
|
+
async executed(row, run) {
|
|
45
|
+
const start = performance.now();
|
|
46
|
+
this.#executing.push(row);
|
|
47
|
+
try {
|
|
48
|
+
return await run();
|
|
49
|
+
} finally {
|
|
50
|
+
remove(this.#executing, row);
|
|
51
|
+
const end = performance.now();
|
|
52
|
+
row.durationMs = end - Math.max(start, this.#executedUntil);
|
|
53
|
+
this.#executedUntil = end;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Count a statement towards the render, and towards the row that ran it:
|
|
58
|
+
* a sync in progress, or else the query executing, which is the earliest
|
|
59
|
+
* one called that has not finished (see `executed`).
|
|
60
|
+
*/
|
|
61
|
+
statement(durationMs, sql) {
|
|
23
62
|
this.statements++;
|
|
24
63
|
this.sqlMs += durationMs;
|
|
64
|
+
const row = this.#syncing.at(-1) ?? this.#executing[0];
|
|
65
|
+
if (row) {
|
|
66
|
+
row.statements = (row.statements ?? 0) + 1;
|
|
67
|
+
row.sqlMs = (row.sqlMs ?? 0) + durationMs;
|
|
68
|
+
}
|
|
69
|
+
if (sql === void 0) return;
|
|
70
|
+
const { slowest } = this;
|
|
71
|
+
if (slowest.length >= slowestCount && durationMs <= slowest[slowest.length - 1].durationMs)
|
|
72
|
+
return;
|
|
73
|
+
slowest.push({ sql: summarizeSql(sql), durationMs, query: row?.summary });
|
|
74
|
+
slowest.sort((a, b) => b.durationMs - a.durationMs);
|
|
75
|
+
slowest.length = Math.min(slowest.length, slowestCount);
|
|
25
76
|
}
|
|
26
77
|
/**
|
|
27
78
|
* Resolves once nothing ran for `quietMs`, so queries of server components
|
|
@@ -36,10 +87,22 @@ var RenderStats = class {
|
|
|
36
87
|
(resolve) => setTimeout(resolve, Math.min(wait, deadline - now))
|
|
37
88
|
);
|
|
38
89
|
}
|
|
39
|
-
const { rows, statements, sqlMs } = this;
|
|
40
|
-
|
|
90
|
+
const { rows, statements, sqlMs, slowest, database } = this;
|
|
91
|
+
const renderMs = Math.max(0, this.#renderEnd - this.#renderStart);
|
|
92
|
+
return {
|
|
93
|
+
rows: rows.map((row) => ({ ...row })),
|
|
94
|
+
statements,
|
|
95
|
+
sqlMs,
|
|
96
|
+
renderMs,
|
|
97
|
+
slowest: [...slowest],
|
|
98
|
+
database
|
|
99
|
+
};
|
|
41
100
|
}
|
|
42
101
|
};
|
|
102
|
+
function summarizeSql(sql, maxLength = 200) {
|
|
103
|
+
const text = sql.replace(/\s+/g, " ").replaceAll('"', "").replace(/^select .*? from /i, "select \u2026 from ").replace(/\b\w+\.(\w+)/g, "$1").trim();
|
|
104
|
+
return text.length > maxLength ? `${text.slice(0, maxLength - 1)}\u2026` : text;
|
|
105
|
+
}
|
|
43
106
|
async function timed(row, run) {
|
|
44
107
|
if (!row) return run();
|
|
45
108
|
const start = performance.now();
|
|
@@ -67,8 +130,13 @@ function summarizeQuery(query) {
|
|
|
67
130
|
);
|
|
68
131
|
return `${mode}(${parts.join(", ")})`;
|
|
69
132
|
}
|
|
133
|
+
function remove(items, item) {
|
|
134
|
+
const index = items.indexOf(item);
|
|
135
|
+
if (index !== -1) items.splice(index, 1);
|
|
136
|
+
}
|
|
70
137
|
export {
|
|
71
138
|
RenderStats,
|
|
72
139
|
summarizeQuery,
|
|
140
|
+
summarizeSql,
|
|
73
141
|
timed
|
|
74
142
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import "../../chunks/chunk-CQ52GEHY.js";
|
|
2
2
|
|
|
3
3
|
// src/adapter/next/syncCheck.ts
|
|
4
|
-
import { ReadonlyTree } from "alinea/core/source/Tree";
|
|
5
4
|
var CONTENT_SHA_TAG = "alinea-content-sha";
|
|
6
5
|
var SHA_REVALIDATE_SECONDS = 60;
|
|
7
|
-
var SENTINEL_SHA = ReadonlyTree.EMPTY.sha;
|
|
8
6
|
var inflight;
|
|
9
7
|
function latestSha(client) {
|
|
10
8
|
if (inflight) return inflight;
|
|
@@ -17,18 +15,14 @@ async function loadLatestSha(client) {
|
|
|
17
15
|
try {
|
|
18
16
|
const { unstable_cache } = await import("next/cache.js");
|
|
19
17
|
const getSha = unstable_cache(
|
|
20
|
-
|
|
21
|
-
const tree = await client.getTreeIfDifferent(SENTINEL_SHA);
|
|
22
|
-
return tree?.sha;
|
|
23
|
-
},
|
|
18
|
+
() => client.getSha(),
|
|
24
19
|
["alinea-content-sha"],
|
|
25
20
|
{ revalidate: SHA_REVALIDATE_SECONDS, tags: [CONTENT_SHA_TAG] }
|
|
26
21
|
);
|
|
27
22
|
return await getSha();
|
|
28
23
|
} catch {
|
|
29
24
|
try {
|
|
30
|
-
|
|
31
|
-
return tree?.sha;
|
|
25
|
+
return await client.getSha();
|
|
32
26
|
} catch {
|
|
33
27
|
return void 0;
|
|
34
28
|
}
|
|
@@ -41,7 +41,8 @@ function withAlinea(config = {}) {
|
|
|
41
41
|
...config.experimental,
|
|
42
42
|
serverComponentsExternalPackages: [
|
|
43
43
|
...config.experimental?.serverComponentsExternalPackages ?? [],
|
|
44
|
-
"@alinea/generated"
|
|
44
|
+
"@alinea/generated",
|
|
45
|
+
"@alinea/sqlite-wasm"
|
|
45
46
|
]
|
|
46
47
|
},
|
|
47
48
|
rewrites,
|
|
@@ -52,7 +53,10 @@ function withAlinea(config = {}) {
|
|
|
52
53
|
...config,
|
|
53
54
|
serverExternalPackages: [
|
|
54
55
|
...config.serverExternalPackages ?? [],
|
|
55
|
-
"@alinea/generated"
|
|
56
|
+
"@alinea/generated",
|
|
57
|
+
// Loads its native extension from the package directory, which file
|
|
58
|
+
// tracing then includes.
|
|
59
|
+
"@alinea/sqlite-wasm"
|
|
56
60
|
],
|
|
57
61
|
rewrites,
|
|
58
62
|
images,
|
|
@@ -14,7 +14,7 @@ var HandleAction = /* @__PURE__ */ ((HandleAction2) => {
|
|
|
14
14
|
HandleAction2["Mutate"] = "mutate";
|
|
15
15
|
HandleAction2["Upload"] = "upload";
|
|
16
16
|
HandleAction2["Tree"] = "tree";
|
|
17
|
-
HandleAction2["
|
|
17
|
+
HandleAction2["Sha"] = "sha";
|
|
18
18
|
HandleAction2["Blob"] = "blob";
|
|
19
19
|
return HandleAction2;
|
|
20
20
|
})(HandleAction || {});
|
package/dist/backend/Handler.js
CHANGED
|
@@ -32,7 +32,7 @@ import { isRecord } from "alinea/core/util/Objects";
|
|
|
32
32
|
import { isAbsolute, normalize } from "alinea/core/util/Paths";
|
|
33
33
|
import { InvalidCredentialsError, MissingCredentialsError } from "./Auth.js";
|
|
34
34
|
import { HandleAction } from "./HandleAction.js";
|
|
35
|
-
import {
|
|
35
|
+
import { proxyMediaUrl } from "./api/ProxyMedia.js";
|
|
36
36
|
import { applyPreview, decodePreviewRequest } from "./resolver/ParsePreview.js";
|
|
37
37
|
import { compressResponse } from "./router/Router.js";
|
|
38
38
|
import { createThrottledSync } from "./util/Syncable.js";
|
|
@@ -124,7 +124,7 @@ function createHandler({
|
|
|
124
124
|
if (typeof location !== "string")
|
|
125
125
|
return new Response("Not found", { status: 404 });
|
|
126
126
|
const previewSource = typeof previewUrl === "string" && previewUrl ? new URL(previewUrl, request.url).href : void 0;
|
|
127
|
-
async function proxyMedia(source2, cacheControl
|
|
127
|
+
async function proxyMedia(source2, cacheControl) {
|
|
128
128
|
const previewEntryId = uploadPreviewEntryId(
|
|
129
129
|
source2,
|
|
130
130
|
context.handlerUrl
|
|
@@ -135,13 +135,12 @@ function createHandler({
|
|
|
135
135
|
} else {
|
|
136
136
|
response = await proxyMediaUrl(
|
|
137
137
|
request,
|
|
138
|
-
new URL(source2, request.url)
|
|
139
|
-
isAllowed
|
|
138
|
+
new URL(source2, request.url)
|
|
140
139
|
);
|
|
141
140
|
}
|
|
142
141
|
return mediaResponse(request, response, cacheControl);
|
|
143
142
|
}
|
|
144
|
-
if (!wasBuilt && previewSource) {
|
|
143
|
+
if (!context.isDev && !wasBuilt && previewSource) {
|
|
145
144
|
if (proxy) return proxyMedia(previewSource, "private, no-store");
|
|
146
145
|
return redirectFile(previewSource, "private, no-store");
|
|
147
146
|
}
|
|
@@ -153,18 +152,10 @@ function createHandler({
|
|
|
153
152
|
if (!source || source === requestedUrl)
|
|
154
153
|
return new Response("Not found", { status: 404 });
|
|
155
154
|
if (!proxy) return redirectFile(source, "public, max-age=60");
|
|
156
|
-
const
|
|
157
|
-
cms.config,
|
|
158
|
-
context.isDev ? "development" : "production"
|
|
159
|
-
);
|
|
160
|
-
const deliveryBase = configuredBase ?? context.handlerUrl;
|
|
161
|
-
const sourceUrl = new URL(source, deliveryBase);
|
|
162
|
-
const deliveryOrigin = new URL(deliveryBase).origin;
|
|
163
|
-
const handlerPath = context.handlerUrl.pathname;
|
|
155
|
+
const deliveryBase = !context.isDev && Config.baseUrl(cms.config, "production") || context.handlerUrl;
|
|
164
156
|
return proxyMedia(
|
|
165
|
-
|
|
166
|
-
"public, max-age=60"
|
|
167
|
-
(url2) => url2.origin === deliveryOrigin && url2.pathname !== handlerPath && !url2.pathname.startsWith(`${handlerPath}/`)
|
|
157
|
+
new URL(source, deliveryBase).href,
|
|
158
|
+
"public, max-age=60"
|
|
168
159
|
);
|
|
169
160
|
}
|
|
170
161
|
const action = params.get("action");
|
|
@@ -315,23 +306,6 @@ function createHandler({
|
|
|
315
306
|
}
|
|
316
307
|
return Response.json({ sha });
|
|
317
308
|
}
|
|
318
|
-
if (action === HandleAction.Commit && request.method === "POST") {
|
|
319
|
-
if (!context.isDev)
|
|
320
|
-
throw new HttpError(400, "Commits are only accepted in development");
|
|
321
|
-
const developmentKey = request.headers.get(developmentKeyHeader);
|
|
322
|
-
if (!context.apiKey || developmentKey !== context.apiKey)
|
|
323
|
-
throw new HttpError(401, "Invalid development commit credentials");
|
|
324
|
-
const user = expectUser();
|
|
325
|
-
expectJson();
|
|
326
|
-
const commit = {
|
|
327
|
-
...await body,
|
|
328
|
-
user: user.claims
|
|
329
|
-
};
|
|
330
|
-
let { sha } = await cnx.write(commit);
|
|
331
|
-
if (sha === commit.intoSha) await local.write(commit);
|
|
332
|
-
else sha = await local.syncWith(cnx);
|
|
333
|
-
return Response.json({ sha });
|
|
334
|
-
}
|
|
335
309
|
if (action === HandleAction.History && request.method === "GET") {
|
|
336
310
|
expectUser();
|
|
337
311
|
expectJson();
|
|
@@ -347,6 +321,11 @@ function createHandler({
|
|
|
347
321
|
const tree = await local.getTreeIfDifferent(sha);
|
|
348
322
|
return compressResponse(request, Response.json(tree ?? null));
|
|
349
323
|
}
|
|
324
|
+
if (action === HandleAction.Sha && request.method === "GET") {
|
|
325
|
+
expectJson();
|
|
326
|
+
await syncForRead(cnx);
|
|
327
|
+
return Response.json(await local.sha);
|
|
328
|
+
}
|
|
350
329
|
if (action === HandleAction.Blob && request.method === "POST") {
|
|
351
330
|
const { shas } = object({ shas: array(string) })(await body);
|
|
352
331
|
await periodicSync(cnx);
|
|
@@ -452,8 +431,6 @@ function uploadPreviewEntryId(previewSource, handlerUrl) {
|
|
|
452
431
|
return previewUrl.searchParams.get("entryId") ?? void 0;
|
|
453
432
|
}
|
|
454
433
|
function mediaResponse(request, upstream, cacheControl) {
|
|
455
|
-
if (isRedirectStatus(upstream.status))
|
|
456
|
-
return new Response("Media backend returned a redirect", { status: 502 });
|
|
457
434
|
const responseHeaders = new Headers({
|
|
458
435
|
"cache-control": upstream.ok || upstream.status === 304 ? cacheControl : "no-store"
|
|
459
436
|
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
driver_exports
|
|
3
|
-
} from "../../chunks/chunk-
|
|
4
|
-
import "../../chunks/chunk-
|
|
5
|
-
import "../../chunks/chunk-
|
|
6
|
-
import "../../chunks/chunk-
|
|
7
|
-
import "../../chunks/chunk-
|
|
3
|
+
} from "../../chunks/chunk-QJGGYF6E.js";
|
|
4
|
+
import "../../chunks/chunk-QSN6RH6X.js";
|
|
5
|
+
import "../../chunks/chunk-ETWOY4AL.js";
|
|
6
|
+
import "../../chunks/chunk-66YZ47TY.js";
|
|
7
|
+
import "../../chunks/chunk-AIU6CMVT.js";
|
|
8
8
|
import "../../chunks/chunk-N47Y62CI.js";
|
|
9
9
|
import "../../chunks/chunk-QBPYWU6C.js";
|
|
10
10
|
import "../../chunks/chunk-2BJ2IFQM.js";
|
|
11
11
|
import "../../chunks/chunk-XCZXR3C2.js";
|
|
12
|
-
import "../../chunks/chunk-
|
|
12
|
+
import "../../chunks/chunk-MOWR65LM.js";
|
|
13
13
|
import "../../chunks/chunk-76VMZTLN.js";
|
|
14
14
|
import "../../chunks/chunk-2PIFHEYR.js";
|
|
15
15
|
import "../../chunks/chunk-K62JP6HR.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
integer,
|
|
8
8
|
text,
|
|
9
9
|
varchar
|
|
10
|
-
} from "../../chunks/chunk-
|
|
10
|
+
} from "../../chunks/chunk-ASYKC6IE.js";
|
|
11
11
|
import {
|
|
12
12
|
Builder
|
|
13
13
|
} from "../../chunks/chunk-2BJ2IFQM.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "../../chunks/chunk-XCZXR3C2.js";
|
|
17
17
|
import {
|
|
18
18
|
table
|
|
19
|
-
} from "../../chunks/chunk-
|
|
19
|
+
} from "../../chunks/chunk-MOWR65LM.js";
|
|
20
20
|
import "../../chunks/chunk-76VMZTLN.js";
|
|
21
21
|
import "../../chunks/chunk-2PIFHEYR.js";
|
|
22
22
|
import "../../chunks/chunk-K62JP6HR.js";
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { type Request
|
|
2
|
-
export declare function proxyMediaUrl(request: Request, source: URL
|
|
3
|
-
export declare function isRedirectStatus(status: number): boolean;
|
|
1
|
+
import { type Request } from '@alinea/iso';
|
|
2
|
+
export declare function proxyMediaUrl(request: Request, source: URL): Promise<Response>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "../../chunks/chunk-CQ52GEHY.js";
|
|
2
2
|
|
|
3
3
|
// src/backend/api/ProxyMedia.ts
|
|
4
|
-
import { Headers
|
|
5
|
-
|
|
4
|
+
import { Headers } from "@alinea/iso";
|
|
5
|
+
function proxyMediaUrl(request, source) {
|
|
6
6
|
const headers = new Headers();
|
|
7
7
|
for (const name of [
|
|
8
8
|
"range",
|
|
@@ -13,27 +13,12 @@ async function proxyMediaUrl(request, source, isAllowed = (url) => url.origin ==
|
|
|
13
13
|
const value = request.headers.get(name);
|
|
14
14
|
if (value) headers.set(name, value);
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
method: request.method,
|
|
22
|
-
headers,
|
|
23
|
-
redirect: "manual",
|
|
24
|
-
signal: request.signal
|
|
25
|
-
});
|
|
26
|
-
const location = response.headers.get("location");
|
|
27
|
-
if (!isRedirectStatus(response.status) || !location) return response;
|
|
28
|
-
if (redirects === 3)
|
|
29
|
-
return new Response("Too many media redirects", { status: 502 });
|
|
30
|
-
current = new URL(location, current);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function isRedirectStatus(status) {
|
|
34
|
-
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
16
|
+
return fetch(source, {
|
|
17
|
+
method: request.method,
|
|
18
|
+
headers,
|
|
19
|
+
signal: request.signal
|
|
20
|
+
});
|
|
35
21
|
}
|
|
36
22
|
export {
|
|
37
|
-
isRedirectStatus,
|
|
38
23
|
proxyMediaUrl
|
|
39
24
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
driver_exports
|
|
3
|
-
} from "../../chunks/chunk-
|
|
4
|
-
import "../../chunks/chunk-
|
|
5
|
-
import "../../chunks/chunk-
|
|
6
|
-
import "../../chunks/chunk-
|
|
7
|
-
import "../../chunks/chunk-
|
|
3
|
+
} from "../../chunks/chunk-QJGGYF6E.js";
|
|
4
|
+
import "../../chunks/chunk-QSN6RH6X.js";
|
|
5
|
+
import "../../chunks/chunk-ETWOY4AL.js";
|
|
6
|
+
import "../../chunks/chunk-66YZ47TY.js";
|
|
7
|
+
import "../../chunks/chunk-AIU6CMVT.js";
|
|
8
8
|
import "../../chunks/chunk-N47Y62CI.js";
|
|
9
9
|
import "../../chunks/chunk-QBPYWU6C.js";
|
|
10
10
|
import "../../chunks/chunk-2BJ2IFQM.js";
|
|
11
11
|
import "../../chunks/chunk-XCZXR3C2.js";
|
|
12
|
-
import "../../chunks/chunk-
|
|
12
|
+
import "../../chunks/chunk-MOWR65LM.js";
|
|
13
13
|
import "../../chunks/chunk-76VMZTLN.js";
|
|
14
14
|
import "../../chunks/chunk-2PIFHEYR.js";
|
|
15
15
|
import "../../chunks/chunk-K62JP6HR.js";
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Config } from 'alinea/core/Config';
|
|
2
|
+
import type { DatabaseHandle } from 'alinea/database/driver/DatabaseHandle';
|
|
2
3
|
import { EntryStore } from 'alinea/database/EntryStore';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Serve a generated database from a connection that keeps its writes in
|
|
6
|
+
* memory, so syncs and commits never reach the generated file.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createGeneratedDatabase(config: Config, { database: db, fork, driver }: DatabaseHandle): Promise<EntryStore>;
|
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
import "../../chunks/chunk-CQ52GEHY.js";
|
|
2
2
|
|
|
3
3
|
// src/backend/store/GeneratedDatabase.ts
|
|
4
|
+
import { DatabaseSource } from "alinea/database/DatabaseSource";
|
|
4
5
|
import { assertReadableData } from "alinea/database/entry/EntryData";
|
|
5
6
|
import { EntryDatabase } from "alinea/database/EntryDatabase";
|
|
6
7
|
import { EntryStore } from "alinea/database/EntryStore";
|
|
7
|
-
async function createGeneratedDatabase(config, db) {
|
|
8
|
+
async function createGeneratedDatabase(config, { database: db, fork, driver }) {
|
|
8
9
|
let initialTree;
|
|
9
|
-
const
|
|
10
|
+
const database = new EntryDatabase(config, db, {
|
|
11
|
+
fork,
|
|
10
12
|
includedAtBuild(filePath) {
|
|
11
13
|
return initialTree?.has(filePath) ?? false;
|
|
12
|
-
}
|
|
14
|
+
},
|
|
15
|
+
// Nothing reopens the in-memory writes: skip storing the synced tree.
|
|
16
|
+
recordsTree: false
|
|
13
17
|
});
|
|
14
18
|
try {
|
|
15
19
|
await assertReadableData(db);
|
|
16
|
-
initialTree = await
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
await base.close();
|
|
22
|
-
}
|
|
20
|
+
initialTree = await database.getTree();
|
|
21
|
+
return new EntryStore(config, database, new DatabaseSource(database), {
|
|
22
|
+
ownsDatabase: true,
|
|
23
|
+
sourceFollowsDatabase: true,
|
|
24
|
+
driver
|
|
23
25
|
});
|
|
24
26
|
} catch (error) {
|
|
25
|
-
await
|
|
27
|
+
await database.close();
|
|
26
28
|
throw error;
|
|
27
29
|
}
|
|
28
30
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Config } from 'alinea/core/Config';
|
|
2
2
|
import type { DatabaseOptions } from 'rado';
|
|
3
|
-
/** Open the traced generated file
|
|
3
|
+
/** Open the traced generated file as an in-memory overlay. */
|
|
4
4
|
export declare function generatedDatabase(config: Config, options?: DatabaseOptions): Promise<import("../../database/EntryStore.js").EntryStore>;
|
|
@@ -19,7 +19,7 @@ function generatedDatabase(config, options = {}) {
|
|
|
19
19
|
store = generatedDatabasePath().then(
|
|
20
20
|
(path) => runtimeDatabase({
|
|
21
21
|
path,
|
|
22
|
-
|
|
22
|
+
overlay: true,
|
|
23
23
|
logQuery: (query, durationMs) => loggers.get(config)?.(query, durationMs)
|
|
24
24
|
})
|
|
25
25
|
).then((db) => createGeneratedDatabase(config, db));
|